Skip to content

Volume classification plot: trapped-passing and deeply-trapped boundaries do not enclose data pixels #349

@krystophny

Description

@krystophny

Symptom

In the volume classification plots generated by
examples/classification/plot_paper_results.py:plot_volume_classification
(figures volume_classification_q[ahi].png), the two analytic boundary
curves do not enclose the per-pixel J_perp data:

  • Dashed deeply-trapped boundary sits visibly below the lower edge
    of the populated trapped band. Worst case is the QI config: dashed
    line at J_perp ≈ 0.70, data lower edge at J_perp ≈ 0.85
    (~0.15 offset).
  • Solid trapped-passing boundary cuts through the upper edge of
    the data rather than enclosing it from above.
  • All three configurations under
    examples/classification/configs/{qi,qh,qa}_volume.in show the same
    pattern, just at different magnitudes.

The boundaries should enclose the trapped-classified pixels precisely;
they currently do not.

Likely cause: inconsistent normalization

In plot_paper_results.py, the boundaries are drawn as:

bmin_global = np.min(bminmax[:, 1])
ax.plot(bminmax[:, 0], bmin_global / bminmax[:, 1], "k", lw=1.5)     # solid
ax.plot(bminmax[:, 0], bmin_global / bminmax[:, 2], "k--", lw=1.0)   # dashed

i.e. both curves are normalized to the global minimum bmin over
all surfaces.

The per-particle J_perp plotted as image pixels comes from
class_parts.dat[:, 2], written by classification.f90:

perp_inv(ipart) = z(4)**2 * (1.d0 - z(5)**2) / bmod

i.e. v_perp^2 / B_local evaluated at each particle's starting point.

The two are not on the same scale. The boundary curves assume J_perp
is normalized so that a deeply-trapped particle at the surface bmin has
J_perp = bmin_global / bmin(s), but the per-particle quantity is
absolute v_perp^2 / B_local (or some other Fortran-side convention).
A global rescale by bmin_global is missing on one side, or the two
quantities are being computed against different references entirely.

The asymmetry across configs is consistent with this hypothesis: the
mismatch is largest where bmin(s) varies most across surfaces (QI),
smallest where the variation is mild (QH).

What to fix

Pick one canonical normalization and use it on both sides:

  • Either change plot_volume_classification to draw the boundaries
    using the same reference field as perp_inv (e.g. drop the
    bmin_global factor and use a normalization derived from each
    particle's own bmod), or
  • Change classification.f90 to write a normalized perp_inv that
    matches the bmin_global / bmin(s) convention used by the plot.

Either way, document the convention in a one-line comment next to
perp_inv = ... in classification.f90 and next to the boundary
plot lines so the two stay in sync.

Test

Regenerate the three volume plots from
examples/classification/configs/{qi,qh,qa}_volume.in after the fix
and verify that the dashed (deeply-trapped) and solid (trapped-passing)
curves enclose the non-NaN pixel region in all three cases.

Context

References

  • examples/classification/plot_paper_results.pyplot_volume_classification
  • src/classification.f90 — line ~154, perp_inv definition
  • examples/classification/configs/{qi,qh,qa}_volume.in

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions