Skip to content

Predict XRT with utu.dem.emission_measure in the DEM tutorial, and integrate its ranges exactly - #7

Merged
roytsmart merged 1 commit into
mainfrom
docs/dem-mass-matrix
Oct 16, 2026
Merged

roytsmart merged 1 commit into
mainfrom
docs/dem-mass-matrix

Conversation

@roytsmart

Copy link
Copy Markdown
Contributor

This fixes two integrals of the DEM in the DEM tutorial. Neither one was the integral that utu.dem.plowman assumes.

The XRT intensity a DEM predicts

The tutorial predicted the XRT intensity of each DEM as the DEM times the response times the 0.05-dex step. plowman takes the DEM and each response to be linear in log T between the temperatures, and fits each intensity with the integral of their product, Rᵀ M D, where M is the mass matrix of those triangle functions. The rectangle sum weights each temperature by the sum of its row of M instead.

The tutorial now uses utu.dem.emission_measure (sun-data/utu#15, new in utu 0.5.0), which returns M D, so the predicted intensity is the one the inversion fit:

emission_measure = utu.dem.emission_measure(dem, "temperature")
predicted = (emission_measure * outputs_xrt).sum("temperature")

The change is small, and every number in the text still holds:

Ratio of predicted to observed XRT Before After
AIA + XRT, median 1.229 1.236
AIA + XRT, 5th–95th percentile 1.16–1.31 1.17–1.32
AIA alone, median 9.01 8.96
AIA alone, 10th–90th percentile ("3 to 18 times") 3.06–17.81 3.05–17.70

Per pixel, the ratio changes by a median of +0.6% for the DEM from AIA and XRT (at most +2.4%), and by −0.5% for the DEM from AIA alone (at most −8.7%). The χ² maps are unchanged.

The maps of emission measure

The four maps were left Riemann sums over [lower, upper), the nodes times the step, as in the DEM tutorial of sdo before sun-data/solar-dynamics-observatory#30. For a DEM linear between its nodes, the exact integral over a range is the trapezoid rule, which counts the two end nodes by half and includes the node at upper.

As in sdo, the tutorial now gives the DEM log₁₀ T as its inputs and integrates it with FunctionArray.integrate, from the node at lower to the node at upper. The text says why the trapezoid rule is exact here. The old maps, against the exact integral:

log T Median ratio of old to exact
5.6–6.0 0.88
6.0–6.3 1.08
6.3–6.6 1.15
6.6–7.0 1.08

Other changes

  • utu.dem.emission_measure is not used for the maps. Its sum over a range is not the integral of the DEM over that range, since each temperature stands for plasma up to a step either side of it.
  • The logt of the response section, used only by the old maps, is now defined where the maps are made, from the DEM.
  • The doc extras require utu>=0.5.

Checks

I ran every jupyter-execute cell of the edited tutorial in order, against utu 0.5.0, and the same cells of main for the "Before" numbers. All the cells ran. Each of the four maps equals np.trapezoid of the DEM over log T exactly, and the median reduced χ² is still 0.968, with one pixel above 3.

🤖 Generated with Claude Code

https://claude.ai/code/session_017xqpht97bF4FWsACAA4wQa

…tegrate its ranges exactly

The XRT intensity a DEM predicted was the DEM times the response times the 0.05-dex step, which weights each temperature by the sum of its row of the mass matrix utu.dem.plowman fits with. It is now utu.dem.emission_measure (utu 0.5.0) times the response, which is the intensity the inversion fit. Per pixel, the ratio of the predicted to the observed XRT changes by a median of +0.6% for the DEM from AIA and XRT and -0.5% for the DEM from AIA alone, so the numbers in the text stand.

The four maps of emission measure were left Riemann sums over [lower, upper), as in the DEM tutorial of sdo before sun-data/solar-dynamics-observatory#30. They now integrate the DEM over log T with FunctionArray.integrate, whose trapezoid rule is exact for the piecewise-linear DEM of plowman. In the median pixel, the old maps were 0.88 to 1.15 times the exact integral, depending on the range.

The doc extras require utu>=0.5.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017xqpht97bF4FWsACAA4wQa
@codecov

codecov Bot commented Oct 16, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.86%. Comparing base (19ab6ff) to head (46e5604).

Additional details and impacted files
@@           Coverage Diff           @@
##             main       #7   +/-   ##
=======================================
  Coverage   99.86%   99.86%           
=======================================
  Files          18       18           
  Lines        2160     2160           
=======================================
  Hits         2157     2157           
  Misses          3        3           
Flag Coverage Δ
unittests 99.86% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@read-the-docs-community

Copy link
Copy Markdown

Documentation build overview

📚 hinode | 🛠️ Build #35201488 | 📁 Comparing 46e5604 against latest (19ab6ff)

  🔍 Preview build  

1 file changed
± tutorials/dem.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant