Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
132 commits
Select commit Hold shift + click to select a range
b3c9b77
New folder and init for DEM efforts
Jul 16, 2025
4bea4b7
Merge branch 'main' into xray-plasma-decoder-dem-solver
joyvelasquez Jul 16, 2025
d7b11ab
Add new script that will hold DEM code
Jul 16, 2025
cdb20bc
Fixing ruff rules
Jul 16, 2025
50a3754
Adding to make new branch'
Jul 16, 2025
646b267
Move xrt_dem_iterative module into xrtpy/
Jul 16, 2025
574a3e1
Merge branch 'main' into xray-plasma-decoder-dem-solver
joyvelasquez Jul 16, 2025
3406ce6
Updating new function-calling
Jul 16, 2025
b6f7a50
Define main elements
Jul 16, 2025
ebd02be
Adding observed_intensities function
Jul 25, 2025
28db848
Adding observed_intensities function
Jul 26, 2025
892c8d5
Adding a quick for consistency;
Jul 26, 2025
dd8d69d
Adding functions
Jul 29, 2025
26bb0c2
Updated method of naming functions
Jul 29, 2025
5b8ebed
Adding XRTDEMIterative class to the init
Jul 29, 2025
f5db31c
Adding intensity_errors function
Jul 29, 2025
3c04580
Adding conditions to values
Jul 29, 2025
5dd94c9
Adding more basic info for using in mandatory functions and check of …
Jul 29, 2025
a26dbde
Applied ruff
Jul 29, 2025
f97703e
Add basic function to recorde number of MC user wantst to run
Jul 29, 2025
5a52acf
Applied black
Jul 29, 2025
60d2cf2
Adding max iter
Jul 30, 2025
a03a623
Adding create_logT_grid
Jul 31, 2025
2798577
Adding _build_response_matrix
Jul 31, 2025
fa3d7fd
Trying to get a working initial estimate of how much plasma is emitti…
Jul 31, 2025
510035c
Merge branch 'main' into xray-plasma-decoder-dem-solver
joyvelasquez Aug 11, 2025
bc5ec29
Creating a script for monte_carlo_iteration'
Aug 25, 2025
46dece7
Adding init
Aug 25, 2025
e2fe9a0
WIP: saving changes before rebase
Aug 25, 2025
5e704b0
Updating path the data file
Aug 25, 2025
25a4394
Updating init info
Aug 25, 2025
3f7aa5b
Applied Black
Aug 26, 2025
cc06e61
Working on solving DEM scale issue
Aug 27, 2025
3ed8726
Working on create_logT_grid
Aug 28, 2025
608522b
Merge branch 'main' into xray-plasma-decoder-dem-solver
joyvelasquez Aug 28, 2025
526e3c2
move the emptiness check above the formatter.
Aug 28, 2025
3cb632a
Tighten the first error block
Aug 28, 2025
abc8dc8
little snippet is just a guardrail to make sure your log-T grid is re…
Aug 28, 2025
2c85443
Forgot to define - n_pts
Aug 28, 2025
f1df988
Redundant error check block at the end
Aug 28, 2025
810a5c1
Minnor clean up
Aug 28, 2025
d7fe729
Clean up on docstrings
Aug 28, 2025
2f0ec9a
Trigger the warning only once, store the result
Aug 28, 2025
aa56f80
Clean up on docstrings
Aug 28, 2025
cf2ee0a
Clean up text
Aug 28, 2025
e43df5a
Updating create_logT_grid
Aug 28, 2025
234b9a8
Applying black
Aug 28, 2025
d549f0b
Updated _interpolate_responses_to_grid
Aug 28, 2025
4f3b4a2
Removing code where it is used twice for the same reason
Aug 28, 2025
3f8f589
Cleaning up some function logic;
Aug 28, 2025
f1a310a
Adding ComputeDEMStatistics
Aug 29, 2025
e2dd4ef
Script for DEM Stats
Aug 29, 2025
3ca6ec3
Adding ComputeDEMStatistics
Aug 29, 2025
2a39844
Removing unsed code
Aug 29, 2025
05f6b4e
Applying black
Aug 29, 2025
04c1163
Minor update to MC code
Aug 29, 2025
427cff0
If lmfit is required for any normal use (not just testing)
Aug 29, 2025
5538c8d
Syntax error
Aug 29, 2025
8835e6f
missing a validate_inputs() method
Aug 29, 2025
0bc097e
Putting validate_inputs() inside class
Aug 29, 2025
3009e11
Cleaning codedem_solver.py
Aug 29, 2025
6ec50f6
Cleaning code
Aug 29, 2025
7e939d8
Cleaning code - test
Aug 29, 2025
15ac54e
Merge branch 'main' into xray-plasma-decoder-dem-solver
joyvelasquez Sep 2, 2025
a90645c
Updated info about xrt
Sep 12, 2025
6282e43
Merge branch 'main' into xray-plasma-decoder-dem-solver
joyvelasquez Sep 12, 2025
6cedf2a
UPdated with two reference for DEM paper
Sep 12, 2025
2c2459d
WIP: local changes before pull
Sep 12, 2025
9a0fb64
WIP: local changes in dem_solver.py
Sep 12, 2025
e648860
Trying to fix git doc 3.13 failing test
Sep 15, 2025
fd4e8e1
fixing - generate_temperature_responses reference
Sep 15, 2025
f3c10f6
Cleaning function
Sep 16, 2025
81161d5
Clean and updated - create_logT_grid
Sep 16, 2025
ca85d4c
Update two functions
Sep 16, 2025
8d6d3c5
Removing_build_response_matrix function
Sep 17, 2025
2b4f761
Removing older version of -_interpolate_responses_to_grid
Sep 17, 2025
69765c9
Clean code and apply black to triple checked code
Sep 17, 2025
5ef701a
Updated solver still needs alot of work - just saving
Sep 19, 2025
28d5b36
Moving plotting function to its own script
Sep 22, 2025
a7959ca
Applying black to plotting
Sep 22, 2025
6a91264
Updated and cleaned out dem_solver main code
Sep 22, 2025
0b3d949
Removed code that is not going to be used
Sep 22, 2025
62d1698
Removed and cleared out code - will update soon
Sep 22, 2025
a126d1d
Merge branch 'main' into xray-plasma-decoder-dem-solver
joyvelasquez Oct 8, 2025
3bc71eb
Merge branch 'main' into xray-plasma-decoder-dem-solver
joyvelasquez Nov 5, 2025
95ba290
Appling black
Nov 5, 2025
254b2e6
Testingccorrect physical units
Nov 17, 2025
0ec1638
Corrected use of relative_error and added notes to correct/check later
Nov 17, 2025
04bdbfd
Updated function names to better understand/reference in code
Nov 17, 2025
e64d476
Debugging-updates made
Nov 18, 2025
f8ad163
Adding code incase - observed intensities are all zero.
Nov 18, 2025
ddd90bf
Fixing placement of code
Nov 18, 2025
9be53d8
Prepare the scaled observed intensities and uncertainties-new function
Nov 19, 2025
a08fbf7
Just a note to add test for scaling before being sent to DEM function
Nov 19, 2025
77b3bc6
Removed self.logT in the init and kept a sinlge one in a created func…
Nov 19, 2025
a12669d
Clean up - _estimate_initial_dem and mirror IDL where I forgot to -Us…
Nov 20, 2025
5827f22
Cleaned up code and methods
Nov 20, 2025
6bf6ade
Quick clean up
Nov 20, 2025
22e92a6
Working on the MC'
Nov 21, 2025
c426a25
Removing code that will not be used
Nov 21, 2025
5352869
Worked on the code method and finally got a DEM and MC to work, main …
Nov 21, 2025
27c23d2
Cleaning up plotting to just two.
Nov 22, 2025
9ca92ed
Clean up code and added summary function
Nov 22, 2025
ccdf112
Cleaned up plotting functions
Nov 24, 2025
18a60e6
Cleaning up minor code issues
Nov 24, 2025
337c481
Removed xrt_dem_statistics.py and monte_carlo_iteration.py
Nov 24, 2025
952e4cb
Cleaned up summary function
Nov 24, 2025
b6c8262
Working on test now
Nov 24, 2025
473a0cb
Adding more test
Nov 25, 2025
fda3d0e
Correction to warning error output
Nov 25, 2025
766370d
Adding more test
Nov 25, 2025
d11ef99
spline testing
Nov 25, 2025
895834c
Creating test for residuals - dummy data
Nov 25, 2025
264a734
Adding more test, and cleaning up formatting
Nov 25, 2025
c345534
Now working on docstrings-main function doc
Nov 25, 2025
b4d8bfe
Updating intensity_errors doc
Nov 25, 2025
b37654f
Cleaned up doc for _interpolate_responses_to_grid and _estimate_initi…
Nov 25, 2025
2ba49f7
Added more docstrings and code formatting using tools like black, ruf…
Nov 26, 2025
d7012ee
Few string/comment edits
Nov 26, 2025
d36d4e0
Cleaning up code and removing comments
Nov 26, 2025
b3d851c
Working on docs site for the DEM
Nov 26, 2025
c993a66
Updating doc site page
Nov 28, 2025
244e5be
Updating DEM doc site
Nov 28, 2025
8388f54
Few doc edits
Nov 29, 2025
c19e5bc
Trying to fix github doc test to pass
Nov 29, 2025
a8e9171
Added three new works-def
Nov 29, 2025
c87c2aa
Working on test for DEM;
Jan 14, 2026
0dddf65
Merge branch 'main' into xray-plasma-decoder-dem-solver
joyvelasquez Jan 15, 2026
77e651f
Updating testing values to real values
Jan 15, 2026
249a5e7
Adding more IDL sav DEM testing files
Jan 15, 2026
1588fc0
Merge branch 'main' into xray-plasma-decoder-dem-solver
joyvelasquez Jan 15, 2026
c85ef0d
Merge remote-tracking branch 'upstream/main' into xray-plasma-decoder…
Jan 21, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions docs/about_xrt.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ Hinode
======

