Skip to content

Commit fde01b8

Browse files
authored
EBTEL interface refactor (#99)
* refactored ebtel interface to use ebtel++ * misc refactoring * minor package reorg * fix ebtel dependency * tests for ebtel interface and heating models * add gallery example for ebtel * reduce ram consumption for rtd * reduce number of points per strand
1 parent c45f6aa commit fde01b8

18 files changed

+620
-585
lines changed
+17-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,26 @@
11
synthesizAR interfaces
2-
==========================================
2+
======================
33

44
.. automodapi:: synthesizAR.interfaces
55
:no-heading:
66
:no-inheritance-diagram:
77

8+
HYDRAD Interface
9+
----------------
10+
11+
.. automodapi:: synthesizAR.interfaces.hydrad
12+
:no-heading:
13+
:no-inheritance-diagram:
14+
815
EBTEL Interface
9-
---------------------
16+
---------------
17+
1018
.. automodapi:: synthesizAR.interfaces.ebtel
1119
:no-heading:
20+
:no-inheritance-diagram:
21+
22+
EBTEL Heating Models
23+
--------------------
24+
25+
.. automodapi:: synthesizAR.interfaces.ebtel.heating_models
26+
:no-heading:

docs/conf.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,10 @@
6565
'astropy': ('https://docs.astropy.org/en/stable', None),
6666
'sunpy': ('https://docs.sunpy.org/en/stable/', None),
6767
'aiapy': ('https://aiapy.readthedocs.io/en/stable/', None),
68-
'fiasco': ('https://fiasco.readthedocs.io/en/latest/', None),
68+
'xrtpy': ('https://xrtpy.readthedocs.io/en/stable/', None),
69+
'fiasco': ('https://fiasco.readthedocs.io/en/stable/', None),
70+
'pydrad': ('https://pydrad.readthedocs.io/en/latest/', None),
71+
'ebtelplusplus': ('https://ebtelplusplus.readthedocs.io/en/stable', None),
6972
'dask': ('https://docs.dask.org/en/latest', None),
7073
}
7174

@@ -121,5 +124,6 @@
121124
'examples_dirs': '../examples', # path to your example scripts
122125
'gallery_dirs': 'generated/gallery', # path to where to save gallery generated output
123126
'filename_pattern': '^((?!skip_).)*$',
124-
'default_thumb_file': '_static/synthesizar_logo.png'
127+
'default_thumb_file': '_static/synthesizar_logo.png',
128+
'matplotlib_animations': True,
125129
}

docs/references.bib

+13
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,16 @@ @article{ugarte-urra_magnetic_2019
3636
doi = {10.3847/1538-4357/ab1d4d},
3737
urldate = {2020-06-12}
3838
}
39+
40+
@article{reep_diagnosing_2013,
41+
title = {Diagnosing the {{Time Dependence}} of {{Active Region Core Heating}} from the {{Emission Measure}}. {{II}}. {{Nanoflare Trains}}},
42+
author = {Reep, J. W. and Bradshaw, S. J. and Klimchuk, J. A.},
43+
year = {2013},
44+
month = feb,
45+
journal = {The Astrophysical Journal},
46+
volume = {764},
47+
pages = {193},
48+
issn = {0004-637X},
49+
doi = {10.1088/0004-637X/764/2/193},
50+
urldate = {2014-07-23}
51+
}

examples/ebtel-nanoflares.py

