Skip to content

Add warm thick - #293

Open
KriSun95 wants to merge 6 commits into
sunpy:mainfrom
KriSun95:add-warm-thick
Open

Add warm thick#293
KriSun95 wants to merge 6 commits into
sunpy:mainfrom
KriSun95:add-warm-thick

Conversation

@KriSun95

@KriSun95 KriSun95 commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator

Opening this WIP PR that introduces the warm thick target model...at least the core part of it

The warm thick target is the addition of the thick target and a thermal component; that thermal component is the ThermalEmission model where the emission measure input is calculated from the thick target's low-energy cut-off and electron flux values, and new plasma number density and column length parameters.

I've made a new model called ThickTargetWarmContribution that, given these parameters, will calculate the thermal component o the whole warm thick target model we know rom IDL. That should mean that to re create the whole warm thick target model we would only need to do:

warm_thick = ThickTarget()+ThickTargetWarmContribution()

and make sure the low-energy cut-off and electron flux parameters are shared.

It is a work in progress, still need to add tests and comparisons to IDL, etc. but we'll want this physical model in eventually I'd imagine so might as well put it here for folk to see.

Here is a snippet of code I've been using it in:

import astropy.units as u
import matplotlib.pyplot as plt
import numpy as np

from sunkit_spex.models.physical.nonthermal import ThickTarget
from sunkit_spex.models.physical.thermal import ThermalEmission,  ThickTargetWarmContribution

energy_edges = np.arange(1.6, 15, 0.1) << u.keV

energy_mids = (energy_edges[:-1]+energy_edges[1:])/2

## parameters from https://iopscience.iop.org/article/10.3847/2041-8213/ab7341 Table 1 Lindsay's paper
temperature = 10.2 << u.MK
plasma_density = 6e9 << u.cm**-3
low_e_cutoff = 6.5 << u.keV
total_eflux = 1.8e35 << (u.electron/u.second) 
p = 6.3
length = 15 << u.Mm

model_thick = ThickTarget(total_eflux=total_eflux/1e35, p=p, low_e_cutoff=low_e_cutoff, break_energy=1500<< u.keV, q=20, high_e_cutoff=1500<< u.keV)
model_warmtherm2 =  ThickTargetWarmContribution(temperature=temperature,
                                                plasma_density=plasma_density,
                                                low_e_cutoff=low_e_cutoff,
                                                total_eflux=total_eflux,
                                                length=length,
                                                )
# print(model_warmtherm2.parameters)
flux_c2 = model_warmtherm2(energy_edges)
# print(model_warmtherm2.parameters)
flux_e2 = model_warmtherm2.evaluate(energy_edges, *model_warmtherm2.parameters)

plt.figure()
plt.plot(energy_mids, flux_c2, marker="o", label="warm called")
plt.plot(energy_mids, flux_e2, marker="x", ls=":", label="warm evaluated")
plt.plot(energy_mids, model_thick(energy_edges), marker="o", label="thick called")
plt.plot(energy_mids, model_thick(energy_edges)+flux_c2, marker="o", label="warm thick total")
plt.legend()
plt.yscale("log")
plt.ylabel(f"[{flux_c2.unit:latex}]")
plt.xlabel(f"Energy [{energy_mids.unit:latex}]")
plt.show()
Screenshot 2026-07-30 at 3 06 12 pm

KriSun95 added 2 commits July 29, 2026 16:45
…ed and make a thick tharget warm contribution model that should have its e_c param tied to a thick target param e_c?
@settwi

settwi commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Related to #235

@KriSun95

Copy link
Copy Markdown
Collaborator Author

Just another small addition. I've now made a model that combines ThickTarget and ThickTargetWarmContribution.

Still to add:

  • Tests
  • Examples

Here is a snippet of code and the plot showing it working:

import astropy.units as u
import matplotlib.pyplot as plt
import numpy as np

from sunkit_spex.models.physical.nonthermal import ThickTarget, WarmThickTarget
from sunkit_spex.models.physical.thermal import ThermalEmission,  ThickTargetWarmContribution

energy_edges = np.arange(1.6, 15, 0.1) << u.keV

energy_mids = (energy_edges[:-1]+energy_edges[1:])/2

## parameters from https://iopscience.iop.org/article/10.3847/2041-8213/ab7341 Table 1 Lindsay's paper
temperature = 10.2 << u.MK
plasma_density = 6e9 << u.cm**-3
low_e_cutoff = 6.5 << u.keV
total_eflux = 1.8e35 << (u.electron/u.second) 
p = 6.3
length = 15 << u.Mm