.. image:: _static/images/hinode_satellite.png
:alt: Hinode Satellite
:align: center
:alt: Hinode Satellite
:align: center

Hinode is a joint mission involving the space agencies of Japan, the United States, Europe, and the United Kingdom.
It is depicted in the *illustration shown above*.
Expand All @@ -25,9 +25,9 @@ The X-Ray Telescope
===================

.. image:: _static/images/XRT_composite_image_full_disk_14February2015.png
:alt: XRT Composite Image
:align: center
:scale: 50%
:alt: XRT Composite Image
:align: center
:scale: 50%

The X-Ray Telescope (XRT), depicted as a long linear black tube on the Hinode spacecraft is a crucial instrument for observing the solar corona's most intense regions, with temperatures ranging from 1,000,000 to 10,000,000 Kelvin.
The image below is a synoptic composite from February 14, 2015, created using the Al-Mesh/Be-Thin/Al-Med filters.
Expand All @@ -36,7 +36,7 @@ For a comprehensive overview of XRT's mission and capabilities, please visit the

.. tip::

Visit the `XRT Picture of the Week`_ and the `Hinode-XRT YouTube`_ page for captivating visual content showcasing the XRT's solar observations.
Visit the `XRT Picture of the Week`_ and the `Hinode-XRT YouTube`_ page for captivating visual content showcasing the XRT's solar observations.