+102
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
"""
2+
Simulating Time-dependent Emission from Impulsively Heated Loops with EBTEL
3+
===========================================================================
4+
5+
This example demonstrates how to model the resulting AIA emission from an
6+
arcade of loops heated impulsively and modeled using the `ebtelplusplus` code.
7+
"""
8+
import astropy.time
9+
import astropy.units as u
10+
import matplotlib.pyplot as plt
11+
import numpy as np
12+
import sunpy.map
13+
14+
from astropy.coordinates import SkyCoord
15+
from astropy.visualization import AsinhStretch, ImageNormalize, quantity_support
16+
from sunpy.coordinates import get_horizons_coord
17+
18+
import synthesizAR
19+
20+
from synthesizAR.instruments import InstrumentSDOAIA
21+
from synthesizAR.interfaces.ebtel import EbtelInterface
22+
from synthesizAR.interfaces.ebtel.heating_models import PowerLawNanoflareTrain
23+
from synthesizAR.models import semi_circular_arcade
24+
25+
# sphinx_gallery_thumbnail_number = -1
26+
27+
###########################################################################
28+
# First, set up the coordinates for the arcade. The structure we will model
29+
# is an arcade of longer overlying loops with an arcade of successively
30+
# shorter loops underneath.
31+
32+
obstime = astropy.time.Time('2022-11-14T22:00:00')
33+
pos = SkyCoord(lon=15*u.deg,
34+
lat=25*u.deg,
35+
radius=1*u.AU,
36+
obstime=obstime,
37+
frame='heliographic_stonyhurst')
38+
arcade_coords = []
39+
delta_s = 0.3 * u.Mm
40+
for l in np.arange(25,150,25)*u.Mm:
41+
n_points = int(np.ceil((l/delta_s).decompose()))
42+
arcade_coords += semi_circular_arcade(l, 5*u.deg, 50, pos, n_points=n_points)
43+
44+
###########################################################################
45+
# Next, build a `~synthesizAR.Skeleton` from the coordinates of the strands
46+
# in our arcade.
47+
strands = [synthesizAR.Strand(f'strand{i}', c) for i, c in enumerate(arcade_coords)]
48+
arcade = synthesizAR.Skeleton(strands)
49+
50+
###########################################################################
51+
# We can visualize what this structure would look like as observed from
52+
# the Solar Dynamics Observatory.
53+
sdo_observer = get_horizons_coord('SDO', time=obstime)
54+
arcade.peek(observer=sdo_observer,
55+
axes_limits=[(175, 300)*u.arcsec, (300, 450)*u.arcsec])
56+
57+
###########################################################################
58+
# Next, we will model the hydrodynamic response to an impulsive heating event
59+
# on each strand using the `ebtelplusplus` code. We will simulate a total of
60+
# 3 h of simulation time where each loop is heated by a single event with an
61+
# energy chosen from a powerlaw distribution.
62+
event_model = PowerLawNanoflareTrain(
63+
[0,200]*u.s, 200*u.s, 0*u.s, [1e-3,1e-1]*u.Unit('erg cm-3 s-1'), -1.5
64+
)
65+
ebtel = EbtelInterface(3*u.h, event_builder=event_model)
66+
67+
###########################################################################
68+
# To attach the results of our loop simulation to each strand, we pass the
69+
# interface to the geometric model of our arcade we built above.
70+
arcade.load_loop_simulations(ebtel)
71+
72+
###########################################################################
73+
# We can then visualize the temperature and density evolution of each strand
74+
# as a function of time. Note that because EBTEL is a spatially-averaged model,
75+
# it is assumed that eadch point along the strand has the same temperature and
76+
# density.
77+
with quantity_support():
78+
fig = plt.figure(figsize=(10,5))
79+
ax1 = fig.add_subplot(121)
80+
ax2 = fig.add_subplot(122)
81+
for s in arcade.strands:
82+
ax1.plot(s.time, s.electron_temperature[:,0], color='k', alpha=0.25)
83+
ax2.plot(s.time, s.density[:,0], color='k', alpha=0.25)
84+
85+
###########################################################################
86+
# The last step is to use the temperature and density along each strand to
87+
# compute the emission as observed by the AIA instrument. We'll model the
88+
# emission from 500 s to 6000 s at a cadence of 50 s for the 193 Å channel.
89+
aia = InstrumentSDOAIA(np.arange(500,6e3,50)*u.s,
90+
sdo_observer,
91+
pad_fov=(20, 20)*u.arcsec)
92+
maps = aia.observe(arcade, channels=aia.channels[3:4])
93+
94+
###########################################################################
95+
# We can easily visualize this time-dependent emission using a
96+
# `~sunpy.map.MapSequence`.
97+
mseq = sunpy.map.MapSequence(maps['193'], sequence=True)
98+
fig = plt.figure()
99+
ax = fig.add_subplot(projection=mseq[0])
100+
ani = mseq.plot(axes=ax, norm=ImageNormalize(vmin=0, vmax=5, stretch=AsinhStretch()))
101+
102+
plt.show()

pyproject.toml

+3-2
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,19 @@ Homepage = "https://github.com/wtbarnes/synthesizAR"
2929
Documentation = "https://synthesizar.readthedocs.io"
3030

3131
[project.optional-dependencies]
32-
all = ["synthesizAR[aia,xrt,atomic,hydrad,parallel]"]
32+
all = ["synthesizAR[aia,atomic,ebtel,hydrad,parallel,xrt]"]
3333
aia = ["aiapy"]
34-
xrt = ["xrtpy"]
3534
atomic = [
3635
"plasmapy",
3736
"fiasco",
3837
]
38+
ebtel = ["ebtelplusplus"]
3939
hydrad = ["pydrad@git+https://github.com/rice-solar-physics/pydrad@main"]
4040
parallel =[
4141
"dask[complete]",
4242
"distributed",
4343
]
44+
xrt = ["xrtpy"]
4445
test =[
4546
"synthesizAR[all]",
4647
"tox",
+1-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
"""
22
Interface to the 0D EBTEL model
33
"""
4-
from .ebtel import EbtelInterface
5-
from .heating_models import *
6-
from .util import *
4+
from .ebtel import *

0 commit comments

Comments
 (0)