Spaces:
Runtime error
Runtime error
File size: 10,632 Bytes
5e3a6e4 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
import datetime
import io
from hydralit import HydraHeadApp
import astropy.units as u
import pandas as pd
import streamlit as st
from astropy.coordinates import SkyCoord
from sunpy.coordinates import frames
from apps.extras.backmapping import *
import hydralit_components as hc
class SolarMach(HydraHeadApp):
def __init__(self, title = '', **kwargs):
self.__dict__.update(kwargs)
self.title = title
def run(self):
st.title('Solar-MACH')
st.subheader('Source for this great app is from the Streamlit gallery [Solar-MACH](https://github.com/jgieseler/Solar-MACH). An example of how easy it is to convert an existing application and use within a Hydralit multi-page application, see the secret saurce [here] (https://github.com/TangleSpace/hydralit).')
st.markdown('<br><br>',unsafe_allow_html=True)
st.markdown('## Multi-spacecraft longitudinal configuration plotter')
# provide date and time
with st.sidebar.container():
d = st.sidebar.date_input("Select date", datetime.date.today()-datetime.timedelta(days = 2))
t = st.sidebar.time_input('Select time', datetime.time(1, 30))
date = datetime.datetime.combine(d, t).strftime("%Y-%m-%d %H:%M:%S")
# plotting settings
with st.sidebar.container():
st.sidebar.subheader('Plot options:')
plot_spirals = st.sidebar.checkbox('Parker spiral for each body', value=True)
plot_sun_body_line = st.sidebar.checkbox('Straight line from Sun to body', value=True)
show_earth_centered_coord = st.sidebar.checkbox('Add Earth-aligned coord. system', value=False)
transparent = st.sidebar.checkbox('Transparent background', value=False)
plot_reference = st.sidebar.checkbox('Plot reference (e.g. flare)', value=True)
with st.sidebar.expander("Reference coordinates (e.g. flare)", expanded=plot_reference):
reference_sys = st.radio('Coordinate system:', ['Carrington', 'Stonyhurst'], index=0)
if reference_sys == 'Carrington':
reference_long = st.slider('Longitude:', 0, 360, 20)
reference_lat = st.slider('Latitude:', -90, 90, 0)
if reference_sys == 'Stonyhurst':
reference_long = st.slider('Longitude:', -180, 180, 20)
reference_lat = st.slider('Latitude:', -90, 90, 0)
# convert Stonyhurst coordinates to Carrington for further use:
coord = SkyCoord(reference_long*u.deg, reference_lat*u.deg, frame=frames.HeliographicStonyhurst, obstime=date)
coord = coord.transform_to(frames.HeliographicCarrington(observer='Sun'))
reference_long = coord.lon.value
reference_lat = coord.lat.value
import math
reference_vsw = int(float(st.text_input('Solar wind speed for reference', 400)))
if plot_reference is False:
reference_long = None
reference_lat = None
st.sidebar.subheader('Choose bodies/spacecraft and measured solar wind speeds')
with st.sidebar.container():
full_body_list = \
st.sidebar.text_area('Bodies/spacecraft (scroll down for example list)',
'STEREO A, Earth, BepiColombo, PSP, Solar Orbiter, Mars',
height=50)
vsw_list = \
st.sidebar.text_area('Solar wind speed per body/SC (mind the order!)', '400, 400, 400, 400, 400, 400',
height=50)
body_list = full_body_list.split(',')
vsw_list = vsw_list.split(',')
body_list = [body_list[i].strip() for i in range(len(body_list))]
wrong_vsw = False
try:
vsw_list = [int(vsw_list[i].strip()) for i in range(len(vsw_list))]
except ValueError:
wrong_vsw = True
all_bodies = print_body_list()
# ugly workaround to not show the index in the table: replace them with empty strings
all_bodies.reset_index(inplace=True)
all_bodies.index = [""] * len(all_bodies)
st.sidebar.table(all_bodies['Key'])
st.sidebar.markdown('[Complete list of available bodies](https://ssd.jpl.nasa.gov/horizons.cgi?s_target=1#top)')
if wrong_vsw:
st.error('ERROR: There is something wrong in the solar wind speed list! Maybe some missing or wrong comma?')
st.stop()
if len(body_list) == len(vsw_list):
# initialize the bodies
c = HeliosphericConstellation(date, body_list, vsw_list, reference_long,
reference_lat)
# make the longitudinal constellation plot
plot_file = 'Solar-MACH_'+datetime.datetime.combine(d, t).strftime("%Y-%m-%d_%H-%M-%S")+'.png'
c.plot(
plot_spirals=plot_spirals, # plot Parker spirals for each body
plot_sun_body_line=plot_sun_body_line, # plot straight line between Sun and body
show_earth_centered_coord=show_earth_centered_coord, # display Earth-aligned coordinate system
reference_vsw=reference_vsw, # define solar wind speed at reference
transparent = transparent,
# outfile=plot_file # output file (optional)
)
# download plot
filename = 'Solar-MACH_'+datetime.datetime.combine(d, t).strftime("%Y-%m-%d_%H-%M-%S")
plot2 = io.BytesIO()
plt.savefig(plot2, format='png', bbox_inches="tight")
# plot3 = base64.b64encode(plot2.getvalue()).decode("utf-8").replace("\n", "")
# st.markdown(f'<a href="data:file/png;base64,{plot3}" download="{plot_file}" target="_blank">Download figure as .png file</a>', unsafe_allow_html=True)
download_button_str = self.download_button(plot2.getvalue(), filename+'.png', f'Download figure as .png file', pickle_it=False)
#st.markdown(download_button_str, unsafe_allow_html=True)
# display coordinates table
df = c.coord_table
df.index = df['Spacecraft/Body']
df = df.drop(columns=['Spacecraft/Body'])
df = df.round(0)
df = df.rename(columns=
{"Spacecraft/Body": "Spacecraft / body",
"Carrington Longitude (°)": "Carrington longitude",
"Latitude (°)": "Carrington latitude",
"Heliocentric Distance (AU)": "Heliocent. distance",
"Longitudinal separation to Earth's longitude": "Longitud. separation to Earth longitude",
"Latitudinal separation to Earth's latitude": "Latitud. separation to Earth latitude",
"Vsw": "Solar wind speed",
"Magnetic footpoint longitude (Carrington)": "Magnetic footpoint Carrington longitude",
"Longitudinal separation between body and reference_long": "Longitud. separation bw. body & reference",
"Longitudinal separation between body's mangetic footpoint and reference_long": "Longitud. separation bw. body's magnetic footpoint & reference",
"Latitudinal separation between body and reference_lat": "Latitudinal separation bw. body & reference"})
st.table(df.T)
# download coordinates
# filename = 'Solar-MACH_'+datetime.datetime.combine(d, t).strftime("%Y-%m-%d_%H-%M-%S")
# csv = c.coord_table.to_csv().encode()
# b64 = base64.b64encode(csv).decode()
# st.markdown(f'<a href="data:file/csv;base64,{b64}" download="{filename}.csv" target="_blank">Download table as .csv file</a>', unsafe_allow_html=True)
download_button_str = self.download_button(c.coord_table, filename+'.csv', f'Download table as .csv file', pickle_it=False)
#st.markdown(download_button_str, unsafe_allow_html=True)
else:
st.error(f"ERROR: Number of elements in the bodies/spacecraft list \
({len(body_list)}) and solar wind speed list ({len(vsw_list)}) \
don't match! Please verify that for each body there is a solar \
wind speed provided!")
# footer
st.markdown("""---""")
st.markdown('The *Solar MAgnetic Connection Haus* (Solar-MACH) tool is a \
multi-spacecraft longitudinal configuration plotter. It was \
originally developed at the University of Kiel, Germany, and further \
discussed within the [ESA Heliophysics Archives USer (HAUS)]\
(https://www.cosmos.esa.int/web/esdc/archives-user-groups/heliophysics) \
group. It is now opened to everyone ([original code]\
(https://github.com/esdc-esac-esa-int/Solar-MACH)).')
st.markdown('[Forked and modified](https://github.com/jgieseler/Solar-MACH) by \
[J. Gieseler](https://jgieseler.github.io) (University of Turku, Finland). \
[**Get in contact**](mailto:[email protected]?subject=Solar-MACH).')
col1, col2 = st.columns((5,1))
col1.markdown("The development of the online tool has received funding from the \
European Union's Horizon 2020 research and innovation programme \
under grant agreement No 101004159 (SERPENTINE).")
col2.markdown('[<img src="https://serpentine-h2020.eu/wp-content/uploads/2021/02/SERPENTINE_logo_new.png" \
height="80">](https://serpentine-h2020.eu)', unsafe_allow_html=True)
st.markdown('Powered by: \
[<img src="https://matplotlib.org/stable/_static/logo2_compressed.svg" height="25">](https://matplotlib.org) \
[<img src="https://streamlit.io/images/brand/streamlit-logo-secondary-colormark-darktext.svg" height="30">](https://streamlit.io) \
[<img src="https://raw.githubusercontent.com/sunpy/sunpy-logo/master/generated/sunpy_logo_landscape.svg" height="30">](https://sunpy.org)', \
unsafe_allow_html=True)
|