Docs

The method was developed in 09W3 (W in RMP) and generalized to every species in
09W4. Call it with analyze_shot(shot), Shot.analyze_injections() or
GroupShots.analyze_injections().

Steps

  1. Signal: shot.emission(shot.default_signal), the core line with its
    physical sign.
  2. Detection, with find_injections(shot).
    • The scan_injections sweep looks for rises of the smoothed signal (5 pts)
      over 30 ms that exceed k=8 sigma (MAD).
    • Events near a -lboN.txt (−80/+200 ms) get source="lbo file".
    • An unlisted event gets source="detected" if
      z >= max(z_strong=30, z_rel=0.2 * z_max_listado), or if it falls on the
      shot's firing grid (grid_period=1 s, same phase ±30 ms as the listed
      ones, and only when those have a consistent phase).
    • extra_times=[...] and exclude_times=[...] correct by hand.
    • The full sweep is kept in df.attrs["candidates"].
  3. Characterization, with characterize_injection(t, y, t_ref): peak (smoothed
    maximum in −80/+200 ms), baseline and noise (100 ms before the onset,
    iterated), onset (last point below baseline + 4σ/√3), amplitude, SNR,
    t_onset_to_peak_ms and t_rise_10_90_ms.
  4. Decay window, with decay_end: from the peak to t_peak + t_max
    (DECAY_T_MAX: W 0.45 s; Fe/Ni/Mo 0.6 s). It is cut 50 ms before the next
    injection or an ECRH step (heating_steps), and at the end of the data.
  5. Normalized curve, with decay_curve: tr = t − t_peak,
    yn = (I − baseline)/A. It never includes the rise.
  6. Fits (aug.models.exponential):
    • fit_single_exp: a·exp(−t/τ) + b.
    • fit_double_exp: a_f·exp(−t/τ_f) + a_s·exp(−t/τ_s) + b, multi-start,
      τ_f ∈ [6, 60] ms. τ_imp = τ_s. The fit is identifiable if each
      amplitude is ≥ 0.1, τ_s > 1.5 τ_f, τ_f is not at its bound,
      σ(τ_s) < 50 % and τ_s < 0.75 × the window.
    • select_decay_model picks "double" only if the F-test gives p < 0.05,
      ΔAIC > 2, and the fit is identifiable.
    • block_bootstrap_tau estimates the error of τ (single) with a
      moving-block bootstrap of the residuals (blocks of 10 samples).
    • fit_rise_decay: a rise + decay model, as a check (τ_r and τ_d come out
      correlated).
  7. Window sensitivity: single τ with the start at peak + {0, 10, 20, 40} ms
    and length {⅔, 1, 4/3}·t_max. This gives tau_sys_ms (p16-p84
    half-range).
  8. Context, with plasma_context: P_ECRH_MW, P_NBI_MW, Te_c_keV,
    ne_1e19, Wmhd_kJ, Ip_MA, Zeff; elm_rate (peaks of Ipolsola);
    dFe23_sigma (change in Fe23+ during the window, for non-Fe shots).
  9. Flags (FLAGS). clean means no flags.

Adopted τ

Flags

Flag Condition
ECRH_step ECRH step < 150 ms before the onset
Fe_influx Fe23+ rises > 5σ during the window (species ≠ Fe only)
no_decay single-fit R² < 0.5
low_snr amplitude < 5σ
ELMy > 10 ELMs/s during the decay (RMP regime only)
window_sensitive tau_sys_ms > 30 % of τ
short_window window < 100 ms or shorter than τ
fit_failed a fit did not converge, or there are < 10 points

InjectionSet

res = group.analyze_injections()
res.table                       # DataFrame, una fila por inyección
res.details[(shot, inj)]        # dict: t, y, char, t_end, tr, yn, model, rd, boot, sens
res_a + res_b                   # concatena

Main columns of res.table: dataset, regime, species, heating, signal, shot, inj, source, t_ref, t_onset, t_peak, snr, t_onset_to_peak_ms, t_rise_10_90_ms, tau_rise_ms, window_ms, tau_1exp_ms, tau_1exp_err_ms, tau_1exp_err_boot_ms, tau_sys_ms, r2_1exp, tau_slow_2exp_ms, tau_slow_2exp_err_ms, tau_fast_2exp_ms, a_fast, a_slow, identifiable_2exp, p_F, dAIC, recommended, tau_imp_ms, tau_imp_err_ms, P_ECRH_MW, P_NBI_MW, Te_c_keV, ne_1e19, Ip_MA, elm_rate_decay_Hz, dFe23_sigma, <flags>, clean, flags.