model_thick = ThickTarget(total_eflux=total_eflux/1e35, p=p, low_e_cutoff=low_e_cutoff, break_energy=1500<< u.keV, q=20, high_e_cutoff=1500<< u.keV)
model_warmtherm2 =  ThickTargetWarmContribution(temperature=temperature,
                                                plasma_density=plasma_density,
                                                low_e_cutoff=low_e_cutoff,
                                                total_eflux=total_eflux,
                                                length=length,
                                                )
# print(model_warmtherm2.parameters)
flux_c2 = model_warmtherm2(energy_edges)
# print(model_warmtherm2.parameters)
flux_e2 = model_warmtherm2.evaluate(energy_edges, *model_warmtherm2.parameters)

model_awt = WarmThickTarget(total_eflux=total_eflux, 
                            p=p, 
                            low_e_cutoff=low_e_cutoff, 
                            break_energy=1500<< u.keV, 
                            q=20, 
                            high_e_cutoff=1500<< u.keV,
                            temperature=temperature,
                            plasma_density=plasma_density,
                            length=length
                            )
flux_c3 = model_awt(energy_edges)
flux_e3 = model_awt.evaluate(energy_edges, *model_awt.parameters)

plt.figure()
plt.plot(energy_mids, flux_c2, marker="o", label="warm called")
plt.plot(energy_mids, flux_e2, marker="x", ls=":", label="warm evaluated")
plt.plot(energy_mids, model_thick(energy_edges), marker="o", label="thick called")
plt.plot(energy_mids, model_thick(energy_edges)+flux_c2, marker="o", label="warm thick total")
plt.plot(energy_mids, flux_c3, marker="o", ms=3, label="WARM THICK called")
plt.plot(energy_mids, flux_e3, marker="o", ms=2, label="WARM THICK eval")
plt.legend()
plt.yscale("log")
plt.ylabel(f"[{flux_c2.unit:latex}]")
plt.xlabel(f"Energy [{energy_mids.unit:latex}]")
plt.show()
Screenshot 2026-07-31 at 9 48 57 am

Comment on lines +1341 to +1363
temperature = Parameter(
name="temperature",
default=10,
min=1,
max=100,
unit=u.MK,
description="Temperature of the plasma",
fixed=False,
)

mg = Parameter(name="Mg", default=8.15, min=6.15, max=10.15, description="Mg relative abundance", fixed=True)

al = Parameter(name="Al", default=7.04, min=5.04, max=9.04, description="Al relative abundance", fixed=True)

si = Parameter(name="Si", default=8.1, min=6.1, max=10.1, description="Si relative abundance", fixed=True)

s = Parameter(name="S", default=7.27, min=5.27, max=9.27, description="S relative abundance", fixed=True)

ar = Parameter(name="Ar", default=6.58, min=4.58, max=8.58, description="Ar relative abundance", fixed=True)

ca = Parameter(name="Ca", default=6.93, min=4.93, max=8.93, description="Ca relative abundance", fixed=True)

fe = Parameter(name="Fe", default=8.1, min=6.1, max=10.1, description="Fe relative abundance", fixed=True)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There must be a better way to do this without repeating the same parameter definition everywhere

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea see #297 for potential method to not have to repeat the parameters would need to be tweaked a bit for here but similar approach should work.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you so much for looking into this. I tried to get around it using inheritance but I kept running into meta-class stuff. This was so annoying to write so I'll edit using #297

@KriSun95

Copy link
Copy Markdown
Collaborator Author

@samaloney , looking at #297 , I think it would be better to merge that first then come back to this PR. The WarmThickTarget and ThickTargetWarmContribution models need all the thermal parameters anyway so I'd need to duplicate the work in #297 if it wasn't merged first.

@ianan , I'm also curious about your thoughts on how I've split up the warm thick target model, effectively just separating out the thermal contribution into its own separate model so we have both the ThickTargetWarmContribution mode and overall WarmThickTarget (equal to ThickTarget+ThickTargetWarmContribution) model. Additionally, any comments on the descriptions in the doc-strings (here and here ) or anything else would be greatly appreciated.

I'll move this off of a draft PR since I don't know if it being a "draft" stops folk editing/collaborating on it.

@KriSun95
KriSun95 marked this pull request as ready for review August 12, 2026 14:46
@KriSun95 KriSun95 added the Solar Physics Knowledge This requires some understanding of solar physics. label Aug 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Solar Physics Knowledge This requires some understanding of solar physics.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants