PyThea 0.11.0__tar.gz → 0.13.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.13.0/.readthedocs.yaml +29 -0
- {pythea-0.11.0 → pythea-0.13.0}/CHANGELOG.md +40 -1
- {pythea-0.11.0/PyThea.egg-info → pythea-0.13.0}/PKG-INFO +6 -7
- {pythea-0.11.0 → pythea-0.13.0}/PyThea/PyThea_app.py +108 -48
- {pythea-0.11.0 → pythea-0.13.0}/PyThea/_version.py +2 -2
- {pythea-0.11.0 → pythea-0.13.0}/PyThea/callbacks.py +40 -0
- {pythea-0.11.0 → pythea-0.13.0}/PyThea/config/app_styles.py +0 -5
- pythea-0.13.0/PyThea/config/selected_imagers.py +73 -0
- {pythea-0.11.0 → pythea-0.13.0}/PyThea/data/sample_data.py +10 -1
- pythea-0.13.0/PyThea/extensions/Parker_spirals/__init__.py +62 -0
- pythea-0.13.0/PyThea/extensions/Parker_spirals/utils.py +43 -0
- pythea-0.13.0/PyThea/extensions/hek/utils.py +118 -0
- {pythea-0.11.0 → pythea-0.13.0}/PyThea/geometrical_models.py +123 -30
- {pythea-0.11.0 → pythea-0.13.0}/PyThea/modules.py +169 -25
- {pythea-0.11.0 → pythea-0.13.0}/PyThea/sunpy_dev/map/maputils.py +15 -2
- pythea-0.13.0/PyThea/test/__init__.py +0 -0
- {pythea-0.11.0 → pythea-0.13.0}/PyThea/test/figure_hashes.json +4 -1
- pythea-0.13.0/PyThea/test/test_extension_utils.py +56 -0
- {pythea-0.11.0 → pythea-0.13.0}/PyThea/test/test_figures.py +98 -1
- {pythea-0.11.0 → pythea-0.13.0}/PyThea/test/test_remote_clients.py +2 -2
- {pythea-0.11.0 → pythea-0.13.0}/PyThea/test/test_utils.py +37 -5
- pythea-0.13.0/PyThea/utils.py +957 -0
- {pythea-0.11.0 → pythea-0.13.0/PyThea.egg-info}/PKG-INFO +6 -7
- {pythea-0.11.0 → pythea-0.13.0}/PyThea.egg-info/SOURCES.txt +6 -0
- {pythea-0.11.0 → pythea-0.13.0}/PyThea.egg-info/requires.txt +2 -3
- {pythea-0.11.0 → pythea-0.13.0}/README.md +3 -3
- {pythea-0.11.0 → pythea-0.13.0}/README_pypi.md +3 -3
- {pythea-0.11.0 → pythea-0.13.0}/environment.yml +3 -4
- {pythea-0.11.0 → pythea-0.13.0}/requirements.txt +2 -3
- {pythea-0.11.0 → pythea-0.13.0}/setup.cfg +4 -0
- pythea-0.11.0/PyThea/config/selected_imagers.py +0 -34
- pythea-0.11.0/PyThea/utils.py +0 -496
- {pythea-0.11.0 → pythea-0.13.0}/LICENSE.md +0 -0
- {pythea-0.11.0 → pythea-0.13.0}/MANIFEST.in +0 -0
- {pythea-0.11.0 → pythea-0.13.0}/PyThea/__init__.py +0 -0
- {pythea-0.11.0 → pythea-0.13.0}/PyThea/config/__init__.py +0 -0
- {pythea-0.11.0 → pythea-0.13.0}/PyThea/config/config_sliders.py +0 -0
- {pythea-0.11.0 → pythea-0.13.0}/PyThea/config/selected_bodies.py +0 -0
- {pythea-0.11.0 → pythea-0.13.0}/PyThea/data/__init__.py +0 -0
- {pythea-0.11.0 → pythea-0.13.0}/PyThea/extensions/LICENSE_gcs_python.md +0 -0
- {pythea-0.11.0 → pythea-0.13.0}/PyThea/extensions/__init__.py +0 -0
- {pythea-0.11.0 → pythea-0.13.0}/PyThea/extensions/buttons.py +0 -0
- {pythea-0.11.0/PyThea/sunpy_dev → pythea-0.13.0/PyThea/extensions/hek}/__init__.py +0 -0
- {pythea-0.11.0 → pythea-0.13.0}/PyThea/pythea_cli.py +0 -0
- {pythea-0.11.0/PyThea/sunpy_dev/extern → pythea-0.13.0/PyThea/sunpy_dev}/__init__.py +0 -0
- {pythea-0.11.0/PyThea/sunpy_dev/extern/sunkit_instruments → pythea-0.13.0/PyThea/sunpy_dev/extern}/__init__.py +0 -0
- {pythea-0.11.0/PyThea/sunpy_dev/extern/sunkit_instruments/aia → pythea-0.13.0/PyThea/sunpy_dev/extern/sunkit_instruments}/__init__.py +0 -0
- {pythea-0.11.0/PyThea/sunpy_dev/extern/sunkit_instruments/lasco → pythea-0.13.0/PyThea/sunpy_dev/extern/sunkit_instruments/aia}/__init__.py +0 -0
- {pythea-0.11.0 → pythea-0.13.0}/PyThea/sunpy_dev/extern/sunkit_instruments/aia/utils.py +0 -0
- {pythea-0.11.0/PyThea/sunpy_dev/extern/sunkit_instruments/stereo → pythea-0.13.0/PyThea/sunpy_dev/extern/sunkit_instruments/lasco}/__init__.py +0 -0
- {pythea-0.11.0 → pythea-0.13.0}/PyThea/sunpy_dev/extern/sunkit_instruments/lasco/utils.py +0 -0
- {pythea-0.11.0/PyThea/sunpy_dev/map → pythea-0.13.0/PyThea/sunpy_dev/extern/sunkit_instruments/stereo}/__init__.py +0 -0
- {pythea-0.11.0 → pythea-0.13.0}/PyThea/sunpy_dev/extern/sunkit_instruments/stereo/utils.py +0 -0
- {pythea-0.11.0/PyThea/test → pythea-0.13.0/PyThea/sunpy_dev/map}/__init__.py +0 -0
- {pythea-0.11.0 → pythea-0.13.0}/PyThea/test/Pythea_test.py +0 -0
- {pythea-0.11.0 → pythea-0.13.0}/PyThea/test/conftest.py +0 -0
- {pythea-0.11.0 → pythea-0.13.0}/PyThea/test/test_geometrical_models.py +0 -0
- {pythea-0.11.0 → pythea-0.13.0}/PyThea/test/test_imports.py +0 -0
- {pythea-0.11.0 → pythea-0.13.0}/PyThea/version.py +0 -0
- {pythea-0.11.0 → pythea-0.13.0}/PyThea.egg-info/.DS_Store +0 -0
- {pythea-0.11.0 → pythea-0.13.0}/PyThea.egg-info/dependency_links.txt +0 -0
- {pythea-0.11.0 → pythea-0.13.0}/PyThea.egg-info/entry_points.txt +0 -0
- {pythea-0.11.0 → pythea-0.13.0}/PyThea.egg-info/not-zip-safe +0 -0
- {pythea-0.11.0 → pythea-0.13.0}/PyThea.egg-info/top_level.txt +0 -0
- {pythea-0.11.0 → pythea-0.13.0}/pyproject.toml +0 -0
- {pythea-0.11.0 → pythea-0.13.0}/setup.py +0 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# .readthedocs.yaml
|
|
2
|
+
# Read the Docs configuration file
|
|
3
|
+
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
|
|
4
|
+
|
|
5
|
+
# Required
|
|
6
|
+
version: 2
|
|
7
|
+
|
|
8
|
+
# Set the version of Python and other tools you might need
|
|
9
|
+
build:
|
|
10
|
+
os: ubuntu-22.04
|
|
11
|
+
tools:
|
|
12
|
+
python: "3.9"
|
|
13
|
+
# You can also specify other tool versions:
|
|
14
|
+
# nodejs: "16"
|
|
15
|
+
# rust: "1.55"
|
|
16
|
+
# golang: "1.17"
|
|
17
|
+
|
|
18
|
+
# Build documentation in the docs/ directory with Sphinx
|
|
19
|
+
sphinx:
|
|
20
|
+
configuration: docs/source/conf.py
|
|
21
|
+
|
|
22
|
+
# If using Sphinx, optionally build your docs in additional formats such as PDF
|
|
23
|
+
# formats:
|
|
24
|
+
# - pdf
|
|
25
|
+
|
|
26
|
+
# Optionally declare the Python requirements required to build your docs
|
|
27
|
+
python:
|
|
28
|
+
install:
|
|
29
|
+
- requirements: docs/source/requirements.txt
|
|
@@ -1,4 +1,43 @@
|
|
|
1
|
-
# v0.
|
|
1
|
+
# v0.13.0 (14-Jul-2024)
|
|
2
|
+
|
|
3
|
+
## Features
|
|
4
|
+
- Adds imaging data from PSP/WISPR.
|
|
5
|
+
- Implements new feature of Parker spiral and HEK events visualization on the images.
|
|
6
|
+
- Adds a method to get directly the geometrical model from model_fittings.
|
|
7
|
+
- Adds tests for extensions, WISPR imaging.
|
|
8
|
+
- Adds and improves docstrings in utilities, modules, and geometrical models.
|
|
9
|
+
- Adds GCS and kinematic plots in documentation
|
|
10
|
+
- Adds function reference in the documentation
|
|
11
|
+
|
|
12
|
+
## Minor Changes
|
|
13
|
+
- Changes some optional inputs for get_hek_flare, make_figure, plot_bodies, and plot_solar_reference_lines to be better utilised.
|
|
14
|
+
|
|
15
|
+
# v0.12.0 (09-Jun-2024)
|
|
16
|
+
|
|
17
|
+
## Features
|
|
18
|
+
- Adds more imaging data from SDO/AIA.
|
|
19
|
+
- Adds acceleration calculation in the kinematic plots.
|
|
20
|
+
- Implements acceleration plotting in the app.
|
|
21
|
+
- Includes fits file name in fitting files and dataframes.
|
|
22
|
+
- Highlights a row in the fitting table when fitting exist in table.
|
|
23
|
+
|
|
24
|
+
## Major Changes
|
|
25
|
+
- Decouples the loading of fits files from download_fits function.
|
|
26
|
+
|
|
27
|
+
## Minor Changes
|
|
28
|
+
- Improves configuration dictionary for selected imagers.
|
|
29
|
+
- Improves json warning message in the main app page.
|
|
30
|
+
- Adds documentation page link to the main app page.
|
|
31
|
+
- Updates README files.
|
|
32
|
+
- Improves plot_fitting_model and adds figure test.
|
|
33
|
+
- Improves application layout.
|
|
34
|
+
|
|
35
|
+
## Bug Fixes
|
|
36
|
+
- Fixes a potential bug in filter_maps when no filtering is applied.
|
|
37
|
+
- Fixes a bug with progress bar with stqdm.
|
|
38
|
+
- Fixes a bug with image processing mode selection.
|
|
39
|
+
|
|
40
|
+
# v0.11.0 (19-May-2024)
|
|
2
41
|
|
|
3
42
|
## Features
|
|
4
43
|
- Adds tests for ellipsoid location on AIA and STEREO COR images.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: PyThea
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.13.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
|
|
@@ -20,11 +20,11 @@ Classifier: Topic :: Scientific/Engineering :: Physics
|
|
|
20
20
|
Requires-Python: >=3.8, <3.11
|
|
21
21
|
Description-Content-Type: text/markdown
|
|
22
22
|
License-File: LICENSE.md
|
|
23
|
-
Requires-Dist: numpy
|
|
23
|
+
Requires-Dist: numpy==1.26.4
|
|
24
24
|
Requires-Dist: pandas
|
|
25
25
|
Requires-Dist: scipy
|
|
26
26
|
Requires-Dist: aiapy
|
|
27
|
-
Requires-Dist: astropy
|
|
27
|
+
Requires-Dist: astropy==6.0.0
|
|
28
28
|
Requires-Dist: astroquery
|
|
29
29
|
Requires-Dist: jplephem
|
|
30
30
|
Requires-Dist: numexpr
|
|
@@ -35,7 +35,6 @@ Requires-Dist: matplotlib
|
|
|
35
35
|
Requires-Dist: seaborn
|
|
36
36
|
Requires-Dist: streamlit
|
|
37
37
|
Requires-Dist: Pillow
|
|
38
|
-
Requires-Dist: stqdm
|
|
39
38
|
Requires-Dist: lxml
|
|
40
39
|
Requires-Dist: zeep
|
|
41
40
|
Requires-Dist: drms
|
|
@@ -63,8 +62,8 @@ We recommend, creating a virtual environment for _PyThea_ and installing the pac
|
|
|
63
62
|
If you use Anaconda or Miniconda (which we also recommend) you can create a virtual environment using ```conda``` and then install _PyThea_ using from PyPI using ```pip```. In the terminal do the following:
|
|
64
63
|
|
|
65
64
|
```python
|
|
66
|
-
# Create a virtual environment. Use python
|
|
67
|
-
conda create --name PyThea python=3.
|
|
65
|
+
# Create a virtual environment. Use python>3.9
|
|
66
|
+
conda create --name PyThea python=3.10
|
|
68
67
|
|
|
69
68
|
# Activate the environment
|
|
70
69
|
conda activate PyThea
|
|
@@ -138,7 +137,7 @@ If there is an error when running ```PyThea streamlit``` then you can manually r
|
|
|
138
137
|
|
|
139
138
|
## 📙 Usage
|
|
140
139
|
|
|
141
|
-
Complete documentation of the _PyThea_
|
|
140
|
+
Complete documentation of the _PyThea_ can be found in [https://www.pythea.org/](https://www.pythea.org/).
|
|
142
141
|
|
|
143
142
|
## 📦 Useful Python packages
|
|
144
143
|
|
|
@@ -23,7 +23,6 @@ from copy import copy
|
|
|
23
23
|
|
|
24
24
|
import astropy.units as u
|
|
25
25
|
import numpy as np
|
|
26
|
-
import stqdm # See also https://github.com/tqdm/tqdm
|
|
27
26
|
import streamlit as st
|
|
28
27
|
from astropy.coordinates import Distance, SkyCoord, SphericalRepresentation
|
|
29
28
|
from sunpy.coordinates import frames
|
|
@@ -38,8 +37,8 @@ from PyThea.modules import (date_and_event_selection, figure_streamlit,
|
|
|
38
37
|
fitting_and_slider_options_container,
|
|
39
38
|
fitting_sliders)
|
|
40
39
|
from PyThea.sunpy_dev.map.maputils import get_closest, maps_clims
|
|
41
|
-
from PyThea.utils import (download_fits,
|
|
42
|
-
single_imager_maps_process)
|
|
40
|
+
from PyThea.utils import (download_fits, load_fits, model_fittings,
|
|
41
|
+
plot_fitting_model, single_imager_maps_process)
|
|
43
42
|
from PyThea.version import version
|
|
44
43
|
|
|
45
44
|
|
|
@@ -49,6 +48,13 @@ def delete_from_state(vars):
|
|
|
49
48
|
del st.session_state[var]
|
|
50
49
|
|
|
51
50
|
|
|
51
|
+
def highlight_row(row, row_index):
|
|
52
|
+
if row.name.strftime('%Y-%m-%dT%H:%M:%S.%f') == row_index.strftime('%Y-%m-%dT%H:%M:%S.%f').values[0]:
|
|
53
|
+
return ['background-color: lightpink']*len(row)
|
|
54
|
+
else:
|
|
55
|
+
return ['']*len(row)
|
|
56
|
+
|
|
57
|
+
|
|
52
58
|
def footer_text():
|
|
53
59
|
st.subheader('About this application:')
|
|
54
60
|
st.markdown("""
|
|
@@ -65,16 +71,24 @@ def footer_text():
|
|
|
65
71
|
right.markdown("""
|
|
66
72
|
**Github**: Find the latest version here
|
|
67
73
|
[](https://github.com/AthKouloumvakos/PyThea) \n
|
|
68
|
-
**
|
|
74
|
+
**Documentation Page**: https://www.pythea.org/
|
|
69
75
|
""" +
|
|
70
76
|
f"""
|
|
71
77
|
**Version**: {version} (latest release [](https://github.com/AthKouloumvakos/PyThea/releases))
|
|
72
78
|
""")
|
|
73
79
|
left.image('https://github.com/AthKouloumvakos/PyThea/blob/master/docs/logo/pythea_logo.png?raw=true')
|
|
80
|
+
st.markdown("""
|
|
81
|
+
**Citation**: Please cite the following paper [](https://www.frontiersin.org/articles/10.3389/fspas.2022.974137/) and [](https://doi.org/10.5281/zenodo.5713659)
|
|
82
|
+
""")
|
|
83
|
+
st.info('''
|
|
84
|
+
More imaging data have been added:
|
|
85
|
+
- SDO/AIA images from 211A channel.
|
|
86
|
+
- PSP/WISPR inner and outer telescope images.
|
|
87
|
+
''', icon='ℹ️')
|
|
74
88
|
st.warning('''
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
''')
|
|
89
|
+
**NOTE: From PyThea >0.8.1 the JSON fitting files will be slightly different from the old ones.**
|
|
90
|
+
Due to a change in the fitting time input, the new fitting files may have slightly different times for the same images (see further information [here](https://github.com/AthKouloumvakos/PyThea/discussions/24)).
|
|
91
|
+
''', icon='⚠️')
|
|
78
92
|
st.markdown('---')
|
|
79
93
|
|
|
80
94
|
|
|
@@ -86,7 +100,10 @@ def run():
|
|
|
86
100
|
#############################################################
|
|
87
101
|
# set page config
|
|
88
102
|
st.set_page_config(page_title='PyThea', page_icon=':rocket:',
|
|
89
|
-
initial_sidebar_state='expanded'
|
|
103
|
+
initial_sidebar_state='expanded',
|
|
104
|
+
menu_items={
|
|
105
|
+
'Get Help': 'https://www.pythea.org/',
|
|
106
|
+
'Report a Bug': 'https://github.com/AthKouloumvakos/PyThea'})
|
|
90
107
|
|
|
91
108
|
#############################################################
|
|
92
109
|
# HTML Styles
|
|
@@ -94,7 +111,7 @@ def run():
|
|
|
94
111
|
|
|
95
112
|
#############################################################
|
|
96
113
|
# Main page information text
|
|
97
|
-
st.
|
|
114
|
+
st.header('PyThea: Reconstruct CMEs & Shocks')
|
|
98
115
|
|
|
99
116
|
#############################################################
|
|
100
117
|
# Startup Variables
|
|
@@ -106,7 +123,6 @@ def run():
|
|
|
106
123
|
|
|
107
124
|
if 'date_process' not in st.session_state:
|
|
108
125
|
date_and_event_selection(st)
|
|
109
|
-
st.markdown(""" #### ⏻ Select a day & solar event. """)
|
|
110
126
|
else:
|
|
111
127
|
st.sidebar.markdown('## Processing Event|Date:')
|
|
112
128
|
st.sidebar.info(f'{st.session_state.event_selected}')
|
|
@@ -182,7 +198,7 @@ def run():
|
|
|
182
198
|
key='imaging_time_range')
|
|
183
199
|
select_timerange_form.form_submit_button(label='Submit',
|
|
184
200
|
on_click=delete_from_state,
|
|
185
|
-
kwargs={'vars': ['map', 'map_', 'imagers_list_']})
|
|
201
|
+
kwargs={'vars': ['map', 'map_', 'imagers_list_', 'hek_responses']})
|
|
186
202
|
|
|
187
203
|
with st.sidebar.expander('Processing Options'):
|
|
188
204
|
procoption_container = st.container()
|
|
@@ -194,7 +210,8 @@ def run():
|
|
|
194
210
|
on_change=delete_from_state,
|
|
195
211
|
kwargs={'vars': ['map', 'imagers_list_', 'clim', 'clim_manual_low', 'clim_manual_high']})
|
|
196
212
|
if image_mode in ['Running Diff.', 'Base Diff.']:
|
|
197
|
-
|
|
213
|
+
min_diff = 1 if image_mode == 'Running Diff.' else 0
|
|
214
|
+
diff_value = procoption_container.number_input('Select Step/Image for Running/Base Diff.', min_diff, 5, key='diff_value',
|
|
198
215
|
on_change=delete_from_state,
|
|
199
216
|
kwargs={'vars': ['map', 'imagers_list_', 'clim', 'clim_manual_low', 'clim_manual_high']})
|
|
200
217
|
else:
|
|
@@ -206,32 +223,59 @@ def run():
|
|
|
206
223
|
plotviewopt_container = st.container()
|
|
207
224
|
plotviewopt_container.checkbox('Clip plot on image limits', value=True, key='clip_model')
|
|
208
225
|
plt_supp_imagers = plotviewopt_container.checkbox('Supplementary Imaging', value=False)
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
226
|
+
|
|
227
|
+
#############################################################
|
|
228
|
+
# Magnetic Connectivity
|
|
229
|
+
st.sidebar.markdown('## Overlays')
|
|
230
|
+
with st.sidebar.expander('Bodies or s/c Location'):
|
|
231
|
+
bodies_container = st.container()
|
|
232
|
+
bodies_container.checkbox('View Bodies or s/c', key='star_field')
|
|
233
|
+
bodies_container.multiselect('Select Bodies', options=selected_bodies.bodies_dict.keys(),
|
|
234
|
+
default=['Mercury', 'Venus', 'Jupiter'],
|
|
235
|
+
key='bodies_list',
|
|
236
|
+
disabled=not st.session_state.star_field)
|
|
237
|
+
with st.sidebar.expander('Limb and Meridians'):
|
|
238
|
+
limb_meridians_container = st.container()
|
|
239
|
+
limb_meridians_container.checkbox('View Limb and Meridians', key='plot_solar_reference_lines_')
|
|
240
|
+
markdown = '''
|
|
241
|
+
**Limb**: plots the solar limb as observed
|
|
242
|
+
for the selected observers.
|
|
243
|
+
**Central Meridian**: plots the central meridian
|
|
244
|
+
observed for the selected observers.
|
|
245
|
+
**CR Meridan+Equator**: plots the primary meridian
|
|
246
|
+
and equator of Carrington coordinate system.
|
|
247
|
+
'''.strip()
|
|
248
|
+
limb_meridians_container.selectbox('Select plot option',
|
|
249
|
+
options=['Limb from Obs.', 'Central Meridian from Obs.', 'Carr. Prime Meridian+Solar Equator',
|
|
250
|
+
'Stonyhurst Grid', 'Carrington Grid'],
|
|
251
|
+
help=markdown,
|
|
252
|
+
key='plot_solar_reference_lines_mode',
|
|
253
|
+
disabled=not st.session_state.plot_solar_reference_lines_)
|
|
254
|
+
disabled = False if (st.session_state.plot_solar_reference_lines_) and \
|
|
255
|
+
(st.session_state.plot_solar_reference_lines_mode in ['Limb from Obs.', 'Central Meridian from Obs.']) else True
|
|
256
|
+
limb_meridians_container.multiselect('Select Bodies',
|
|
257
|
+
label_visibility='collapsed',
|
|
258
|
+
options=selected_bodies.bodies_dict.keys(),
|
|
259
|
+
default=['Earth'], disabled=disabled,
|
|
260
|
+
key='plot_solar_reference_lines_bodies_list')
|
|
261
|
+
with st.sidebar.expander('Magnetic Connectivity'):
|
|
262
|
+
connectivity_container = st.container()
|
|
263
|
+
connectivity_container.checkbox('Plot Parker spirals', key='plot_parker_spirals')
|
|
264
|
+
connectivity_container.multiselect('Select bodies/spacecraft', options=selected_bodies.bodies_dict.keys(),
|
|
265
|
+
default=['Earth'], key='mag_bodies_list',
|
|
266
|
+
disabled=not st.session_state.plot_parker_spirals)
|
|
267
|
+
st.session_state.sw_speed_select = {}
|
|
268
|
+
for body in st.session_state.mag_bodies_list:
|
|
269
|
+
connectivity_container.number_input(f'{body} solar wind speed', min_value=200, max_value=800, value=350, step=50,
|
|
270
|
+
key=f'sw_speed_select_{body}',
|
|
271
|
+
disabled=not st.session_state.plot_parker_spirals)
|
|
272
|
+
st.session_state.sw_speed_select[body] = st.session_state[f'sw_speed_select_{body}'] * (u.km/u.second)
|
|
273
|
+
with st.sidebar.expander('HEK feature/events'):
|
|
274
|
+
hek_container = st.container()
|
|
275
|
+
hek_container.checkbox('Plot HEK feature/events', key='plot_hek', on_change=delete_from_state,
|
|
276
|
+
kwargs={'vars': ['hek_responses', ]})
|
|
277
|
+
hek_container.multiselect('Select HEK feature/events', options=['Active Regions', 'Coronal Holes', 'Flares'],
|
|
278
|
+
default=['Flares'], key='hek_list', disabled=not st.session_state.plot_hek)
|
|
235
279
|
|
|
236
280
|
#############################################################
|
|
237
281
|
# Download and Process the Images
|
|
@@ -245,15 +289,16 @@ def run():
|
|
|
245
289
|
st.session_state.map_ = {} if 'map_' not in st.session_state else st.session_state.map_
|
|
246
290
|
st.session_state.map = {} if 'map' not in st.session_state else st.session_state.map
|
|
247
291
|
st.session_state['imagers_list_'] = imagers_list
|
|
248
|
-
progress_bar =
|
|
249
|
-
for imager in
|
|
250
|
-
progress_bar.
|
|
292
|
+
progress_bar = st.progress(0, text='Preparing to Download data')
|
|
293
|
+
for i, imager in enumerate(imager_added):
|
|
294
|
+
progress_bar.progress(i/len(imager_added), text=f'Download {imager} images from VSO')
|
|
251
295
|
if imager not in st.session_state.map_:
|
|
252
296
|
timerange = a.Time(st.session_state.date_process + datetime.timedelta(hours=imaging_time_range[0]),
|
|
253
297
|
st.session_state.date_process + datetime.timedelta(hours=imaging_time_range[1]))
|
|
254
|
-
|
|
298
|
+
downloaded_files = download_fits(timerange, imager)
|
|
299
|
+
st.session_state.map_[imager] = load_fits(downloaded_files)
|
|
255
300
|
st.session_state.map_[imager] = single_imager_maps_process(st.session_state.map_[imager],
|
|
256
|
-
**selected_imagers.imager_dict[imager][
|
|
301
|
+
**selected_imagers.imager_dict[imager]['process'],
|
|
257
302
|
skip='sequence_processing')
|
|
258
303
|
processed_images = single_imager_maps_process(st.session_state.map_[imager],
|
|
259
304
|
skip=['filter', 'prepare'],
|
|
@@ -265,6 +310,7 @@ def run():
|
|
|
265
310
|
else:
|
|
266
311
|
st.session_state.imagers_list_.remove(imager)
|
|
267
312
|
st.session_state.map_colormap_limits.pop(imager, None)
|
|
313
|
+
progress_bar.empty()
|
|
268
314
|
|
|
269
315
|
if imager_removed != []:
|
|
270
316
|
st.session_state['imagers_list_'] = imagers_list
|
|
@@ -281,13 +327,14 @@ def run():
|
|
|
281
327
|
col1, col2 = st.columns((1, 3))
|
|
282
328
|
imager_select = col1.selectbox('Select an imager',
|
|
283
329
|
options=st.session_state.imagers_list_,
|
|
284
|
-
on_change=delete_from_state, kwargs={'vars': ['clim', 'clim_manual_low', 'clim_manual_high']})
|
|
330
|
+
on_change=delete_from_state, kwargs={'vars': ['clim', 'clim_manual_low', 'clim_manual_high', 'hek_responses']})
|
|
285
331
|
|
|
286
332
|
maps_date = [getattr(maps, 'date_average', None) or getattr(maps, 'date', None) for maps in st.session_state.map[imager_select]]
|
|
287
333
|
if len(maps_date) > 1:
|
|
288
334
|
running_map_date = col2.select_slider('Slide to the image time',
|
|
289
335
|
options=maps_date, value=maps_date[0],
|
|
290
|
-
key='running_map_date'
|
|
336
|
+
key='running_map_date',
|
|
337
|
+
on_change=delete_from_state, kwargs={'vars': ['hek_responses']})
|
|
291
338
|
else:
|
|
292
339
|
running_map_date = maps_date[0]
|
|
293
340
|
|
|
@@ -350,6 +397,15 @@ def run():
|
|
|
350
397
|
fig, axis = figure_streamlit(st, running_map, image_mode, imager_select, model)
|
|
351
398
|
st.pyplot(fig)
|
|
352
399
|
|
|
400
|
+
if st.session_state.plot_hek and st.session_state.hek_responses['Flares']:
|
|
401
|
+
st.markdown('**HEK Flare List:**')
|
|
402
|
+
st.write(st.session_state.hek_responses['Flares'].to_pandas())
|
|
403
|
+
st.markdown('*Flares with no location have been removed from the table.')
|
|
404
|
+
if st.session_state.plot_hek and st.session_state.hek_responses['Active Regions']:
|
|
405
|
+
st.markdown('**HEK Active Regions List:**')
|
|
406
|
+
st.write(st.session_state.hek_responses['Active Regions'].to_pandas())
|
|
407
|
+
st.markdown('*Active Regions without NOAA number have been removed from the table.')
|
|
408
|
+
|
|
353
409
|
if plt_supp_imagers:
|
|
354
410
|
if len(st.session_state.imagers_list_) < 3:
|
|
355
411
|
other_element = [element for element in st.session_state.imagers_list_ if element != imager_select][0]
|
|
@@ -374,6 +430,7 @@ def run():
|
|
|
374
430
|
# Store the fitting
|
|
375
431
|
single_fit = model.to_dataframe()
|
|
376
432
|
single_fit['imager'] = imager_select
|
|
433
|
+
single_fit['fits_file'] = running_map.meta['fits_file']
|
|
377
434
|
|
|
378
435
|
if store_fit_button_pressed:
|
|
379
436
|
if 'model_fittings' not in st.session_state:
|
|
@@ -390,10 +447,13 @@ def run():
|
|
|
390
447
|
st.markdown('---')
|
|
391
448
|
st.markdown('### Parameters Table')
|
|
392
449
|
st.markdown('**Running Fitting Table:**')
|
|
393
|
-
|
|
450
|
+
col_formats = {col: '{:,.2f}'.format for col in single_fit.select_dtypes(include='number').columns}
|
|
451
|
+
st.dataframe(single_fit.style.format(col_formats))
|
|
394
452
|
if 'model_fittings' in st.session_state:
|
|
395
453
|
st.markdown('**Stored Fitting Table:**')
|
|
396
|
-
st.dataframe(st.session_state.model_fittings.parameters
|
|
454
|
+
st.dataframe(st.session_state.model_fittings.parameters.style.apply(highlight_row,
|
|
455
|
+
row_index=single_fit.index, axis=1).format(col_formats)
|
|
456
|
+
)
|
|
397
457
|
col1, col2 = st.columns((2, 2))
|
|
398
458
|
col2.selectbox('Select a fitting',
|
|
399
459
|
options=st.session_state.model_fittings.parameters.index,
|
|
@@ -413,7 +473,7 @@ def run():
|
|
|
413
473
|
st.markdown('### Plots of kinematics ')
|
|
414
474
|
col1, col2, col3 = st.columns(3)
|
|
415
475
|
plt_kinematics_select = col1.selectbox('Select Plots',
|
|
416
|
-
options=['All', 'HeightT', 'SpeedT', 'Long-LatT'])
|
|
476
|
+
options=['All', 'HeightT', 'SpeedT', 'AccelerationT', 'Long-LatT'])
|
|
417
477
|
|
|
418
478
|
fit_mode = col2.selectbox('Select Fitting Mode',
|
|
419
479
|
options=['polynomial', 'spline', 'custom'],
|
|
@@ -3,10 +3,24 @@ from sunpy.coordinates import frames
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
def load_or_delete_fittings(st):
|
|
6
|
+
"""
|
|
7
|
+
Load or delete fitting parameters from the model fittings based on user selection.
|
|
8
|
+
|
|
9
|
+
Parameters
|
|
10
|
+
----------
|
|
11
|
+
st : Streamlit session state object
|
|
12
|
+
Streamlit session state object for managing UI components.
|
|
13
|
+
|
|
14
|
+
Returns
|
|
15
|
+
-------
|
|
16
|
+
None
|
|
17
|
+
"""
|
|
6
18
|
selected_row = str(st.session_state.fitting_select)
|
|
7
19
|
dataframe = st.session_state.model_fittings.parameters
|
|
20
|
+
|
|
8
21
|
if st.session_state.fit_action == 'Select':
|
|
9
22
|
pass
|
|
23
|
+
|
|
10
24
|
elif st.session_state.fit_action == 'Load':
|
|
11
25
|
if st.session_state.coord_system == 'HGS':
|
|
12
26
|
st.session_state.longit = float(dataframe.loc[selected_row, 'hgln'])
|
|
@@ -27,6 +41,7 @@ def load_or_delete_fittings(st):
|
|
|
27
41
|
# del st.session_state[key]
|
|
28
42
|
st.session_state[key] = float(dataframe.loc[selected_row, key])
|
|
29
43
|
del st.session_state.fit_action
|
|
44
|
+
|
|
30
45
|
elif st.session_state.fit_action == 'Delete':
|
|
31
46
|
st.session_state.model_fittings.parameters = dataframe.drop(st.session_state.fitting_select)
|
|
32
47
|
del st.session_state.fitting_select
|
|
@@ -36,6 +51,18 @@ def load_or_delete_fittings(st):
|
|
|
36
51
|
|
|
37
52
|
|
|
38
53
|
def change_long_lat_sliders(st):
|
|
54
|
+
"""
|
|
55
|
+
Update longitude and latitude sliders based on the selected coordinate system.
|
|
56
|
+
|
|
57
|
+
Parameters
|
|
58
|
+
----------
|
|
59
|
+
st : Streamlit session state object
|
|
60
|
+
Streamlit session state object for managing UI components.
|
|
61
|
+
|
|
62
|
+
Returns
|
|
63
|
+
-------
|
|
64
|
+
None
|
|
65
|
+
"""
|
|
39
66
|
if st.session_state.coord_system == 'HGS':
|
|
40
67
|
center_ = st.session_state.center.transform_to(frames.HeliographicStonyhurst)
|
|
41
68
|
elif st.session_state.coord_system == 'HGC':
|
|
@@ -46,9 +73,22 @@ def change_long_lat_sliders(st):
|
|
|
46
73
|
|
|
47
74
|
|
|
48
75
|
def change_fitting_sliders(st):
|
|
76
|
+
"""
|
|
77
|
+
Update fitting sliders based on the selected fitting method.
|
|
78
|
+
|
|
79
|
+
Parameters
|
|
80
|
+
----------
|
|
81
|
+
st : Streamlit session state object
|
|
82
|
+
Streamlit session state object for managing UI components.
|
|
83
|
+
|
|
84
|
+
Returns
|
|
85
|
+
-------
|
|
86
|
+
None
|
|
87
|
+
"""
|
|
49
88
|
st.session_state.startup['fitting'] = False
|
|
50
89
|
fit_opt = st.session_state.fit_args_prime
|
|
51
90
|
st.session_state.fit_mode = fit_opt['type']
|
|
91
|
+
|
|
52
92
|
if fit_opt['type'] == 'polynomial':
|
|
53
93
|
st.session_state.polyfit_order = fit_opt['order']
|
|
54
94
|
elif fit_opt['type'] == 'spline':
|
|
@@ -1,9 +1,4 @@
|
|
|
1
1
|
def apply(st):
|
|
2
|
-
# Hide the menu button
|
|
3
|
-
st.markdown(""" <style>
|
|
4
|
-
#MainMenu {visibility: hidden;}
|
|
5
|
-
footer {visibility: hidden;}
|
|
6
|
-
</style> """, unsafe_allow_html=True)
|
|
7
2
|
# Do some css styling tricks here (e.g. remove the padding)
|
|
8
3
|
# https://discuss.streamlit.io/t/reduce-white-space-top-of-the-page/21737/3
|
|
9
4
|
st.markdown("""
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
'''
|
|
2
|
+
A dictionary of the selected imagers
|
|
3
|
+
How to use this:
|
|
4
|
+
|
|
5
|
+
'''
|
|
6
|
+
import astropy.units as u
|
|
7
|
+
from sunpy.net import attrs as a
|
|
8
|
+
|
|
9
|
+
imager_dict = {}
|
|
10
|
+
|
|
11
|
+
imager_dict['LC2'] = {'fido': (a.Instrument.lasco, a.Detector.c2),
|
|
12
|
+
'process': {'dimensions': (1024*u.pixel, 1024*u.pixel), 'polar': 'Clear', 'superpixel': 2},
|
|
13
|
+
'source': 'SOHO', 'instrument': 'LASCO', 'detector': 'C2'}
|
|
14
|
+
|
|
15
|
+
imager_dict['LC3'] = {'fido': (a.Instrument.lasco, a.Detector.c3),
|
|
16
|
+
'process': {'dimensions': (1024*u.pixel, 1024*u.pixel), 'polar': 'Clear', 'superpixel': 2},
|
|
17
|
+
'source': 'SOHO', 'instrument': 'LASCO', 'detector': 'C3'}
|
|
18
|
+
|
|
19
|
+
imager_dict['AIA-193'] = {'fido': (a.Instrument.aia, a.Wavelength(19.3 * u.nm), a.Sample(1*u.minute)),
|
|
20
|
+
'process': {'dimensions': (4096*u.pixel, 4096*u.pixel), 'superpixel': 8, 'exposure': 1.90},
|
|
21
|
+
'source': 'SDO', 'instrument': 'AIA', 'wavelength': '193'}
|
|
22
|
+
|
|
23
|
+
imager_dict['AIA-211'] = {'fido': (a.Instrument.aia, a.Wavelength(21.1 * u.nm), a.Sample(1*u.minute)),
|
|
24
|
+
'process': {'dimensions': (4096*u.pixel, 4096*u.pixel), 'superpixel': 8, 'exposure': 1.90},
|
|
25
|
+
'source': 'SDO', 'instrument': 'AIA', 'wavelength': '211'}
|
|
26
|
+
|
|
27
|
+
imager_dict['COR2A'] = {'fido': (a.Source('STEREO_A'), a.Detector.cor2),
|
|
28
|
+
'process': {'dimensions': (2048*u.pixel, 2048*u.pixel), 'polar': 1001, 'superpixel': 4},
|
|
29
|
+
'source': 'STEREO_A', 'instrument': 'SECCHI', 'detector': 'COR2'}
|
|
30
|
+
|
|
31
|
+
imager_dict['COR2B'] = {'fido': (a.Source('STEREO_B'), a.Detector.cor2),
|
|
32
|
+
'process': {'dimensions': (2048*u.pixel, 2048*u.pixel), 'polar': 1001, 'superpixel': 4},
|
|
33
|
+
'source': 'STEREO_B', 'instrument': 'SECCHI', 'detector': 'COR2'}
|
|
34
|
+
|
|
35
|
+
imager_dict['EUVIA'] = {'fido': (a.Source('STEREO_A'), a.Detector.euvi, a.Wavelength(19.5 * u.nm)),
|
|
36
|
+
'process': {'dimensions': (2048*u.pixel, 2048*u.pixel), 'superpixel': 4},
|
|
37
|
+
'source': 'STEREO_A', 'instrument': 'SECCHI', 'detector': 'EUVI'}
|
|
38
|
+
|
|
39
|
+
imager_dict['EUVIB'] = {'fido': (a.Source('STEREO_B'), a.Detector.euvi, a.Wavelength(19.5 * u.nm)),
|
|
40
|
+
'process': {'dimensions': (2048*u.pixel, 2048*u.pixel), 'superpixel': 4},
|
|
41
|
+
'source': 'STEREO_B', 'instrument': 'SECCHI', 'detector': 'EUVI'}
|
|
42
|
+
|
|
43
|
+
imager_dict['COR1A'] = {'fido': (a.Source('STEREO_A'), a.Detector.cor1),
|
|
44
|
+
'process': {'dimensions': (512*u.pixel, 512*u.pixel)},
|
|
45
|
+
'source': 'STEREO_A', 'instrument': 'SECCHI', 'detector': 'COR1'}
|
|
46
|
+
|
|
47
|
+
imager_dict['COR1B'] = {'fido': (a.Source('STEREO_B'), a.Detector.cor1),
|
|
48
|
+
'process': {'dimensions': (512*u.pixel, 512*u.pixel)},
|
|
49
|
+
'source': 'STEREO_B', 'instrument': 'SECCHI', 'detector': 'COR1'}
|
|
50
|
+
|
|
51
|
+
imager_dict['HI1A'] = {'fido': (a.Source('STEREO_A'), a.Detector.hi1),
|
|
52
|
+
'process': {'dimensions': (1024*u.pixel, 1024*u.pixel), 'superpixel': 2},
|
|
53
|
+
'source': 'STEREO_A', 'instrument': 'SECCHI', 'detector': 'HI1'}
|
|
54
|
+
|
|
55
|
+
imager_dict['HI1B'] = {'fido': (a.Source('STEREO_B'), a.Detector.hi1),
|
|
56
|
+
'process': {'dimensions': (1024*u.pixel, 1024*u.pixel), 'superpixel': 2},
|
|
57
|
+
'source': 'STEREO_B', 'instrument': 'SECCHI', 'detector': 'HI1'}
|
|
58
|
+
|
|
59
|
+
imager_dict['HI2A'] = {'fido': (a.Source('STEREO_A'), a.Detector.hi2),
|
|
60
|
+
'process': {'dimensions': (1024*u.pixel, 1024*u.pixel), 'superpixel': 2},
|
|
61
|
+
'source': 'STEREO_A', 'instrument': 'SECCHI', 'detector': 'HI2'}
|
|
62
|
+
|
|
63
|
+
imager_dict['HI2B'] = {'fido': (a.Source('STEREO_B'), a.Detector.hi2),
|
|
64
|
+
'process': {'dimensions': (1024*u.pixel, 1024*u.pixel), 'superpixel': 2},
|
|
65
|
+
'source': 'STEREO_B', 'instrument': 'SECCHI', 'detector': 'HI2'}
|
|
66
|
+
|
|
67
|
+
imager_dict['WISPR1'] = {'fido': (a.Instrument.wispr, a.Detector.inner),
|
|
68
|
+
'process': {'dimensions': (960*u.pixel, 1024*u.pixel), 'processing_level': 3, 'superpixel': 2},
|
|
69
|
+
'source': 'PSP', 'instrument': 'WISPR', 'detector': 'Inner'}
|
|
70
|
+
|
|
71
|
+
imager_dict['WISPR2'] = {'fido': (a.Instrument.wispr, a.Detector.outer),
|
|
72
|
+
'process': {'dimensions': (960*u.pixel, 1024*u.pixel), 'processing_level': 3, 'superpixel': 2},
|
|
73
|
+
'source': 'PSP', 'instrument': 'WISPR', 'detector': 'Outer'}
|
|
@@ -26,10 +26,19 @@ stereo_sample_data = pooch.create(
|
|
|
26
26
|
},
|
|
27
27
|
)
|
|
28
28
|
|
|
29
|
+
wispr_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
|
+
'psp_l3_wispr_20210808t103707_v1_1211.fits': 'sha256:85035693c4677e8fa8a3e61b8051d6f0a46e96806b5b0cbdb3efa77652308bda',
|
|
34
|
+
'psp_l3_wispr_20210808t104010_v1_2222.fits': 'sha256:5e55e17f1aed7dc96f88b79f092947c58e6ee0def1b72822dbf1a696d8df7e6f'
|
|
35
|
+
},
|
|
36
|
+
)
|
|
37
|
+
|
|
29
38
|
json_fitting_file_sample_data = pooch.create(
|
|
30
39
|
path=os.path.join(database_dir, 'sample_data'), # The cache folder
|
|
31
40
|
base_url=f'{github_main_url}/raw/main/data/', # The remote data url on Github
|
|
32
41
|
registry={
|
|
33
|
-
'FLX1p0D20211028T153500MEllipsoid.json': 'sha256:
|
|
42
|
+
'FLX1p0D20211028T153500MEllipsoid.json': 'sha256:34fced8530875110117ba27a73541d3acd0c90bc8fca99367c1ec4cdfc05ce86',
|
|
34
43
|
},
|
|
35
44
|
)
|