Note
Go to the end to download the full example code.
Create a VDEM#
This how-to demonstrates how to create a Velocity-Differential Emission Measure (VDEM) for MUSE.
A VDEM contains the physical properties of the solar atmosphere (temperature, velocity, spatial structure).
import gc
import os
import contextlib
from pathlib import Path
import matplotlib.pyplot as plt
import numpy as np
import pooch
from matplotlib import colors
from PlasmaCalcs.hookups.muram.muram_calculator import MuramCalculator
from muse.synthesis.utils import create_simple_vdem
Creating a VDEM
The MUSE library includes a simple function to create VDEMs. But we will use PlasmaCalcs to derive the VDEM properties from a MURaM simulation snapshot.
PlasmaCalcs includes the possibility to create VDEMs with many more options: absorption, other interpolation methods, TRAC if applies, limb view options, etc.
We will use a MURaM simulation snapshot of a flare. The data is stored online at Stanford. It was used in A comprehensive three-dimensional radiative magnetohydrodynamic simulation of a solar flare.
To download the data, we will use pooch. To avoid downloading individual files, we will use a tar-ed snapshot.
tar_path = pooch.retrieve(
"https://www.dropbox.com/scl/fi/tpkscbv2jq0slpz5hbupe/flare_nature_astro.tar.gz?rlkey=egmnsk2u8y17sdx4d6rcl8brm&st=kllq9izh&e=1&dl=1",
known_hash="4ddc37682e65ee343657929beb8ddc50f472411ebd9fca66ec6ee18afeaf68c9",
fname="flare_nature_astro.tar.gz",
processor=pooch.Untar(),
)
simulation_path = Path(os.path.commonpath(tar_path))
# Due to a bug in the MURaM reader, we need to change the working directory to the simulation path.
with contextlib.chdir(simulation_path):
# In your case, you may need to change the snapshot number if you have your own simulation.
muram_calc = MuramCalculator(dir=simulation_path, snap="0310000", units="cgs")
temperature = muram_calc("T") # Temperature array in K
r_per_nH_tot = (muram_calc.elements.n_per_nH() * muram_calc.elements.m * muram_calc.u("amu")).sum()
ne_nh = (muram_calc("r") / r_per_nH_tot) ** 2 # Emission measure 1/cm^6
velocity = muram_calc("u", component="z") * 1e-5 # velocity along the line of sight in km/s
cell_length = muram_calc("dz") + muram_calc("maindims_z_coord") * 0.0 # grid spacing along the line of sight in cm
x_coord = muram_calc("maindims_x_coord")
y_coord = muram_calc("maindims_y_coord")
velocity_axis = np.arange(-500, 510, 10) # Velocity axis in km/s
log_temperature_axis = np.arange(5.5, 7.6, 0.1)
vdem = create_simple_vdem(
temperature.values,
velocity.values,
ne_nh,
cell_length,
x_coord,
y_coord,
velocity_axis,
log_temperature_axis,
# Used to split the x axis into this many contiguous blocks and process them one at a time.
# Required for the online documentation build.
n_x_chunks=8,
)
# Due to tight memory constraints, the online documentation build requires deleting a few large variables.
del (
temperature,
velocity,
ne_nh,
cell_length,
x_coord,
y_coord,
velocity_axis,
log_temperature_axis,
MuramCalculator,
muram_calc,
)
gc.collect()
Downloading data from 'https://www.dropbox.com/scl/fi/tpkscbv2jq0slpz5hbupe/flare_nature_astro.tar.gz?rlkey=egmnsk2u8y17sdx4d6rcl8brm&st=kllq9izh&e=1&dl=1' to file '/home/docs/.cache/pooch/flare_nature_astro.tar.gz'.
Untarring contents of '/home/docs/.cache/pooch/flare_nature_astro.tar.gz' to '/home/docs/.cache/pooch/flare_nature_astro.tar.gz.untar'
/home/docs/checkouts/readthedocs.org/user_builds/muse-lmsal/conda/latest/lib/python3.13/site-packages/muse/synthesis/utils.py:70: RuntimeWarning: overflow encountered in cast
q.astype(np.float32, copy=False) for q in [velocity, temperature, ne_nh, velocity_axis, log_temperature_axis]
/home/docs/checkouts/readthedocs.org/user_builds/muse-lmsal/conda/latest/lib/python3.13/site-packages/muse/synthesis/utils.py:103: RuntimeWarning: invalid value encountered in multiply
los_integrand = ne_nh * bin_fraction * cell_length_los
/home/docs/checkouts/readthedocs.org/user_builds/muse-lmsal/conda/latest/lib/python3.13/site-packages/muse/synthesis/utils.py:103: RuntimeWarning: overflow encountered in multiply
los_integrand = ne_nh * bin_fraction * cell_length_los
/home/docs/checkouts/readthedocs.org/user_builds/muse-lmsal/conda/latest/lib/python3.13/site-packages/muse/synthesis/utils.py:112: RuntimeWarning: overflow encountered in cast
.astype(ne_nh.dtype, copy=False)
60
The VDEM contains information about: - Temperature distribution (logT dimension) - Doppler velocity distribution (vdop dimension) - Spatial distribution (x, y dimensions) - Temporal evolution (time dimension)
We can now print and plot the VDEM we created.
print(vdem)
# Moment 0 from VDEM
vdem.vdem.sum(dim=["logT", "vdop"], skipna=False).plot(norm=colors.LogNorm(vmin=1))
plt.show()

<xarray.Dataset> Size: 2GB
Dimensions: (logT: 21, vdop: 101, x: 256, y: 768)
Coordinates:
* logT (logT) float32 84B 5.5 5.6 5.7 5.8 5.9 6.0 ... 7.1 7.2 7.3 7.4 7.5
* vdop (vdop) float32 404B -500.0 -490.0 -480.0 ... 480.0 490.0 500.0
* x (x) float64 2kB 0.0 1.92e+07 3.84e+07 ... 4.877e+09 4.896e+09
* y (y) float64 6kB 0.0 6.4e+06 1.28e+07 ... 4.902e+09 4.909e+09
Data variables:
vdem (logT, vdop, x, y) float32 2GB 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0
Attributes:
n_x_chunks: 8
HISTORY: ['create_simple_vdem(temperature=temperature, velocity=vel...
date created: 02-Jul-2026
version: 0.2.dev73+gb8b7d8bc3
Now that you have a VDEM, you can use it to create a synthetic MUSE observation.
Total running time of the script: (1 minutes 32.359 seconds)
Estimated memory usage: 5878 MB