XRT uses two sequentially positioned filter wheels, as shown in the diagram below, where each wheel houses a variety of filters.
By rotating these wheels, scientists can select different filters to study the Sun in different wavelengths, thereby enhancing the resolution and quality of solar images.
Expand Down Expand Up @@ -73,8 +73,8 @@ The existing filters are structured as follows:
The process is the same for all XRT filter channels.

.. image:: _static/images/XRT_filter_wheels_Sun_View_Diagram.png
:alt: Diagram of the XRT Filter Wheels
:align: center
:alt: Diagram of the XRT Filter Wheels
:align: center

Data Products
*************
Expand All @@ -99,8 +99,8 @@ The XRT software was originally created in the Interactive Data Language (IDL).

.. note::

Please note that the `SolarSoft XRT Analysis Guide`_ does not serve as a guide for using XRTpy.
It focuses solely on the analysis of XRT data using the IDL software.
Please note that the `SolarSoft XRT Analysis Guide`_ does not serve as a guide for using XRTpy.
It focuses solely on the analysis of XRT data using the IDL software.

.. _Hinode-XRT YouTube: https://www.youtube.com/user/xrtpow
.. _Interactive Data Language: https://www.l3harrisgeospatial.com/Software-Technology/IDL
Expand Down
20 changes: 20 additions & 0 deletions docs/bibliography.bib
Original file line number Diff line number Diff line change
Expand Up @@ -171,3 +171,23 @@ @ARTICLE{velasquez:2024
doi = {10.21105/joss.06396},
url = {https://doi.org/10.21105/joss.06396}
}

@ARTICLE{weber:2004,
author = {{Weber}, M.~A. and {DeLuca}, E.~E. and {Golub}, L. and {Sette}, A.~L.},
title = "{Temperature diagnostics with multichannel imaging telescopes}",
journal = "{IAU Symposium 223: Multi-Wavelength Investigations of Solar Activity}",
year = 2004,
pages = {321--328},
publisher = {Cambridge University Press},
doi = {10.1017/S1743921304006088}
}

@ARTICLE{golub:2004,
author = {{Golub}, L. and {DeLuca}, E.~E. and {Sette}, A. and {Weber}, M.},
title = "{DEM analysis with the X-Ray Telescope (XRT) for Solar-B}",
journal = "{ASP Conference Series, The Solar-B Mission and the Outlook for Space-Based Solar Physics}",
year = 2004,
volume = {325},
pages = {217--222},
publisher = {Astronomical Society of the Pacific}
}
3 changes: 2 additions & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
ogp_image = "https://raw.githubusercontent.com/HinodeXRT/xrtpy/main/docs/_static/images/xrtpy_logo.png"
ogp_use_first_image = True
ogp_description_length = 160
ogp_custom_meta_tags = ('<meta property="og:ignore_canonical" content="true" />',)
#ogp_custom_meta_tags = ('<meta property="og:ignore_canonical" content="true" />',)

# Suppress warnings about overriding directives as we overload some of the
# doctest extensions.
Expand Down Expand Up @@ -230,6 +230,7 @@
"feedback_communication*": [],
"contributing*": [],
"code_of_conduct*": [],
"dem_overview*": [],
}
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
Expand Down
264 changes: 264 additions & 0 deletions docs/dem_overview.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,264 @@
.. _xrtpy-dem-overview:

