PyThea 0.11.0__tar.gz → 0.12.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.12.0/.readthedocs.yaml +29 -0
- {pythea-0.11.0 → pythea-0.12.0}/CHANGELOG.md +26 -1
- {pythea-0.11.0/PyThea.egg-info → pythea-0.12.0}/PKG-INFO +4 -5
- {pythea-0.11.0 → pythea-0.12.0}/PyThea/PyThea_app.py +41 -19
- {pythea-0.11.0 → pythea-0.12.0}/PyThea/_version.py +2 -2
- {pythea-0.11.0 → pythea-0.12.0}/PyThea/config/app_styles.py +0 -5
- pythea-0.12.0/PyThea/config/selected_imagers.py +65 -0
- {pythea-0.11.0 → pythea-0.12.0}/PyThea/data/sample_data.py +1 -1
- {pythea-0.11.0 → pythea-0.12.0}/PyThea/sunpy_dev/map/maputils.py +7 -2
- {pythea-0.11.0 → pythea-0.12.0}/PyThea/test/figure_hashes.json +2 -1
- {pythea-0.11.0 → pythea-0.12.0}/PyThea/test/test_figures.py +28 -1
- {pythea-0.11.0 → pythea-0.12.0}/PyThea/test/test_remote_clients.py +2 -2
- {pythea-0.11.0 → pythea-0.12.0}/PyThea/utils.py +95 -29
- {pythea-0.11.0 → pythea-0.12.0/PyThea.egg-info}/PKG-INFO +4 -5
- {pythea-0.11.0 → pythea-0.12.0}/PyThea.egg-info/SOURCES.txt +1 -0
- {pythea-0.11.0 → pythea-0.12.0}/PyThea.egg-info/requires.txt +0 -1
- {pythea-0.11.0 → pythea-0.12.0}/README.md +3 -3
- {pythea-0.11.0 → pythea-0.12.0}/README_pypi.md +3 -3
- {pythea-0.11.0 → pythea-0.12.0}/environment.yml +0 -1
- {pythea-0.11.0 → pythea-0.12.0}/requirements.txt +0 -1
- {pythea-0.11.0 → pythea-0.12.0}/setup.cfg +4 -0
- pythea-0.11.0/PyThea/config/selected_imagers.py +0 -34
- {pythea-0.11.0 → pythea-0.12.0}/LICENSE.md +0 -0
- {pythea-0.11.0 → pythea-0.12.0}/MANIFEST.in +0 -0
- {pythea-0.11.0 → pythea-0.12.0}/PyThea/__init__.py +0 -0
- {pythea-0.11.0 → pythea-0.12.0}/PyThea/callbacks.py +0 -0
- {pythea-0.11.0 → pythea-0.12.0}/PyThea/config/__init__.py +0 -0
- {pythea-0.11.0 → pythea-0.12.0}/PyThea/config/config_sliders.py +0 -0
- {pythea-0.11.0 → pythea-0.12.0}/PyThea/config/selected_bodies.py +0 -0
- {pythea-0.11.0 → pythea-0.12.0}/PyThea/data/__init__.py +0 -0
- {pythea-0.11.0 → pythea-0.12.0}/PyThea/extensions/LICENSE_gcs_python.md +0 -0
- {pythea-0.11.0 → pythea-0.12.0}/PyThea/extensions/__init__.py +0 -0
- {pythea-0.11.0 → pythea-0.12.0}/PyThea/extensions/buttons.py +0 -0
- {pythea-0.11.0 → pythea-0.12.0}/PyThea/geometrical_models.py +0 -0
- {pythea-0.11.0 → pythea-0.12.0}/PyThea/modules.py +0 -0
- {pythea-0.11.0 → pythea-0.12.0}/PyThea/pythea_cli.py +0 -0
- {pythea-0.11.0 → pythea-0.12.0}/PyThea/sunpy_dev/__init__.py +0 -0
- {pythea-0.11.0 → pythea-0.12.0}/PyThea/sunpy_dev/extern/__init__.py +0 -0
- {pythea-0.11.0 → pythea-0.12.0}/PyThea/sunpy_dev/extern/sunkit_instruments/__init__.py +0 -0
- {pythea-0.11.0 → pythea-0.12.0}/PyThea/sunpy_dev/extern/sunkit_instruments/aia/__init__.py +0 -0
- {pythea-0.11.0 → pythea-0.12.0}/PyThea/sunpy_dev/extern/sunkit_instruments/aia/utils.py +0 -0
- {pythea-0.11.0 → pythea-0.12.0}/PyThea/sunpy_dev/extern/sunkit_instruments/lasco/__init__.py +0 -0
- {pythea-0.11.0 → pythea-0.12.0}/PyThea/sunpy_dev/extern/sunkit_instruments/lasco/utils.py +0 -0
- {pythea-0.11.0 → pythea-0.12.0}/PyThea/sunpy_dev/extern/sunkit_instruments/stereo/__init__.py +0 -0
- {pythea-0.11.0 → pythea-0.12.0}/PyThea/sunpy_dev/extern/sunkit_instruments/stereo/utils.py +0 -0
- {pythea-0.11.0 → pythea-0.12.0}/PyThea/sunpy_dev/map/__init__.py +0 -0
- {pythea-0.11.0 → pythea-0.12.0}/PyThea/test/Pythea_test.py +0 -0
- {pythea-0.11.0 → pythea-0.12.0}/PyThea/test/__init__.py +0 -0
- {pythea-0.11.0 → pythea-0.12.0}/PyThea/test/conftest.py +0 -0
- {pythea-0.11.0 → pythea-0.12.0}/PyThea/test/test_geometrical_models.py +0 -0
- {pythea-0.11.0 → pythea-0.12.0}/PyThea/test/test_imports.py +0 -0
- {pythea-0.11.0 → pythea-0.12.0}/PyThea/test/test_utils.py +0 -0
- {pythea-0.11.0 → pythea-0.12.0}/PyThea/version.py +0 -0
- {pythea-0.11.0 → pythea-0.12.0}/PyThea.egg-info/.DS_Store +0 -0
- {pythea-0.11.0 → pythea-0.12.0}/PyThea.egg-info/dependency_links.txt +0 -0
- {pythea-0.11.0 → pythea-0.12.0}/PyThea.egg-info/entry_points.txt +0 -0
- {pythea-0.11.0 → pythea-0.12.0}/PyThea.egg-info/not-zip-safe +0 -0
- {pythea-0.11.0 → pythea-0.12.0}/PyThea.egg-info/top_level.txt +0 -0
- {pythea-0.11.0 → pythea-0.12.0}/pyproject.toml +0 -0
- {pythea-0.11.0 → pythea-0.12.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,29 @@
|
|
|
1
|
-
# v0.
|
|
1
|
+
# v0.12.0 (09-Jun-2024)
|
|
2
|
+
|
|
3
|
+
## Features
|
|
4
|
+
- Adds more imaging data from SDO/AIA.
|
|
5
|
+
- Adds acceleration calculation in the kinematic plots.
|
|
6
|
+
- Implements acceleration plotting in the app.
|
|
7
|
+
- Includes fits file name in fitting files and dataframes.
|
|
8
|
+
- Highlights a row in the fitting table when fitting exist in table.
|
|
9
|
+
|
|
10
|
+
## Major Changes
|
|
11
|
+
- Decouples the loading of fits files from download_fits function.
|
|
12
|
+
|
|
13
|
+
## Minor Changes
|
|
14
|
+
- Improves configuration dictionary for selected imagers.
|
|
15
|
+
- Improves json warning message in the main app page.
|
|
16
|
+
- Adds documentation page link to the main app page.
|
|
17
|
+
- Updates README files.
|
|
18
|
+
- Improves plot_fitting_model and adds figure test.
|
|
19
|
+
- Improves application layout.
|
|
20
|
+
|
|
21
|
+
## Bug Fixes
|
|
22
|
+
- Fixes a potential bug in filter_maps when no filtering is applied.
|
|
23
|
+
- Fixes a bug with progress bar with stqdm.
|
|
24
|
+
- Fixes a bug with image processing mode selection.
|
|
25
|
+
|
|
26
|
+
# v0.11.0 (19-May-2024)
|
|
2
27
|
|
|
3
28
|
## Features
|
|
4
29
|
- 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.12.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
|
|
@@ -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,23 @@ 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 have been added.
|
|
86
|
+
''', icon='ℹ️')
|
|
74
87
|
st.warning('''
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
''')
|
|
88
|
+
**NOTE: From PyThea >0.8.1 the JSON fitting files will be slightly different from the old ones.**
|
|
89
|
+
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)).
|
|
90
|
+
''', icon='⚠️')
|
|
78
91
|
st.markdown('---')
|
|
79
92
|
|
|
80
93
|
|
|
@@ -86,7 +99,10 @@ def run():
|
|
|
86
99
|
#############################################################
|
|
87
100
|
# set page config
|
|
88
101
|
st.set_page_config(page_title='PyThea', page_icon=':rocket:',
|
|
89
|
-
initial_sidebar_state='expanded'
|
|
102
|
+
initial_sidebar_state='expanded',
|
|
103
|
+
menu_items={
|
|
104
|
+
'Get Help': 'https://www.pythea.org/',
|
|
105
|
+
'Report a Bug': 'https://github.com/AthKouloumvakos/PyThea'})
|
|
90
106
|
|
|
91
107
|
#############################################################
|
|
92
108
|
# HTML Styles
|
|
@@ -94,7 +110,7 @@ def run():
|
|
|
94
110
|
|
|
95
111
|
#############################################################
|
|
96
112
|
# Main page information text
|
|
97
|
-
st.
|
|
113
|
+
st.header('PyThea: Reconstruct CMEs & Shocks')
|
|
98
114
|
|
|
99
115
|
#############################################################
|
|
100
116
|
# Startup Variables
|
|
@@ -106,7 +122,6 @@ def run():
|
|
|
106
122
|
|
|
107
123
|
if 'date_process' not in st.session_state:
|
|
108
124
|
date_and_event_selection(st)
|
|
109
|
-
st.markdown(""" #### ⏻ Select a day & solar event. """)
|
|
110
125
|
else:
|
|
111
126
|
st.sidebar.markdown('## Processing Event|Date:')
|
|
112
127
|
st.sidebar.info(f'{st.session_state.event_selected}')
|
|
@@ -194,7 +209,8 @@ def run():
|
|
|
194
209
|
on_change=delete_from_state,
|
|
195
210
|
kwargs={'vars': ['map', 'imagers_list_', 'clim', 'clim_manual_low', 'clim_manual_high']})
|
|
196
211
|
if image_mode in ['Running Diff.', 'Base Diff.']:
|
|
197
|
-
|
|
212
|
+
min_diff = 1 if image_mode == 'Running Diff.' else 0
|
|
213
|
+
diff_value = procoption_container.number_input('Select Step/Image for Running/Base Diff.', min_diff, 5, key='diff_value',
|
|
198
214
|
on_change=delete_from_state,
|
|
199
215
|
kwargs={'vars': ['map', 'imagers_list_', 'clim', 'clim_manual_low', 'clim_manual_high']})
|
|
200
216
|
else:
|
|
@@ -245,15 +261,16 @@ def run():
|
|
|
245
261
|
st.session_state.map_ = {} if 'map_' not in st.session_state else st.session_state.map_
|
|
246
262
|
st.session_state.map = {} if 'map' not in st.session_state else st.session_state.map
|
|
247
263
|
st.session_state['imagers_list_'] = imagers_list
|
|
248
|
-
progress_bar =
|
|
249
|
-
for imager in
|
|
250
|
-
progress_bar.
|
|
264
|
+
progress_bar = st.progress(0, text='Preparing to Download data')
|
|
265
|
+
for i, imager in enumerate(imager_added):
|
|
266
|
+
progress_bar.progress(i/len(imager_added), text=f'Download {imager} images from VSO')
|
|
251
267
|
if imager not in st.session_state.map_:
|
|
252
268
|
timerange = a.Time(st.session_state.date_process + datetime.timedelta(hours=imaging_time_range[0]),
|
|
253
269
|
st.session_state.date_process + datetime.timedelta(hours=imaging_time_range[1]))
|
|
254
|
-
|
|
270
|
+
downloaded_files = download_fits(timerange, imager)
|
|
271
|
+
st.session_state.map_[imager] = load_fits(downloaded_files)
|
|
255
272
|
st.session_state.map_[imager] = single_imager_maps_process(st.session_state.map_[imager],
|
|
256
|
-
**selected_imagers.imager_dict[imager][
|
|
273
|
+
**selected_imagers.imager_dict[imager]['process'],
|
|
257
274
|
skip='sequence_processing')
|
|
258
275
|
processed_images = single_imager_maps_process(st.session_state.map_[imager],
|
|
259
276
|
skip=['filter', 'prepare'],
|
|
@@ -265,6 +282,7 @@ def run():
|
|
|
265
282
|
else:
|
|
266
283
|
st.session_state.imagers_list_.remove(imager)
|
|
267
284
|
st.session_state.map_colormap_limits.pop(imager, None)
|
|
285
|
+
progress_bar.empty()
|
|
268
286
|
|
|
269
287
|
if imager_removed != []:
|
|
270
288
|
st.session_state['imagers_list_'] = imagers_list
|
|
@@ -374,6 +392,7 @@ def run():
|
|
|
374
392
|
# Store the fitting
|
|
375
393
|
single_fit = model.to_dataframe()
|
|
376
394
|
single_fit['imager'] = imager_select
|
|
395
|
+
single_fit['fits_file'] = running_map.meta['fits_file']
|
|
377
396
|
|
|
378
397
|
if store_fit_button_pressed:
|
|
379
398
|
if 'model_fittings' not in st.session_state:
|
|
@@ -390,10 +409,13 @@ def run():
|
|
|
390
409
|
st.markdown('---')
|
|
391
410
|
st.markdown('### Parameters Table')
|
|
392
411
|
st.markdown('**Running Fitting Table:**')
|
|
393
|
-
|
|
412
|
+
col_formats = {col: '{:,.2f}'.format for col in single_fit.select_dtypes(include='number').columns}
|
|
413
|
+
st.dataframe(single_fit.style.format(col_formats))
|
|
394
414
|
if 'model_fittings' in st.session_state:
|
|
395
415
|
st.markdown('**Stored Fitting Table:**')
|
|
396
|
-
st.dataframe(st.session_state.model_fittings.parameters
|
|
416
|
+
st.dataframe(st.session_state.model_fittings.parameters.style.apply(highlight_row,
|
|
417
|
+
row_index=single_fit.index, axis=1).format(col_formats)
|
|
418
|
+
)
|
|
397
419
|
col1, col2 = st.columns((2, 2))
|
|
398
420
|
col2.selectbox('Select a fitting',
|
|
399
421
|
options=st.session_state.model_fittings.parameters.index,
|
|
@@ -413,7 +435,7 @@ def run():
|
|
|
413
435
|
st.markdown('### Plots of kinematics ')
|
|
414
436
|
col1, col2, col3 = st.columns(3)
|
|
415
437
|
plt_kinematics_select = col1.selectbox('Select Plots',
|
|
416
|
-
options=['All', 'HeightT', 'SpeedT', 'Long-LatT'])
|
|
438
|
+
options=['All', 'HeightT', 'SpeedT', 'AccelerationT', 'Long-LatT'])
|
|
417
439
|
|
|
418
440
|
fit_mode = col2.selectbox('Select Fitting Mode',
|
|
419
441
|
options=['polynomial', 'spline', 'custom'],
|
|
@@ -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,65 @@
|
|
|
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'}
|
|
@@ -30,6 +30,6 @@ json_fitting_file_sample_data = pooch.create(
|
|
|
30
30
|
path=os.path.join(database_dir, 'sample_data'), # The cache folder
|
|
31
31
|
base_url=f'{github_main_url}/raw/main/data/', # The remote data url on Github
|
|
32
32
|
registry={
|
|
33
|
-
'FLX1p0D20211028T153500MEllipsoid.json': 'sha256:
|
|
33
|
+
'FLX1p0D20211028T153500MEllipsoid.json': 'sha256:34fced8530875110117ba27a73541d3acd0c90bc8fca99367c1ec4cdfc05ce86',
|
|
34
34
|
},
|
|
35
35
|
)
|
|
@@ -8,6 +8,7 @@ import warnings
|
|
|
8
8
|
import astropy.units as u
|
|
9
9
|
import numpy as np
|
|
10
10
|
import sunpy.map
|
|
11
|
+
from sunpy.map.mapsequence import MapSequence
|
|
11
12
|
|
|
12
13
|
import PyThea.sunpy_dev.extern.sunkit_instruments.aia.utils # noqa
|
|
13
14
|
import PyThea.sunpy_dev.extern.sunkit_instruments.lasco.utils # noqa
|
|
@@ -47,7 +48,7 @@ def maps_sequence_processing(map_sequence, **kwargs):
|
|
|
47
48
|
|
|
48
49
|
smap = []
|
|
49
50
|
if seq_type == 'Running Diff.':
|
|
50
|
-
for i in range(
|
|
51
|
+
for i in range(diff_num, len(map_sequence)):
|
|
51
52
|
smap_diff = difference_maps(map_sequence[i], map_sequence[i-diff_num])
|
|
52
53
|
smap.append(smap_diff)
|
|
53
54
|
if seq_type == 'Base Diff.':
|
|
@@ -151,7 +152,11 @@ def filter_maps(map_sequence, **kwargs):
|
|
|
151
152
|
map_sequence = [tmap for tmap in map_sequence if tmap.meta['polar'] == kwargs['polar']]
|
|
152
153
|
|
|
153
154
|
if len(map_sequence) != 0:
|
|
154
|
-
|
|
155
|
+
if isinstance(map_sequence, MapSequence):
|
|
156
|
+
return map_sequence
|
|
157
|
+
else:
|
|
158
|
+
sequence_final = sunpy.map.Map(map_sequence, sequence=True)
|
|
159
|
+
|
|
155
160
|
else:
|
|
156
161
|
sequence_final = []
|
|
157
162
|
|
|
@@ -2,5 +2,6 @@
|
|
|
2
2
|
"PyThea.test.test_figures.test_ellipsoid_on_AIA_venus": "f1ff774b483a8c934c9353c552278c8823216fc7d9dad4ccc00c74be3f30c4c3",
|
|
3
3
|
"PyThea.test.test_figures.test_ellipsoid_on_AIA_mercury": "f6afda1c769a061b7ab1fc64c4e9c0f4658cdb97c3be83828ba5d98bf1bb182c",
|
|
4
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"
|
|
5
|
+
"PyThea.test.test_figures.test_ellipsoid_on_STEREO_COR2_three_planets": "231d5635f57c4d66556674a83f6cbcef7dc94b51846e977c4c2dc3dc244096ac",
|
|
6
|
+
"PyThea.test.test_figures.test_kinematics_figure": "83e060de53b57e9d34fe50111ba60a44f7c7c7b20faae9a4381654ef1c9ea72d"
|
|
6
7
|
}
|
|
@@ -5,9 +5,12 @@ import sunpy.map
|
|
|
5
5
|
from astropy.coordinates import SkyCoord, solar_system_ephemeris
|
|
6
6
|
from sunpy.coordinates import get_body_heliographic_stonyhurst
|
|
7
7
|
|
|
8
|
-
from PyThea.data.sample_data import aia_sample_data,
|
|
8
|
+
from PyThea.data.sample_data import (aia_sample_data,
|
|
9
|
+
json_fitting_file_sample_data,
|
|
10
|
+
stereo_sample_data)
|
|
9
11
|
from PyThea.geometrical_models import ellipsoid
|
|
10
12
|
from PyThea.sunpy_dev.map.maputils import prepare_maps
|
|
13
|
+
from PyThea.utils import model_fittings, plot_fitting_model
|
|
11
14
|
|
|
12
15
|
solar_system_ephemeris.set('de432s')
|
|
13
16
|
|
|
@@ -167,3 +170,27 @@ def test_ellipsoid_on_STEREO_COR2_three_planets():
|
|
|
167
170
|
fig.subplots_adjust(hspace=0.5, wspace=0.35)
|
|
168
171
|
|
|
169
172
|
return fig
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
@pytest.mark.mpl_image_compare()
|
|
176
|
+
def test_kinematics_figure():
|
|
177
|
+
json_fitting_file = json_fitting_file_sample_data.fetch('FLX1p0D20211028T153500MEllipsoid.json')
|
|
178
|
+
model_fittings_class = model_fittings.load_from_json(json_fitting_file)
|
|
179
|
+
|
|
180
|
+
fit_method = {'type': 'polynomial', 'order': 2}
|
|
181
|
+
|
|
182
|
+
fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(18, 5), tight_layout=True)
|
|
183
|
+
|
|
184
|
+
fig, ax1 = plot_fitting_model(model_fittings_class,
|
|
185
|
+
fit_args=fit_method,
|
|
186
|
+
plt_type='HeightT',
|
|
187
|
+
fig=fig, axis=ax1)
|
|
188
|
+
fig, ax2 = plot_fitting_model(model_fittings_class,
|
|
189
|
+
fit_args=fit_method,
|
|
190
|
+
plt_type='SpeedT',
|
|
191
|
+
fig=fig, axis=ax2)
|
|
192
|
+
fig, ax3 = plot_fitting_model(model_fittings_class,
|
|
193
|
+
fit_args=fit_method,
|
|
194
|
+
plt_type='AccelerationT',
|
|
195
|
+
fig=fig, axis=ax3)
|
|
196
|
+
return fig
|
|
@@ -68,7 +68,7 @@ def test_vso_search(imager):
|
|
|
68
68
|
"""
|
|
69
69
|
Tests that the Fido.search returns always the same number of files from VSO.
|
|
70
70
|
"""
|
|
71
|
-
file_num = {'AIA': [60, 61],
|
|
71
|
+
file_num = {'AIA-193': [60, 61], 'AIA-211': [60, 61],
|
|
72
72
|
'LC2': [5], 'LC3': [5],
|
|
73
73
|
'COR2A': [7], 'COR2B': [7],
|
|
74
74
|
'EUVIA': [11], 'EUVIB': [11],
|
|
@@ -79,7 +79,7 @@ def test_vso_search(imager):
|
|
|
79
79
|
for query in [a.Time('2011/01/01 00:00:00', '2011/01/01 01:00:00'),
|
|
80
80
|
a.Time('2012/01/01 00:00:00', '2012/01/01 01:00:00'),
|
|
81
81
|
a.Time('2013/01/01 00:00:00', '2013/01/01 01:00:00'), ]:
|
|
82
|
-
args = imager_dict[imager][
|
|
82
|
+
args = imager_dict[imager]['fido']
|
|
83
83
|
result = Fido.search(query, *args)
|
|
84
84
|
|
|
85
85
|
assert len(result) == 1
|
|
@@ -174,15 +174,32 @@ def download_fits(timerange, imager):
|
|
|
174
174
|
'''
|
|
175
175
|
Downloads the imaging data (fits files) from VSO
|
|
176
176
|
'''
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
result = Fido.search(timerange, *args)
|
|
177
|
+
imager_prop = imager_dict[imager]
|
|
178
|
+
result = Fido.search(timerange, *imager_prop['fido'])
|
|
180
179
|
print(result)
|
|
181
180
|
if result:
|
|
182
|
-
|
|
183
|
-
|
|
181
|
+
if 'detector' in imager_prop:
|
|
182
|
+
sub_path = imager_prop['detector']
|
|
183
|
+
elif 'wavelength' in imager_prop:
|
|
184
|
+
sub_path = imager_prop['wavelength']
|
|
185
|
+
path_str = f'{database_dir}/data/{imager_prop["source"]}/{imager_prop["instrument"]}/{sub_path}'+'/{file}'
|
|
186
|
+
downloaded_files = Fido.fetch(result, path=path_str)
|
|
187
|
+
else:
|
|
188
|
+
downloaded_files = []
|
|
189
|
+
|
|
190
|
+
return downloaded_files
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def load_fits(files):
|
|
194
|
+
'''
|
|
195
|
+
Loads the imaging data (fits files) from a list of files.
|
|
196
|
+
'''
|
|
197
|
+
maps_ = []
|
|
198
|
+
if files:
|
|
199
|
+
for file_path in files:
|
|
184
200
|
try:
|
|
185
201
|
map_ = sunpy.map.Map(file_path)
|
|
202
|
+
map_.meta['fits_file'] = os.path.basename(file_path)
|
|
186
203
|
maps_.append(map_)
|
|
187
204
|
except RuntimeError as err:
|
|
188
205
|
print('Handling RuntimeError error:', err)
|
|
@@ -192,7 +209,6 @@ def download_fits(timerange, imager):
|
|
|
192
209
|
print(f"File '{file_path}' has been removed.")
|
|
193
210
|
if maps_:
|
|
194
211
|
maps_ = sunpy.map.Map(maps_, sequence=True)
|
|
195
|
-
|
|
196
212
|
return maps_
|
|
197
213
|
|
|
198
214
|
|
|
@@ -210,7 +226,7 @@ def maps_process(maps_dict_in, imagers_list_in, image_mode, **kwargs):
|
|
|
210
226
|
for imager in imagers_list_in:
|
|
211
227
|
if imager in maps_dict_in and maps_dict_in[imager] != []:
|
|
212
228
|
if not kwargs:
|
|
213
|
-
extras = imager_dict[imager][
|
|
229
|
+
extras = imager_dict[imager]['process']
|
|
214
230
|
else:
|
|
215
231
|
if imager in kwargs:
|
|
216
232
|
extras = kwargs[imager]
|
|
@@ -277,6 +293,14 @@ class model_fittings:
|
|
|
277
293
|
the old file with the new one. This will not alter your fittings.')
|
|
278
294
|
kinematics = {'fit_method': {'type': 'polynomial', 'order': 1}}
|
|
279
295
|
|
|
296
|
+
if fitting['version'] <= '0.11.0':
|
|
297
|
+
# In version >0.11.0 more AIA channels added so this will update the fitting files
|
|
298
|
+
# prodused at earlier versions by replasing the imager values from "AIA" to "AIA-193".
|
|
299
|
+
parameters['imager'] = parameters['imager'].replace('AIA', 'AIA-193')
|
|
300
|
+
# In version >0.11.0 the fits file name is added to the single fits
|
|
301
|
+
if 'fits_file' not in parameters.columns:
|
|
302
|
+
parameters['fits_file'] = ''
|
|
303
|
+
|
|
280
304
|
model_fittings_class = model_fittings(fitting['event_selected'],
|
|
281
305
|
fitting['date_process'],
|
|
282
306
|
fitting['geometrical_model']['type'],
|
|
@@ -315,11 +339,15 @@ class model_fittings:
|
|
|
315
339
|
return json.dumps(model_dict, indent=' ')
|
|
316
340
|
|
|
317
341
|
|
|
318
|
-
def plot_fitting_model(model, fit_args, plt_type='HeightT'):
|
|
342
|
+
def plot_fitting_model(model, fit_args, plt_type='HeightT', fig=None, axis=None):
|
|
319
343
|
'''
|
|
320
344
|
Plot the height(speed)--time evolution of the fitting parameters.
|
|
321
345
|
'''
|
|
322
346
|
palete = sns.color_palette('deep')
|
|
347
|
+
|
|
348
|
+
Rs2km = (1 * u.R_sun).to_value(u.km)
|
|
349
|
+
sec = 24*60*60
|
|
350
|
+
|
|
323
351
|
parameters = {
|
|
324
352
|
'Spheroid':
|
|
325
353
|
{'height': ['+', '', palete[3], 'h-apex'],
|
|
@@ -335,9 +363,14 @@ def plot_fitting_model(model, fit_args, plt_type='HeightT'):
|
|
|
335
363
|
'rapex': ['x', '', palete[0], 'r-apex'],
|
|
336
364
|
},
|
|
337
365
|
}
|
|
366
|
+
|
|
338
367
|
parameters = parameters[model.geometrical_model]
|
|
339
|
-
|
|
340
|
-
fig
|
|
368
|
+
|
|
369
|
+
if fig is None and axis is None:
|
|
370
|
+
fig, axis = plt.subplots(figsize=(5.5, 5.5), tight_layout=True)
|
|
371
|
+
else:
|
|
372
|
+
fig, axis = fig, axis
|
|
373
|
+
|
|
341
374
|
if plt_type == 'HeightT':
|
|
342
375
|
for p in parameters.keys():
|
|
343
376
|
axis.plot(model.parameters.index,
|
|
@@ -345,7 +378,7 @@ def plot_fitting_model(model, fit_args, plt_type='HeightT'):
|
|
|
345
378
|
marker=parameters[p][0],
|
|
346
379
|
linestyle=parameters[p][1],
|
|
347
380
|
color=parameters[p][2],
|
|
348
|
-
label=parameters[p][3])
|
|
381
|
+
label=parameters[p][3])
|
|
349
382
|
if len(model.parameters[p])-1 > fit_args['order']:
|
|
350
383
|
# How to get confidence intervals from curve_fit?
|
|
351
384
|
fit = parameter_fit(model.parameters.index, model.parameters[p], fit_args)
|
|
@@ -359,26 +392,45 @@ def plot_fitting_model(model, fit_args, plt_type='HeightT'):
|
|
|
359
392
|
axis.plot(model.parameters.index, model.parameters[p], '--', color=parameters[p][2])
|
|
360
393
|
ylabel = 'Height of apex and length of flanks [Rsun]'
|
|
361
394
|
axis.set_ylim(bottom=0)
|
|
362
|
-
elif plt_type
|
|
395
|
+
elif plt_type in ('SpeedT', 'AccelerationT'):
|
|
396
|
+
gradient_power = {'SpeedT': 1, 'AccelerationT': 2}
|
|
397
|
+
const = {'SpeedT': Rs2km/sec, 'AccelerationT': Rs2km/sec**2}
|
|
363
398
|
for p in parameters.keys():
|
|
364
|
-
if len(model.parameters[p])-
|
|
399
|
+
if len(model.parameters[p])-gradient_power[plt_type] > fit_args['order']:
|
|
365
400
|
# How to get confidence intervals from curve_fit?
|
|
366
401
|
fit = parameter_fit(model.parameters.index, model.parameters[p], fit_args)
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
402
|
+
if plt_type == 'SpeedT':
|
|
403
|
+
best_fit = const[plt_type] * np.gradient(fit['best_fit_y'], fit['best_fit_x_num'])
|
|
404
|
+
upper_bound = const[plt_type] * np.gradient(fit['sigma_bounds']['up'], fit['best_fit_x_num'])
|
|
405
|
+
lower_bound = const[plt_type] * np.gradient(fit['sigma_bounds']['low'], fit['best_fit_x_num'])
|
|
406
|
+
if fit_args['type'] == 'spline':
|
|
407
|
+
axis.fill_between(fit['best_fit_x'], const[plt_type] * fit['sigv_bounds']['dlow'], const[plt_type] * fit['sigv_bounds']['dup'],
|
|
408
|
+
color=parameters[p][2], alpha=0.05)
|
|
409
|
+
ylabel = 'Speed [km/s]'
|
|
410
|
+
elif plt_type == 'AccelerationT':
|
|
411
|
+
best_fit = const[plt_type] * np.gradient(np.gradient(fit['best_fit_y'], fit['best_fit_x_num'], edge_order=2), fit['best_fit_x_num'], edge_order=2)
|
|
412
|
+
upper_bound = const[plt_type] * np.gradient(np.gradient(fit['sigma_bounds']['up'], fit['best_fit_x_num'], edge_order=2), fit['best_fit_x_num'], edge_order=2)
|
|
413
|
+
lower_bound = const[plt_type] * np.gradient(np.gradient(fit['sigma_bounds']['low'], fit['best_fit_x_num'], edge_order=2), fit['best_fit_x_num'], edge_order=2)
|
|
414
|
+
if fit_args['type'] == 'spline':
|
|
415
|
+
axis.fill_between(fit['best_fit_x'], const[plt_type] * fit['sigv_bounds']['ddlow'], const[plt_type] * fit['sigv_bounds']['ddup'],
|
|
416
|
+
color=parameters[p][2], alpha=0.05)
|
|
417
|
+
ylabel = 'Acceleration [km/s$^2$]'
|
|
418
|
+
|
|
419
|
+
axis.plot(fit['best_fit_x'], best_fit, '-', color=parameters[p][2], label=parameters[p][3])
|
|
420
|
+
axis.fill_between(fit['best_fit_x'], lower_bound, upper_bound,
|
|
374
421
|
color=parameters[p][2], alpha=0.20)
|
|
375
|
-
|
|
376
|
-
axis.fill_between(fit['best_fit_x'], (Rs2km/sec) * fit['sigv_bounds']['dlow'], (Rs2km/sec) * fit['sigv_bounds']['dup'],
|
|
377
|
-
color=parameters[p][2], alpha=0.05)
|
|
422
|
+
|
|
378
423
|
else:
|
|
379
|
-
|
|
380
|
-
|
|
424
|
+
ylabel = ' '
|
|
425
|
+
axis.text(0.5, 0.5, f'Not enough points for \n fitting with order {fit_args["order"]}.',
|
|
426
|
+
transform=axis.transAxes,
|
|
427
|
+
fontsize=20, color='gray', alpha=0.5,
|
|
428
|
+
ha='center', va='center', rotation=30)
|
|
429
|
+
break
|
|
430
|
+
|
|
431
|
+
if plt_type != 'AccelerationT':
|
|
381
432
|
axis.set_ylim(bottom=0)
|
|
433
|
+
|
|
382
434
|
if plt_type == 'LongT' or plt_type == 'LatT':
|
|
383
435
|
parameters = {'LongT': ['hgln', '+', palete[3], 'Longitude'],
|
|
384
436
|
'LatT': ['hglt', '+', palete[2], 'Latitude']}
|
|
@@ -411,8 +463,16 @@ def plot_fitting_model(model, fit_args, plt_type='HeightT'):
|
|
|
411
463
|
axis.xaxis.set_major_formatter(formatter)
|
|
412
464
|
axis.minorticks_on()
|
|
413
465
|
xlim = axis.get_xlim()
|
|
414
|
-
|
|
415
|
-
|
|
466
|
+
|
|
467
|
+
hour_threshold = 24 * (xlim[1] - xlim[0])
|
|
468
|
+
|
|
469
|
+
if hour_threshold <= 2:
|
|
470
|
+
axis.xaxis.set_minor_locator(mdates.MinuteLocator(byminute=np.arange(0, 61, 1)))
|
|
471
|
+
elif hour_threshold <= 6:
|
|
472
|
+
axis.xaxis.set_minor_locator(mdates.MinuteLocator(byminute=np.arange(0, 61, 5)))
|
|
473
|
+
else:
|
|
474
|
+
axis.xaxis.set_minor_locator(mdates.HourLocator(byhour=np.arange(0, 25, 1)))
|
|
475
|
+
|
|
416
476
|
fig.autofmt_xdate(bottom=0, rotation=0, ha='center')
|
|
417
477
|
axis.legend(loc='lower right')
|
|
418
478
|
|
|
@@ -453,13 +513,17 @@ def parameter_fit(x, y, fit_args):
|
|
|
453
513
|
sigma_bound_up = best_fit + sigma
|
|
454
514
|
sigma_bound_low = best_fit - sigma
|
|
455
515
|
|
|
456
|
-
sv_bound_up, sv_bound_low, sv_bound_dup, sv_bound_dlow
|
|
516
|
+
sv_bound_up, sv_bound_low, sv_bound_dup, sv_bound_dlow, sv_bound_ddup, sv_bound_ddlow = \
|
|
517
|
+
best_fit, best_fit, np.gradient(best_fit, xxx), np.gradient(best_fit, xxx), \
|
|
518
|
+
np.gradient(np.gradient(best_fit, xxx)), np.gradient(np.gradient(best_fit, xxx))
|
|
457
519
|
for i in range(2, 100):
|
|
458
520
|
spl = UnivariateSpline(xx, y, s=i/100, k=fit_args['order'])
|
|
459
521
|
sv_bound_up = np.maximum(sv_bound_up, spl(xxx))
|
|
460
522
|
sv_bound_low = np.minimum(sv_bound_low, spl(xxx))
|
|
461
523
|
sv_bound_dup = np.maximum(sv_bound_dup, np.gradient(spl(xxx), xxx))
|
|
462
524
|
sv_bound_dlow = np.minimum(sv_bound_dlow, np.gradient(spl(xxx), xxx))
|
|
525
|
+
sv_bound_ddup = np.maximum(sv_bound_ddup, np.gradient(np.gradient(spl(xxx), xxx)))
|
|
526
|
+
sv_bound_ddlow = np.minimum(sv_bound_ddlow, np.gradient(np.gradient(spl(xxx), xxx)))
|
|
463
527
|
|
|
464
528
|
fitting = {'spl': spl,
|
|
465
529
|
'sigma': sigma,
|
|
@@ -471,7 +535,9 @@ def parameter_fit(x, y, fit_args):
|
|
|
471
535
|
'sigv_bounds': {'up': sv_bound_up,
|
|
472
536
|
'low': sv_bound_low,
|
|
473
537
|
'dup': sv_bound_dup,
|
|
474
|
-
'dlow': sv_bound_dlow
|
|
538
|
+
'dlow': sv_bound_dlow,
|
|
539
|
+
'ddup': sv_bound_ddup,
|
|
540
|
+
'ddlow': sv_bound_ddlow},
|
|
475
541
|
}
|
|
476
542
|
elif fit_args['type'] == 'custom':
|
|
477
543
|
expression = fit_args['expression'] # 'a * exp(-b * x) + c'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: PyThea
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.12.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
|
|
@@ -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
|
|
|
@@ -22,8 +22,8 @@ We recommend, creating a virtual environment for _PyThea_ and installing the pac
|
|
|
22
22
|
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:
|
|
23
23
|
|
|
24
24
|
```python
|
|
25
|
-
# Create a virtual environment. Use python
|
|
26
|
-
conda create --name PyThea python=3.
|
|
25
|
+
# Create a virtual environment. Use python>3.9
|
|
26
|
+
conda create --name PyThea python=3.10
|
|
27
27
|
|
|
28
28
|
# Activate the environment
|
|
29
29
|
conda activate PyThea
|
|
@@ -97,7 +97,7 @@ If there is an error when running ```PyThea streamlit``` then you can manually r
|
|
|
97
97
|
|
|
98
98
|
## 📙 Usage
|
|
99
99
|
|
|
100
|
-
Complete documentation of the _PyThea_ can be found in (
|
|
100
|
+
Complete documentation of the _PyThea_ can be found in [https://www.pythea.org/](https://www.pythea.org/).
|
|
101
101
|
|
|
102
102
|
## 📦 Useful Python packages
|
|
103
103
|
|
|
@@ -16,8 +16,8 @@ We recommend, creating a virtual environment for _PyThea_ and installing the pac
|
|
|
16
16
|
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:
|
|
17
17
|
|
|
18
18
|
```python
|
|
19
|
-
# Create a virtual environment. Use python
|
|
20
|
-
conda create --name PyThea python=3.
|
|
19
|
+
# Create a virtual environment. Use python>3.9
|
|
20
|
+
conda create --name PyThea python=3.10
|
|
21
21
|
|
|
22
22
|
# Activate the environment
|
|
23
23
|
conda activate PyThea
|
|
@@ -91,7 +91,7 @@ If there is an error when running ```PyThea streamlit``` then you can manually r
|
|
|
91
91
|
|
|
92
92
|
## 📙 Usage
|
|
93
93
|
|
|
94
|
-
Complete documentation of the _PyThea_
|
|
94
|
+
Complete documentation of the _PyThea_ can be found in [https://www.pythea.org/](https://www.pythea.org/).
|
|
95
95
|
|
|
96
96
|
## 📦 Useful Python packages
|
|
97
97
|
|
|
@@ -1,34 +0,0 @@
|
|
|
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 = dict.fromkeys(['LC2'], [(a.Instrument.lasco, a.Detector.c2),
|
|
10
|
-
{'dimensions': (1024*u.pixel, 1024*u.pixel), 'polar': 'Clear', 'superpixel': 2}, 'LASCO-C2'])
|
|
11
|
-
imager_dict.update(dict.fromkeys(['LC3'], [(a.Instrument.lasco, a.Detector.c3),
|
|
12
|
-
{'dimensions': (1024*u.pixel, 1024*u.pixel), 'polar': 'Clear', 'superpixel': 2}, 'LASCO-C3']))
|
|
13
|
-
imager_dict.update(dict.fromkeys(['AIA'], [(a.Instrument.aia, a.Wavelength(19.3 * u.nm), a.Sample(1*u.minute)),
|
|
14
|
-
{'dimensions': (4096*u.pixel, 4096*u.pixel), 'superpixel': 8, 'exposure': 1.90}, 'SDO-AIA']))
|
|
15
|
-
imager_dict.update(dict.fromkeys(['COR2A'], [(a.Source('STEREO_A'), a.Detector.cor2),
|
|
16
|
-
{'dimensions': (2048*u.pixel, 2048*u.pixel), 'polar': 1001, 'superpixel': 4}, 'STA-COR2']))
|
|
17
|
-
imager_dict.update(dict.fromkeys(['COR2B'], [(a.Source('STEREO_B'), a.Detector.cor2),
|
|
18
|
-
{'dimensions': (2048*u.pixel, 2048*u.pixel), 'polar': 1001, 'superpixel': 4}, 'STB-COR2']))
|
|
19
|
-
imager_dict.update(dict.fromkeys(['EUVIA'], [(a.Source('STEREO_A'), a.Detector.euvi, a.Wavelength(19.5 * u.nm)),
|
|
20
|
-
{'dimensions': (2048*u.pixel, 2048*u.pixel), 'superpixel': 4}, 'STA-EUVI']))
|
|
21
|
-
imager_dict.update(dict.fromkeys(['EUVIB'], [(a.Source('STEREO_B'), a.Detector.euvi, a.Wavelength(19.5 * u.nm)),
|
|
22
|
-
{'dimensions': (2048*u.pixel, 2048*u.pixel), 'superpixel': 4}, 'STB-EUVI']))
|
|
23
|
-
imager_dict.update(dict.fromkeys(['COR1A'], [(a.Source('STEREO_A'), a.Detector.cor1),
|
|
24
|
-
{'dimensions': (512*u.pixel, 512*u.pixel)}, 'STA-COR1'])) # 'polar':0
|
|
25
|
-
imager_dict.update(dict.fromkeys(['COR1B'], [(a.Source('STEREO_B'), a.Detector.cor1),
|
|
26
|
-
{'dimensions': (512*u.pixel, 512*u.pixel)}, 'STB-COR1'])) # 'polar':0
|
|
27
|
-
imager_dict.update(dict.fromkeys(['HI1A'], [(a.Source('STEREO_A'), a.Detector.hi1),
|
|
28
|
-
{'dimensions': (1024*u.pixel, 1024*u.pixel), 'superpixel': 2}, 'STA-HI1']))
|
|
29
|
-
imager_dict.update(dict.fromkeys(['HI1B'], [(a.Source('STEREO_B'), a.Detector.hi1),
|
|
30
|
-
{'dimensions': (1024*u.pixel, 1024*u.pixel), 'superpixel': 2}, 'STB-HI1']))
|
|
31
|
-
imager_dict.update(dict.fromkeys(['HI2A'], [(a.Source('STEREO_A'), a.Detector.hi2),
|
|
32
|
-
{'dimensions': (1024*u.pixel, 1024*u.pixel), 'superpixel': 2}, 'STA-HI2']))
|
|
33
|
-
imager_dict.update(dict.fromkeys(['HI2B'], [(a.Source('STEREO_B'), a.Detector.hi2),
|
|
34
|
-
{'dimensions': (1024*u.pixel, 1024*u.pixel)}, 'STB-HI2']))
|
|
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.11.0 → pythea-0.12.0}/PyThea/sunpy_dev/extern/sunkit_instruments/lasco/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{pythea-0.11.0 → pythea-0.12.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
|