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.
Files changed (66) hide show
  1. pythea-0.13.0/.readthedocs.yaml +29 -0
  2. {pythea-0.11.0 → pythea-0.13.0}/CHANGELOG.md +40 -1
  3. {pythea-0.11.0/PyThea.egg-info → pythea-0.13.0}/PKG-INFO +6 -7
  4. {pythea-0.11.0 → pythea-0.13.0}/PyThea/PyThea_app.py +108 -48
  5. {pythea-0.11.0 → pythea-0.13.0}/PyThea/_version.py +2 -2
  6. {pythea-0.11.0 → pythea-0.13.0}/PyThea/callbacks.py +40 -0
  7. {pythea-0.11.0 → pythea-0.13.0}/PyThea/config/app_styles.py +0 -5
  8. pythea-0.13.0/PyThea/config/selected_imagers.py +73 -0
  9. {pythea-0.11.0 → pythea-0.13.0}/PyThea/data/sample_data.py +10 -1
  10. pythea-0.13.0/PyThea/extensions/Parker_spirals/__init__.py +62 -0
  11. pythea-0.13.0/PyThea/extensions/Parker_spirals/utils.py +43 -0
  12. pythea-0.13.0/PyThea/extensions/hek/utils.py +118 -0
  13. {pythea-0.11.0 → pythea-0.13.0}/PyThea/geometrical_models.py +123 -30
  14. {pythea-0.11.0 → pythea-0.13.0}/PyThea/modules.py +169 -25
  15. {pythea-0.11.0 → pythea-0.13.0}/PyThea/sunpy_dev/map/maputils.py +15 -2
  16. pythea-0.13.0/PyThea/test/__init__.py +0 -0
  17. {pythea-0.11.0 → pythea-0.13.0}/PyThea/test/figure_hashes.json +4 -1
  18. pythea-0.13.0/PyThea/test/test_extension_utils.py +56 -0
  19. {pythea-0.11.0 → pythea-0.13.0}/PyThea/test/test_figures.py +98 -1
  20. {pythea-0.11.0 → pythea-0.13.0}/PyThea/test/test_remote_clients.py +2 -2
  21. {pythea-0.11.0 → pythea-0.13.0}/PyThea/test/test_utils.py +37 -5
  22. pythea-0.13.0/PyThea/utils.py +957 -0
  23. {pythea-0.11.0 → pythea-0.13.0/PyThea.egg-info}/PKG-INFO +6 -7
  24. {pythea-0.11.0 → pythea-0.13.0}/PyThea.egg-info/SOURCES.txt +6 -0
  25. {pythea-0.11.0 → pythea-0.13.0}/PyThea.egg-info/requires.txt +2 -3
  26. {pythea-0.11.0 → pythea-0.13.0}/README.md +3 -3
  27. {pythea-0.11.0 → pythea-0.13.0}/README_pypi.md +3 -3
  28. {pythea-0.11.0 → pythea-0.13.0}/environment.yml +3 -4
  29. {pythea-0.11.0 → pythea-0.13.0}/requirements.txt +2 -3
  30. {pythea-0.11.0 → pythea-0.13.0}/setup.cfg +4 -0
  31. pythea-0.11.0/PyThea/config/selected_imagers.py +0 -34
  32. pythea-0.11.0/PyThea/utils.py +0 -496
  33. {pythea-0.11.0 → pythea-0.13.0}/LICENSE.md +0 -0
  34. {pythea-0.11.0 → pythea-0.13.0}/MANIFEST.in +0 -0
  35. {pythea-0.11.0 → pythea-0.13.0}/PyThea/__init__.py +0 -0
  36. {pythea-0.11.0 → pythea-0.13.0}/PyThea/config/__init__.py +0 -0
  37. {pythea-0.11.0 → pythea-0.13.0}/PyThea/config/config_sliders.py +0 -0
  38. {pythea-0.11.0 → pythea-0.13.0}/PyThea/config/selected_bodies.py +0 -0
  39. {pythea-0.11.0 → pythea-0.13.0}/PyThea/data/__init__.py +0 -0
  40. {pythea-0.11.0 → pythea-0.13.0}/PyThea/extensions/LICENSE_gcs_python.md +0 -0
  41. {pythea-0.11.0 → pythea-0.13.0}/PyThea/extensions/__init__.py +0 -0
  42. {pythea-0.11.0 → pythea-0.13.0}/PyThea/extensions/buttons.py +0 -0
  43. {pythea-0.11.0/PyThea/sunpy_dev → pythea-0.13.0/PyThea/extensions/hek}/__init__.py +0 -0
  44. {pythea-0.11.0 → pythea-0.13.0}/PyThea/pythea_cli.py +0 -0
  45. {pythea-0.11.0/PyThea/sunpy_dev/extern → pythea-0.13.0/PyThea/sunpy_dev}/__init__.py +0 -0
  46. {pythea-0.11.0/PyThea/sunpy_dev/extern/sunkit_instruments → pythea-0.13.0/PyThea/sunpy_dev/extern}/__init__.py +0 -0
  47. {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
  48. {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
  49. {pythea-0.11.0 → pythea-0.13.0}/PyThea/sunpy_dev/extern/sunkit_instruments/aia/utils.py +0 -0
  50. {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
  51. {pythea-0.11.0 → pythea-0.13.0}/PyThea/sunpy_dev/extern/sunkit_instruments/lasco/utils.py +0 -0
  52. {pythea-0.11.0/PyThea/sunpy_dev/map → pythea-0.13.0/PyThea/sunpy_dev/extern/sunkit_instruments/stereo}/__init__.py +0 -0
  53. {pythea-0.11.0 → pythea-0.13.0}/PyThea/sunpy_dev/extern/sunkit_instruments/stereo/utils.py +0 -0
  54. {pythea-0.11.0/PyThea/test → pythea-0.13.0/PyThea/sunpy_dev/map}/__init__.py +0 -0
  55. {pythea-0.11.0 → pythea-0.13.0}/PyThea/test/Pythea_test.py +0 -0
  56. {pythea-0.11.0 → pythea-0.13.0}/PyThea/test/conftest.py +0 -0
  57. {pythea-0.11.0 → pythea-0.13.0}/PyThea/test/test_geometrical_models.py +0 -0
  58. {pythea-0.11.0 → pythea-0.13.0}/PyThea/test/test_imports.py +0 -0
  59. {pythea-0.11.0 → pythea-0.13.0}/PyThea/version.py +0 -0
  60. {pythea-0.11.0 → pythea-0.13.0}/PyThea.egg-info/.DS_Store +0 -0
  61. {pythea-0.11.0 → pythea-0.13.0}/PyThea.egg-info/dependency_links.txt +0 -0
  62. {pythea-0.11.0 → pythea-0.13.0}/PyThea.egg-info/entry_points.txt +0 -0
  63. {pythea-0.11.0 → pythea-0.13.0}/PyThea.egg-info/not-zip-safe +0 -0
  64. {pythea-0.11.0 → pythea-0.13.0}/PyThea.egg-info/top_level.txt +0 -0
  65. {pythea-0.11.0 → pythea-0.13.0}/pyproject.toml +0 -0
  66. {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.11.0 (17-April-2024)
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.11.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=3.8 or 3.9
67
- conda create --name PyThea python=3.9
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_ is under construction.
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, model_fittings, plot_fitting_model,
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
  [![GitHub](https://img.shields.io/badge/github-%23121011.svg?style=for-the-badge&logo=github&logoColor=white)](https://github.com/AthKouloumvakos/PyThea) \n
68
- **Citation**: Cite PyThea as [![https://doi.org/10.5281/zenodo.5713659](https://zenodo.org/badge/DOI/10.5281/zenodo.5713659.svg)](https://doi.org/10.5281/zenodo.5713659) \n
74
+ **Documentation Page**: https://www.pythea.org/
69
75
  """ +
70
76
  f"""
71
77
  **Version**: {version} (latest release [![Version](https://img.shields.io/github/v/release/AthKouloumvakos/PyThea)](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/](https://img.shields.io/static/v1?label=Paper&message=Frontiers&color=red)](https://www.frontiersin.org/articles/10.3389/fspas.2022.974137/) and [![https://doi.org/10.5281/zenodo.5713659](https://zenodo.org/badge/DOI/10.5281/zenodo.5713659.svg)](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
- ⚠️ **NOTE: From PyThea >0.8.1 the JSON fitting files will be slightly different from the old ones.** ⚠️
76
- * 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)).
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.title('PyThea: Reconstruct CMEs & Shocks')
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
- diff_value = procoption_container.number_input('Select Step/Image for Running/Base Diff.', 1, 5, key='diff_value',
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
- plotviewopt_container.checkbox('View Bodies or s/c', key='star_field')
210
- if st.session_state.star_field:
211
- plotviewopt_container.multiselect('Select Bodies', options=selected_bodies.bodies_dict.keys(),
212
- default=['Mercury', 'Venus', 'Jupiter'],
213
- key='bodies_list')
214
- plotviewopt_container.checkbox('View Limb and Meridians', key='plot_solar_reference_lines_')
215
- if st.session_state.plot_solar_reference_lines_:
216
- markdown = '''
217
- **Limb**: plots the solar limb as observed # noqa
218
- for the selected observers. # noqa
219
- **Central Meridian**: plots the central meridian # noqa
220
- observed for the selected observers. # noqa
221
- **CR Meridan+Equator**: plots the primary meridian # noqa
222
- and equator of Carrington coordinate system. # noqa
223
- '''.strip()
224
- plotviewopt_container.selectbox('Select plot option',
225
- options=['Limb from Obs.', 'Central Meridian from Obs.', 'Carr. Prime Meridian+Solar Equator',
226
- 'Stonyhurst Grid', 'Carrington Grid'],
227
- help=markdown,
228
- key='plot_solar_reference_lines_mode')
229
- disabled = False if st.session_state.plot_solar_reference_lines_mode in ['Limb from Obs.', 'Central Meridian from Obs.'] else True
230
- plotviewopt_container.multiselect('Select Bodies',
231
- label_visibility='collapsed',
232
- options=selected_bodies.bodies_dict.keys(),
233
- default=['Earth'], disabled=disabled,
234
- key='plot_solar_reference_lines_bodies_list')
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 = stqdm.stqdm(imager_added, desc='Preparing to Download data')
249
- for imager in progress_bar:
250
- progress_bar.desc = f'Downloaded {imager} images from VSO'
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
- st.session_state.map_[imager] = download_fits(timerange, imager)
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][1],
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
- st.dataframe(single_fit)
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'],
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '0.11.0'
16
- __version_tuple__ = version_tuple = (0, 11, 0)
15
+ __version__ = version = '0.13.0'
16
+ __version_tuple__ = version_tuple = (0, 13, 0)
@@ -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:700687ed982317400ec409390571747694237de9688a2816baa7b1770b75c9b1',
42
+ 'FLX1p0D20211028T153500MEllipsoid.json': 'sha256:34fced8530875110117ba27a73541d3acd0c90bc8fca99367c1ec4cdfc05ce86',
34
43
  },
35
44
  )