===================================
Differential Emission Measure (DEM)
===================================

.. contents::
:local:
:depth: 2

Introduction
------------

The differential emission measure (DEM) describes how much plasma is present
in the solar corona as a function of temperature. It is a key diagnostic for
understanding coronal heating, solar flares, and the thermal structure of
active regions.

Hinode/XRT is well suited for DEM analysis because it observes the corona
through multiple broadband filters, each sensitive to different temperature
ranges. By combining these channels, we can infer a temperature distribution
DEM(T) that explains the observed X-ray intensities.


DEM in XRTpy
------------
XRTpy provides a Python implementation of the iterative spline fitting method
originally available in IDL as `xrt_dem_iterative2.pro <https://hesperia.gsfc.nasa.gov/ssw/hinode/xrt/idl/util/xrt_dem_iterative2.pro>`__.
The core solver is implemented in :class:`xrtpy.xrt_dem_iterative.dem_solver.XRTDEMIterative`.

Conceptually, the solver:
1. Builds a regular grid in log10(T) between user-specified bounds.
2. Interpolates the filter temperature responses onto that grid.
3. Represents log10(DEM) as a spline in log10(T).
4. Uses least-squares fitting (via ``lmfit``) to adjust the spline values so that the modeled filter intensities match the observed intensities.
5. Optionally performs Monte Carlo runs by perturbing the observed intensities with their errors and re-solving the DEM many times to estimate uncertainties.

