Fortran source map
This map is based on the supplied XSTAR 2.59g source archive (xstar_source.tar.gz, SHA-256 f64c8c394e05f5a056206f1143259a8830f58ddf950c1efc15a03a00572db37a). It records the canonical executable ownership that productization must preserve.
The table intentionally distinguishes scientific computation, caller-owned workspace, and publication lifetime. Many parity defects arose when those were treated as interchangeable.
Routine-level concordance
Fortran routine/file |
Scientific role |
Important local/caller workspace |
Python implementation |
C++ implementation |
Qualification evidence |
Intentional deviations / notes |
|---|---|---|---|---|---|---|
|
Top-level executable, parameter/setup sequence, radial pass/shell controller, final-output sequence |
radial counters |
|
|
all-62 STEP 12.3.42; all-62 FITS 12.3.43.3; three-mode 12.3.44 |
Python decomposes inline controller blocks into testable functions but preserves source predicates/order. |
|
Read parameters; calculate initial pressure/density/radius and source-control values |
|
|
|
|
|
|
Energy-grid initialization, radiation remapping, initial global state |
|
|
source-real energy-grid helpers and native run-state construction |
source-port 0.4.60/0.4.63; C++ three-mode 12.3.44 |
Python/C++ use explicit arrays rather than COMMON/global storage, but retain source grid values/order. |
|
Load ATDB, call |
packed record vectors, pointer table, level temperature data |
|
|
atomic source-port tests; all-element fixed-state 12.3.x; C++ 12.3.44 |
Memory-mapped Python FITS storage avoids a second GiB-scale copy; logical record semantics remain source-one-based. |
|
Construct derived database topology and publication attachments |
|
|
native |
generic |
Cache files may persist derived pointers, but the pointer identities are checked against the same source construction. |
|
First-pass total-rate ionization balance and active adjacent ion-stage selection |
total ionization/recombination arrays, preliminary ion fractions, |
|
rate/element construction in |
source-port pre-matrix qualification; all-62 science 12.3.42/43 |
This pass is intentionally separate from population-weighted post-solve diagnostics. |
|
Master fixed-temperature heating/cooling/rate/population calculation across elements |
global |
|
|
Ca/O all-element matrix closure 12.3.25; all-62 12.3.42-44 |
Python packages state into return objects/callbacks instead of global COMMON arrays. Source element order and reduction semantics remain qualified. |
|
Per-element preliminary balance, compact basis, record-rate matrix assembly, solve and element diagnostics |
element-local ion block, |
|
|
|
C++ compact terminal rows use the accepted source endpoint clamp ( |
|
Build per-element/ion compact level representation, superlevel mapping and LTE level populations |
|
|
|
matrix/level population qualifications culminating in 12.3.25 |
Python preserves explicit one-based compact topology even though NumPy storage is zero-based internally. |
|
Traverse atomic records, evaluate rates, add source-ordered matrix/heating/cooling contributions |
record-local |
|
|
extensive type/rate closure; all-element terminal clamp 12.3.25; three-mode 12.3.44 |
C++ may batch/evaluate typed kernels, but accepted production paths preserve the source contribution ordering and active-family gates. |
|
Solve multilevel statistical-equilibrium operator with Lucy superlevel iteration and normalization |
compact matrices |
|
|
Ca XVIII/Ca XVII matrix attribution/closure 12.3.25 |
Solver representation differs, but accepted endpoint/domain, normalization, and final population semantics are source-equivalent. |
|
Continuum Compton/free-free heating/cooling, bremsstrahlung emissivity, final thermal aggregation |
continuum opacity/emissivity, |
|
|
0.4.39-0.4.42 source-port closures; thermal parity campaign; 12.3.44 |
Native reduction is optimized but must retain source term ownership and accepted ordering. |
|
Charge/thermal equilibrium nonlinear controller; repeated |
mutable trial temperature/electron state, previous trial global populations, bracket/secant variables, residuals and iteration counters |
|
native controller support in |
DSEC source-port 0.4.45+; all-62 trajectory/STEP 12.3.42; C++ 12.3.44 |
No generic root-finder substitution: branch order and source state ownership are characterization-tested. |
|
Integrated/reduced-grid line emissivity/opacity and RRC emissivity/absorption/threshold-opacity production |
|
|
|
final FITS 12.3.43.x; Python publication 45.1-45.3.3.8 |
45.3.3.8 adds an output-only retained publication bridge; it must not mutate physical rates/matrices/populations. |
|
Full-grid continuum/line/RRC emission and opacity construction after integrated products are available |
|
|
|
spectrum/continuum/detail4 closures; all-62 FITS 12.3.43.3; three-mode 12.3.44 |
Python exposes rank/bin workspaces explicitly. C++ uses qualified batching/optimized traversal where bit/material parity is established. |
|
Accumulate a source line profile into continuum opacity over the active energy range |
line center/width, |
|
|
Type50 optimization 12.3.26-31, especially 12.3.31 cursor promotion/decomposition |
C++ cursor/AVX helpers alter traversal mechanics only. Accepted invariant: same source-order profile arithmetic/update semantics and bit-equivalent qualified products. |
|
Choose radial shell thickness from opacity/emission/line constraints and user Courant controls |
|
|
standalone production radial controller |
radial source-port 0.4.64; all-62 STEP 12.3.42 |
Source formulas/order retained; no new adaptive algorithm. |
|
Two-stream continuum/radiation transfer into and out of a shell |
|
|
|
radial validation 0.4.64-0.4.68; all-62 12.3.42-44 |
Arrays are object-owned rather than COMMON-owned; direction ownership follows source semantics. |
|
Limit/terminate radial stepping against total column, radius and source stop criteria |
|
|
standalone production controller |
O VII terminal-state repairs 12.3.9-11; exact radius 12.3.36; all-62 12.3.42 |
Termination is source predicate logic, not a tolerance-driven Python convergence invention. |
|
Persist and restore per-shell state across radial passes |
REAL(4)-persisted scalar/population/line/RRC/continuum values; HDU insertion order; direction-owned depths |
|
native run-state/FITS persistence in standalone path |
source-port 0.4.67; detail/publication closures 12.3.43-45 |
In-memory Python snapshots model source FITS persistence for bounded execution; REAL(4) round-trip semantics are explicit. |
|
Per-shell level/population detail writer |
level identities, populations, LTE/departure state, shell metadata |
|
|
detail population/identity closures through 12.3.43; C++ 12.3.44 |
Publication-only formatting/metadata may differ internally; qualified product semantics govern. |
|
Per-shell detailed line writer ( |
line identity, energy, inward/outward emission, opacity/depth |
|
|
detal2 inventory/activity closure 12.3.43.2; all-62 FITS |
Source membership and material numerical surfaces are separately diagnosed. |
|
Per-shell detailed RRC/continuum-record writer ( |
|
|
|
45.3.3.7 C5 terminal replay; 45.3.3.8 full spectral publication; Ca/O accepted exceptions |
This surface is lifetime-sensitive. Accepted Ca/O membership exceptions are structural metadata, not numerical science failures. |
|
Per-shell binned continuum writer ( |
|
|
|
continuum/detail4 closure 5.20.14+; final all-62 FITS |
Frozen after closure; no ordinary productization changes to producer science. |
|
STEP/log print surfaces, ranked line/RRC/edge diagnostics, radial summaries, abundance FITS accumulation |
fixed-capacity ranked arrays, labels/identities, ion columns, timing, radial/thermal state |
|
|
comparator repair 12.3.34; material Option15 12.3.36.1; rank attachment 12.3.41; all-62 STEP 12.3.42; 45.1/45.3.3.2 |
Comparator policy separates numerical rank science, identity/order/membership, and inventory/material surfaces. |
|
Final binned spectrum including lines -> |
final |
|
|
spectrum closure 12.3.25/43.3; 12.3.44 |
Final state is evaluated after radial completion; terminal producer lifetime matters. |
|
Final line table -> |
ranked/filtered line identities, energies, luminosities and depths |
|
|
line identity/order/depth closure 5.20.16+; 12.3.43.3/44 |
Fixed-capacity source ranking semantics retained where observable. |
|
Final continuum without binned lines -> |
incident/outward continuum and continuum-only depths |
|
|
continuum closure and 12.3.43.3/44 |
Product is distinct from |
|
Final RRC table -> |
|
|
|
RRC identity/999-vs-9999 closure 5.20.13; 12.3.43.3/44 |
RRC row identity/source attachment is source-defined and separately qualified. |
Top-level startup and initialization
The canonical xstar.f90 startup is approximately:
parameter/default setup
-> rread1
-> ener (primary and working energy grids)
-> xstarsetup
-> readtbl
-> setptrs
-> LTE/atomic support initialization
-> pprint startup parameter/header surfaces
-> init
-> radial passes
The source itself prints xstar version 2.59g. The source map in this document is tied to that supplied tree rather than to an inferred generic XSTAR version.
Parameter and default-REAL semantics
rread1 uses the XPI/UCL parameter interface (uclgsr8, uclgsi, uclgst) and then performs source calculations. Two kinds of semantics matter:
reader conversion semantics - the parameter system may store a lower-kind value which is promoted by a higher-kind reader;
literal semantics - a literal such as
1.e+19is a default REAL literal even when used in aREAL(8)expression.
The accepted 12.3.36 repair reproduces both where material. Future refactors must not normalize these values merely because a mathematically equivalent decimal can be written as Python/C++ binary64.
Atomic-database pointer ownership
setptrs is not just an index accelerator. Its derived relationships participate in physics and publication identity. In particular:
npilev/npilevibind atomic records to level topology;npcon/npconi/npconi2bind continuum/RRC records and their source identities;nplin/nplinibind line records;parent/next-record chains establish traversal and attachment order.
Therefore pointer caches are acceptable only when they reproduce the canonical setptrs result for the same ATDB.
Two-stage ion and level population solve
The Fortran and the XSTAR manual agree on the conceptual split:
use total ionization/recombination rates to estimate ion fractions and choose an adjacent active stage block;
assemble and solve the full multilevel kinetic operator for the selected ions.
This distinction is preserved in Python by ion_balance.py versus element_equilibrium.py and in the qualified native local-zone engine.
Thermal construction and dsec
calc_hmc_all is a fixed-state scientific operator: given a trial temperature/electron state and current radiation/escape state, it computes level populations, rates, heating, cooling, and charge-balance information. dsec is the nonlinear controller that repeatedly calls that operator.
Do not merge those responsibilities in a way that resets source-owned state between trials or changes the source branch order without dedicated characterization.
Reduced-grid versus full-grid spectral paths
The current source explicitly places:
calc_hmc_all
calc_emisab_all
calc_emis_all
at the end of xstarcalc. calc_emisab_all owns integrated line/RRC quantities; calc_emis_all owns the subsequent full-grid spectral construction. This split is required to understand detail-publication lifetime and Type50 ownership.
STEP print-option map
pprint.f90 documents and implements a broad set of print options. The qualification campaign most heavily exercises these:
Option |
Source role |
Qualification interpretation |
|---|---|---|
1 |
strongest emission lines sorted by strength |
numerical ranked-array comparison separated from identity/order diagnostics |
5 |
energy sums / error |
|
9 |
short radial-zone summary |
trajectory/zone characterization |
12 |
append radial abundance data to |
final abundance publication |
15 |
line luminosities/depth material surface |
normalized-L1 material science is primary; inventory is separate |
17 |
column headings |
exact source-style header semantics used by STEP qualification |
19 |
recombination-continuum luminosities |
RRC numerical/product publication |
22 |
final ionization/summary quantities |
terminal source state |
23 |
strongest absorption lines sorted by strength |
numerical rank science separated from identity/order/membership |
24 |
absorption edges |
inventory and numerical common-row science separated |
27 |
ion column densities in the current port |
format/default-REAL threshold fixes accepted in 45.1 |
The exact full option list remains defined by pprint.f90; the table above records the options with explicit frozen comparator policy.
Terminal/final-output lifetime
After the radial passes, xstar.f90 performs another local calculation at the final boundary, calls final STEP options, and then writes final FITS products. Per-shell detail products have already been written by savd -> fstepr* during the radial loop.
This means three states must not be conflated:
the physical local state used during a shell solve;
the state retained/persisted for a detail shell or later pass;
the terminal state consumed by final public products.
The accepted Python publication bridge at science revision 45.3.3.8 is deliberately output-only: it reconstructs source publication lifetime where necessary without modifying rates, matrices, populations, thermal balance, transport, or trajectory.