This approach mirrors the structure and behavior of the IDL routine while providing
a modern, fully open-source implementation in Python.

Required inputs
---------------
The DEM workflow requires three main input pieces:

1. Observed channels (filters)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Type: ``str`` or ``list`` of ``str``
* Description: Names of the filters used in the observation, for example ``"Al-mesh"`` or ``"Be-thin"``.
* These must correspond to valid XRT filters and must match the provided temperature responses one-to-one.

2. Observed intensities
~~~~~~~~~~~~~~~~~~~~~~~
* Type: array-like
* Units: DN/s (normalized per pixel)
* Description: Measured intensities in each filter channel.
* Length must match the number of filters.


3. Temperature response functions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Type: ``list`` of :class:`xrtpy.response.TemperatureResponseFundamental`
* Units: DN s\ :sup:`-1` pix\ :sup:`-1` cm\ :sup:`5`
* Description: Instrument response as a function of temperature for each filter, matching the order of the filters.
* Can be generated using :func:`xrtpy.response.tools.generate_temperature_responses`.




Example
-------
A simple example with two filters:


.. code-block:: python

from xrtpy.response.tools import generate_temperature_responses

filters = ["Al-poly", "Ti-poly"]
responses = generate_temperature_responses(
filters,
"2012-10-27T00:00:00",
)


Overview of the XRTDEMIterative API
-----------------------------------
The main entry point is :class:`xrtpy.xrt_dem_iterative.dem_solver.XRTDEMIterative`.



Constructor
~~~~~~~~~~~
.. code-block:: python

from xrtpy.xrt_dem_iterative import XRTDEMIterative

dem_solver = XRTDEMIterative(
observed_channel=filters,
observed_intensities=intensities,
temperature_responses=responses,
monte_carlo_runs=0,
max_iterations=2000,
)

# Solve for the DEM
dem = dem_solver.solve() # returns the DEM array, also stored in dem_solver.dem

# Plot the DEM
dem_solver.plot_dem()


Enabling Monte Carlo error estimates
------------------------------------
To estimate uncertainties, you can enable Monte Carlo iterations. The solver
will perturb the observed intensities by their errors and re-solve the DEM
for each realization.

.. code-block:: python

N_mc = 100 # number of Monte Carlo runs

dem_solver = XRTDEMIterative(
observed_channel=filters,
observed_intensities=intensities,
temperature_responses=responses,
monte_carlo_runs=N_mc,
max_iterations=2000,
)

dem_solver.solve()

# Monte Carlo DEM Plot
dem_solver.plot_dem_mc() # base DEM plus Monte Carlo curves

The arrays ``dem_solver.mc_dem``, ``dem_solver.mc_chisq``,
``dem_solver.mc_base_obs``, and ``dem_solver.mc_mod_obs`` are then available
for custom analysis.

Comparison with IDL
-------------------
The Python solver is designed to closely follow the logic of the
SolarSoft/IDL routine `xrt_dem_iterative2.pro <https://hesperia.gsfc.nasa.gov/ssw/hinode/xrt/idl/util/xrt_dem_iterative2.pro>`__:




* Uses a regular log10(T) grid.
* Represents log10(DEM) at a set of spline knots.
* Uses a least-squares algorithm to minimize chi-square.
* Supports Monte Carlo noise realizations for uncertainty estimation.


Small numerical differences can arise due to:

* Different interpolation choices (for example, cubic splines from SciPy).
* Differences in optimization libraries (lmfit versus IDL MPFIT).
* Floating-point rounding and platform-specific details.

Within these limits, the Python implementation is intended to produce
results that are consistent with the IDL tool.



Mathematical background
-----------------------
The DEM inversion problem is ill posed. For each filter channel i,
the observed intensity :math:`I_i` is related to the DEM through:

.. math::

I_i = \int DEM(T) \, R_i(T) \, dT

where :math:`R_i(T)` is the temperature response function for the filter,
and :math:`DEM(T)` is the unknown thermal distribution.

Since the number of temperature bins typically exceeds the number of
observed channels, the inversion does not have a unique solution. The
XRTpy solver uses a forward-fitting approach:

1. Assume a parametric form for log10(DEM(T)) using spline knots.
2. Compute model intensities:

.. math::

I_i^{model} = \sum_j DEM(T_j)\, R_i(T_j)\, T_j\, \Delta(\ln T)

3. Adjust the spline values to minimize:

.. math::

\chi^2 = \sum_i \left[
\frac{I_i^{model} - I_i^{obs}}{\sigma_i}
\right]^2

Here :math:`\sigma_i` are the observational uncertainties. Smoothness and
the low number of spline knots help regularize the solution.


Monte Carlo iterations perturb the observed intensities:

.. math::

I_i^{(k)} = I_i^{obs} + \mathcal{N}(0, \sigma_i)

and re-fit the DEM for each realization k. The spread in the resulting DEM
curves provides an estimate of the uncertainty in DEM(T).


Extended example with options
-----------------------------
Below is an extended example showing more constructor options explicitly.
These values match current defaults but are written out here for clarity.

.. code-block:: python

from xrtpy.response.tools import generate_temperature_responses
from xrtpy.xrt_dem_iterative import XRTDEMIterative

filters = ["Al-poly", "Ti-poly", "Be-thin", "C-poly"]
intensities = [2500.0, 1800.0, 900.0, 450.0] # DN/s
observation_date="2012-10-27T00:00:00"

responses = generate_temperature_responses(
filters,
observation_date,
)

dem_solver = XRTDEMIterative(
observed_channel=filters, # Filter names
observed_intensities=intensities, # Observed intensity values
temperature_responses=responses, # Instrument responses

# Optional configuration:
intensity_errors=None, # Obs. uncertainties - default: auto-estimated (3%)
minimum_bound_temperature=5.5, # Minimum log T (default: 5.5)
maximum_bound_temperature=8.0, # Maximum log T (default: 8.0)
logarithmic_temperature_step_size=0.1, # Bin width in log T (default: 0.1)
monte_carlo_runs=100, # # of Monte Carlo runs (default: none)
max_iterations=2000, # Solver max iterations (default: 2000)
normalization_factor=1e21, # Normalization saling factor (default: 1e21)
)

dem_solver.solve()
dem_solver.plot_dem_mc()

.. note::
The values shown above correspond to existing defaults in the solver,
but they are written out here to illustrate what can be tuned.
You can adjust these to best suit your analysis needs.
This mirrors the flexibility of the IDL routine ``xrt_dem_iterative2.pro``.


.. Acknowledgement
.. ---------------
.. *Development of the DEM solver in XRTpy has been supported in part by
.. a NASA Heliophysics Tools and Methods (HTM) program grant (ROSES-2025,
.. element B.20). This effort reflects the ongoing transition of DEM
.. capabilities from legacy IDL routines into modern, open-source Python
.. tools for the solar physics community.*

References
----------
- Golub, L., et al. (2004), Solar Physics, 243, 63. :cite:p:`golub:2004`
- Weber, M. A., et al. (2004), Astrophysical Journal, 605, 528. :cite:p:`weber:2004`
11 changes: 11 additions & 0 deletions docs/gallery/data_processing/README.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Advanced Data Processing
=========================

This section covers advanced image correction and diagnostic tools.

Examples here show how to:
- Deconvolve images to correct for blurring
- Identify and remove light leaks
- Estimate temperature and emission measure using multi-filter observations

These are core XRTpy functionalities for high-level solar data analysis.
Empty file.
Loading
Loading