Process reference: impa

Generated from the docstrings of vaft.process.impa: 14 public functions. Each entry is what vaft.process.describe("impa.<name>") prints. All process categories

Overview

The array is an insertable midplane probe carrying, at each of eight radial positions, a toroidal-field Hall sensor and a vertical-field sensor. The radial-field sensors are retired: the original design used them only to confirm the probe sat at the midplane, where the radial field is negligible.

The two sets play different roles [1]:

  • the Hall channels establish where the array is. The toroidal field goes as one over the major radius, so measuring it against the known coil current gives each sensor’s radius, and the fitted spacing against the rigid as-built pitch gives the probe’s incident angle.
  • they also establish how each vertical sensor is aligned. On an interval driven by the toroidal field alone the true vertical field is negligible, so whatever the vertical sensor reads there is crosstalk, and its ratio to the measured toroidal field is that sensor’s misalignment.
  • the vertical sensors, once corrected for that crosstalk, carry the physics measurement: the toroidal current density from the radial gradient of the vertical field at the midplane.

Every routine here works on plain arrays, so the machine-specific parts – raw field codes, shot-era geometry and thresholds – stay in vaft.machine_mapping.impa and vest.yaml.

SymbolMeaningUnit
B_measfield a probe actually measuresT
Btvacuum toroidal field at a radius, mu0 N I / (2 pi R)T
Bzvertical field, after compensationT
alphaprobe coupling to the toroidal field, sin of its tilt-
betaper-probe offsetT
kappathe observable ratio alpha / R1/m
R0major radius of the innermost channelm
I_TFtoroidal field coil currentA

The measurement model. Each probe sees a mixture of the local poloidal field and the toroidal field::

B_meas_i(t) = alpha_i * Bt(R_i, t) + Bz_i(t) * sqrt(1 - alpha_i**2) + beta_i

Inverting it gives the compensated internal field::

Bz_i = (B_meas_i - alpha_i * Bt(R_i)) / sqrt(1 - alpha_i**2)

Sign. VAFT takes the coil current as the raw field times -3e4, as vaft.machine_mapping.tf already does, together with a Hall gain of -2/15 T/V. That is the “Data gain” on the array’s own wiring datasheet, the authoritative hardware configuration, and it matches neither legacy script exactly [2]. All three pairings give the same ratio of measured to toroidal field up to an overall sign, so the fits here are sign-agnostic: they detect the working polarity from the data rather than assuming a positive coupling, and only the magnitude of the coupling carries physical meaning. The shipped default carries that sign since #681 closed #624.

The datasheet leaves the vertical sensors’ own volts-to-tesla gain unspecified, so those waveforms stay in native volts throughout; see ImpaCrosstalkFit for what that means for the crosstalk angle.

Geometry and coupling are degenerate. During a toroidal-field-only interval that field is the only driver, so a probe measures alpha_i * mu0 * N * I_TF / (2 * pi * R_i) and only the ratio kappa_i = alpha_i / R_i is observable. Assuming unit coupling yields the radial position, which is the legacy method; a known radius yields the coupling instead. The two cannot be recovered together from that data alone.

Geometry is per shot. The array is insertable and its radial position is set per shot, so self-calibration from the shot’s own clean window is the primary geometry source, not a fallback, and comparing fitted positions between shots is meaningless because the probe really did move. A configured radius in vest.yaml applies only to an era where the array was surveyed or left fixed, and then takes precedence. A reference shot taken with the array in the same position can supply the calibration for another, which is the legacy two-shot arrangement; the single-shot path never requires it.

Functions

find_tf_calibration_windowFind the interval where the toroidal field alone drives the probes. Convention
fit_impa_crosstalkFit the toroidal-field bleed into each vertical sensor. Convention
fit_impa_geometrySelf-calibrate the array’s radial position from the toroidal-field profile. Convention
fit_impa_tf_couplingFit each probe’s coupling to the toroidal field, at known radii. Convention
grade_impa_qualityGrade whether an array’s measurements can be trusted, and say why not. Convention
impa_calibrate_signalsFilter, scale and baseline raw probe records into field units. Convention
impa_lowpassZero-phase low pass reproducing the legacy filter design. Convention
legacy_impa_compensationFaithful port of the legacy compensation script, at one time sample. Convention
legacy_impa_positionFaithful port of the legacy position script, at one time sample. Convention
process_impaRun the whole array chain for one shot, from raw records to a graded result. Convention
remove_bz_crosstalkSubtract a vertical sensor’s toroidal crosstalk. Convention
remove_tf_pickupRecover the vertical field by removing a probe’s toroidal pickup. Convention
toroidal_fieldVacuum toroidal field at a radius, from the coil current. Convention
validate_impaDeprecated compatibility wrapper for grade_impa_quality. Deprecated

find_tf_calibration_window

Machine-independentConvention-sensitive source
find_tf_calibration_window(time, i_tf, ip=None, pf_currents=None, *, criteria=None, b_measured=None)

Find the interval where the toroidal field alone drives the probes.

Calibration needs a stretch of the same shot in which the coil is energised and nothing else is: no plasma current, no poloidal field. That interval is what makes the geometry and coupling fits meaningful, so this reports why it chose the one it did.

NameTypeUnitDescription
timearray_likes

Sample times.

i_tfarray_likeA

Toroidal field coil current.

iparray_like, optionalA

Plasma current, used to exclude the discharge.

pf_currentsarray_like, optionalA

Poloidal field coil currents as (n_coils, n_samples).

criteriaTfWindowCriteria, optional-

Thresholds the interval must satisfy.

b_measuredarray_like, optionalT

Conditioned probe records, used to require finite channels.

Returns
—tuple-

The chosen TfCalibrationWindow with its metrics, and a tuple of reason strings recording what was applied and why.

Convention

The chosen interval is the best-conditioned one, meaning the widest spread in coil current, rather than the longest. A long interval at nearly constant current constrains the fit poorly however many samples it holds, because the fit is a regression against that current.

Both an absolute floor and a fraction of the shot’s own peak are applied, because a shot can be energised weakly overall while still having a usable interval, and a fixed floor alone would either reject it or admit noise on a strong shot.

Processing steps · Defaults · Applicability · Limitations · Provenance

Processing steps

  1. Validate the time axis.
  2. Require the coil current above an absolute floor and above a fraction of the shot’s own peak.
  3. Exclude samples where the plasma current or any poloidal coil exceeds its limit, on median-filtered traces.
  4. Require every probe channel finite.
  5. Group what survives into contiguous runs and drop the too-short ones.
  6. Choose among the survivors by conditioning, not length.

Defaults

The thresholds are hard-coded: an absolute current floor, a fraction of peak, plasma and poloidal current limits, a minimum duration and a dynamic-range floor. The fraction of peak is a validated-workflow value distinguishing the reference shots from a weakly energised one; the rest have no recorded derivation. The median-filter width is an acquisition-era value, one millisecond at the array’s own rate. One configured threshold, the relative noise limit, is read by nothing at all, which is tracked in #625.

Applicability

Machine-independent. The thresholds arrive as an argument.

Limitations

Reasons are returned rather than raised, so a caller must read them: a window can be chosen and still be poor. Without the optional currents the corresponding exclusions simply do not happen, and an interval containing plasma can be selected.

Provenance

  1. vest.yaml impa.calibration_window, which carries the VEST thresholds and the evidence for the fraction-of-peak value.

fit_impa_crosstalk

Machine-independentConvention-sensitive source
fit_impa_crosstalk(b_toroidal, b_z_raw, window, *, max_angle_deg=30.0, bz_gain=None)

Fit the toroidal-field bleed into each vertical sensor.

On an interval driven by the toroidal field alone the true vertical field is negligible, so whatever a vertical sensor reads there is crosstalk. Its ratio to the measured toroidal field is that sensor’s misalignment.

NameTypeUnitDescription
b_toroidalarray_likeT

Toroidal field at each sensor.

b_z_rawarray_likeV

Raw vertical-sensor records, in native units.

windowTfCalibrationWindow-

The toroidal-field-only interval.

max_angle_degfloat, optionaldeg

Largest misalignment still treated as physical.

bz_gainfloat, optionalT/V

Volts-to-tesla gain for the vertical sensors, if known.

Returns
—ImpaCrosstalkFit-

Per-sensor slope, offset and goodness of fit; the misalignment angle only when a gain was supplied.

Convention

The slope is volts per tesla, not a dimensionless projection, because the wiring datasheet leaves the vertical sensors’ gain unspecified and those waveforms stay in volts. Without a gain the angle cannot be formed and is returned as NaN rather than silently wrong.

Defaults · Applicability · Limitations · Provenance

Defaults

The maximum angle is hard-coded with no recorded derivation.

Applicability

Machine-independent.

Limitations

Rests on the vertical field being negligible over the window, which is what makes the window selection load-bearing. A linear fit only: a sensor responding non-linearly keeps a residual.

Provenance

  1. Yang et al., Rev. Sci. Instrum. 85, 11D809 (2014), for the alignment role of the two sensor sets; vest.yaml impa.crosstalk for the configured thresholds.

fit_impa_geometry

Machine-independentConvention-sensitive source
fit_impa_geometry(b_measured, i_tf, window, *, pitch=0.05, z=0.0, turns=24, r0_initial=0.4, r_bounds=(0.1, 0.9), fit_pitch=False)

Self-calibrate the array’s radial position from the toroidal-field profile.

NameTypeUnitDescription
b_measuredarray_likeT

Conditioned probe records as (n_channels, n_samples).

i_tfarray_likeA

Toroidal field coil current.

windowTfCalibrationWindow-

The interval to fit over.

pitchfloat, optionalm

As-built spacing between channels.

zfloat, optionalm

Height of the array.

turnsint, optional-

Coil turns.

r0_initialfloat, optionalm

Starting guess for the innermost channel’s radius.

r_boundstuple of float, optionalm

Bounds on that radius.

fit_pitchbool, optional-

Whether to fit the spacing as well as the position.

Returns
—ImpaGeometryFit-

The fitted radii, the spacing, the incident angle and the residual statistics.

Convention

This is the half of the degeneracy that assuming unit coupling resolves, which is the legacy method: a rigid array of known spacing is slid along the one-over-radius profile until it matches. The other half is fit_impa_tf_coupling.

The coupling sign is detected, not assumed. The measured sign follows the configured Hall gain’s polarity, which this function has no reason to know. An incident angle of zero is a purely radial insertion in the midplane.

Processing steps · Defaults · Applicability · Limitations · Provenance

Processing steps

  1. Keep the channels finite across the window.
  2. Detect the working polarity from the data.
  3. Solve a bounded least squares for the innermost radius, and the spacing when asked.
  4. Form the residual and its normalized form.
  5. Recover the incident angle from the ratio of fitted to as-built spacing.

Defaults

The spacing is machine-specific, the array’s rigid as-built value. The starting guess and the radial bounds are machine-specific too, spanning the vessel. turns = 24 is the VEST coil.

Applicability

Machine-independent. Every machine number is an argument.

Limitations

Assumes the array is rigid and the coupling uniform, so a fitted position is meaningful only where the residual is small; the reference shots sit at 9 to 12 percent and the rejected ones at 34 to 35. Positions are not comparable between shots, because the array is insertable and really is repositioned.

Provenance

  1. The vest_impa_position model: uniform channel spacing and unit coupling, reproduced faithfully by legacy_impa_position.

fit_impa_tf_coupling

Machine-independentConvention-sensitive source
fit_impa_tf_coupling(b_measured, i_tf, r, window, *, turns=24, tilt_bounds_deg=(-10.0, 10.0))

Fit each probe’s coupling to the toroidal field, at known radii.

NameTypeUnitDescription
b_measuredarray_likeT

Conditioned probe records as (n_channels, n_samples).

i_tfarray_likeA

Toroidal field coil current.

rarray_likem

Major radius of each probe.

windowTfCalibrationWindow-

The interval to regress over.

turnsint, optional-

Coil turns.

tilt_bounds_degtuple of float, optionaldeg

Bounds on the probe tilt.

Returns
—ImpaCouplingFit-

Per-channel coupling and offset with their residual statistics.

Convention

Regresses the measured field on the modelled toroidal field at the known radius, giving the coupling as slope and the offset as intercept. This is the half of the degeneracy that a known radius resolves; see fit_impa_geometry for the other half. Only the magnitude of the coupling carries meaning, since its sign follows the calibration polarity.

Defaults · Applicability · Limitations · Provenance

Defaults

turns = 24 is machine-specific. The tilt bounds are a legacy compatibility value from a model that assumed a near-vertical probe, and they saturate on an array that faces the toroidal field, which is the reference condition here.

Applicability

Machine-independent.

Limitations

Needs the radii, which on this array are usually themselves fitted, so the two must not be circular. The tilt bounds saturating is a signal that the model does not fit the array, not a result to use.

Provenance

  1. The measurement model in this module’s conventions.

grade_impa_quality

Machine-independentConvention-sensitive source
grade_impa_quality(time, raw, b_measured, b_z, channel_valid, window, geometry, coupling, *, expected_channels=8, max_normalized_rmse=0.15, r_bounds=(0.1, 0.9), pitch_tolerance=0.01, window_reasons=(), orientation='toroidal', alpha_tolerance=0.15, crosstalk=None, min_crosstalk_r_squared=0.8)

Grade whether an array’s measurements can be trusted, and say why not.

NameTypeUnitDescription
timearray_likes

Sample times.

rawarray_likeV

Raw probe records.

b_measuredarray_likeT

Conditioned probe records.

b_zarray_likeT

Compensated vertical field.

channel_validarray_like-

Which channels to consider.

windowTfCalibrationWindow-

The calibration interval that was used.

geometryImpaGeometryFit-

The fitted geometry.

couplingImpaCouplingFit-

The fitted coupling.

expected_channelsint, optional-

How many channels the array should have.

max_normalized_rmsefloat, optional-

Largest geometry residual still acceptable.

r_boundstuple of float, optionalm

Radial bounds the fit should sit inside.

pitch_tolerancefloat, optionalm

Largest departure of fitted from as-built spacing.

window_reasonssequence of str, optional-

Reasons carried from the window selection.

orientationstr, optional-

Which field the array is taken to face.

alpha_tolerancefloat, optional-

Largest departure of the coupling from unity.

crosstalkImpaCrosstalkFit, optional-

The crosstalk fit, when one was made.

min_crosstalk_r_squaredfloat, optional-

Smallest acceptable crosstalk goodness of fit.

Returns
—ImpaQuality-

A verdict of valid, warning or invalid, with the reasons behind it.

Convention

The verdict is the worst of the checks, not an average, so one invalid check makes the result invalid however many pass. Reasons accumulate rather than short-circuiting, so a caller sees everything wrong at once.

Renamed from validate_impa under issue #337: this layer transforms and infers, and grading sits uneasily here even so. The grading itself moves to the validation layer under issue #339.

Processing steps · Defaults · Applicability · Limitations · Provenance

Processing steps

  1. Check the channels are present and the time axis usable.
  2. Check each channel’s own signal health, including railing.
  3. Check the calibration window, then the geometry, then the coupling.
  4. Check the compensated signal and the vertical sensors.
  5. Combine by taking the worst verdict.

Defaults

The residual, spacing, coupling and goodness-of-fit thresholds are hard-coded, and two of them disagree with the values vest.yaml carries, which is tracked in #625. The channel count and the radial bounds are machine-specific.

Applicability

Machine-independent. Every threshold arrives as an argument.

Limitations

Grades the fits it is handed; it cannot tell a well-fitted wrong model from a right one. A shot whose array faces the toroidal field can pass the geometry checks and still have no usable vertical measurement.

Provenance

  1. Issues #337 and #339 for the naming and the eventual move; vest.yaml impa.quality for the configured thresholds.

impa_calibrate_signals

Machine-independentConvention-sensitive source
impa_calibrate_signals(raw, *, gain, cutoff_hz, sample_rate, baseline='first_sample', baseline_samples=2500)
Show source vaft/process/impa.py, lines 404–471
def impa_calibrate_signals(
    raw: np.ndarray,
    *,
    gain: float,
    cutoff_hz: float,
    sample_rate: float,
    baseline: str = "first_sample",
    baseline_samples: int = 2_500,
) -> np.ndarray:
    """Filter, scale and baseline raw probe records into field units.

    Parameters
    ----------
    raw : array_like
        Raw digitizer records as ``(n_channels, n_samples)`` [V].
    gain : float
        Hall calibration factor [T/V].
    cutoff_hz : float
        Conditioning low-pass cut-off [Hz].
    sample_rate : float
        Sample rate [Hz].
    baseline : str, optional
        Which baseline to remove [-].
    baseline_samples : int, optional
        Leading samples used when the baseline is a mean [-].

    Returns
    -------
    np.ndarray
        Conditioned records in field units [T].

    Processing steps
    ----------------
    1. Low-pass each channel.
    2. Multiply by the calibration factor.
    3. Remove the baseline.

    Convention
    ----------
    **The stage order is the donor's**, low pass then gain then baseline, and it
    is not interchangeable: removing a baseline before filtering leaves the
    filter's transient riding on a different level.

    The sign of the calibration factor is the caller's, and the fits downstream
    are deliberately sign-agnostic; see the module's conventions and #624.

    Defaults
    --------
    ``baseline_samples = 2500`` is an acquisition-era value, the leading interval
    that precedes the discharge at the array's own sample rate. It is a sample
    count, so it means a different duration at a different rate.

    Applicability
    -------------
    Machine-independent.

    Limitations
    -----------
    Assumes the leading window is field-free. Inherits the record-length caveat
    of :func:`impa_lowpass`.

    Provenance
    ----------
    .. [1] ``VEST_IMPAProcessing.m``, whose stage order this follows.
    """
    raw = np.atleast_2d(np.asarray(raw, dtype=float))
    filtered = impa_lowpass(raw, cutoff_hz, sample_rate) * float(gain)
    return _apply_baseline(filtered, baseline, baseline_samples)

Filter, scale and baseline raw probe records into field units.

NameTypeUnitDescription
rawarray_likeV

Raw digitizer records as (n_channels, n_samples).

gainfloatT/V

Hall calibration factor.

cutoff_hzfloatHz

Conditioning low-pass cut-off.

sample_ratefloatHz

Sample rate.

baselinestr, optional-

Which baseline to remove.

baseline_samplesint, optional-

Leading samples used when the baseline is a mean.

Returns
—np.ndarrayT

Conditioned records in field units.

Convention

The stage order is the donor’s, low pass then gain then baseline, and it is not interchangeable: removing a baseline before filtering leaves the filter’s transient riding on a different level.

The sign of the calibration factor is the caller’s, and the fits downstream are deliberately sign-agnostic; see the module’s conventions and #624.

Processing steps · Defaults · Applicability · Limitations · Provenance

Processing steps

  1. Low-pass each channel.
  2. Multiply by the calibration factor.
  3. Remove the baseline.

Defaults

baseline_samples = 2500 is an acquisition-era value, the leading interval that precedes the discharge at the array’s own sample rate. It is a sample count, so it means a different duration at a different rate.

Applicability

Machine-independent.

Limitations

Assumes the leading window is field-free. Inherits the record-length caveat of impa_lowpass.

Provenance

  1. VEST_IMPAProcessing.m, whose stage order this follows.

impa_lowpass

Machine-independentConvention-sensitive source
impa_lowpass(values, cutoff_hz, sample_rate)
Show source vaft/process/impa.py, lines 341–392
def impa_lowpass(values: np.ndarray, cutoff_hz: float, sample_rate: float) -> np.ndarray:
    """Zero-phase low pass reproducing the legacy filter design.

    Parameters
    ----------
    values : array_like
        Waveform or stack of them; the sample axis is the last [any].
    cutoff_hz : float
        Cut-off frequency [Hz].
    sample_rate : float
        Sample rate [Hz].

    Returns
    -------
    np.ndarray
        The filtered waveform, same shape [any].

    Convention
    ----------
    **Zero phase where it can be.**  The forward-backward filter moves no feature
    in time, which matters because the array's channels are compared against each
    other and against the coil current.  A record too short for the padding that
    needs falls back to a single forward pass, which is causal and therefore
    delays every feature; the convention silently changes with record length, and
    only tiny synthetic records are short enough for it.

    Defaults
    --------
    The tap count is a legacy compatibility value: the donor design is a
    Hamming-window filter whose order follows from the sample rate, giving the
    same 26 taps this uses.

    Applicability
    -------------
    Machine-independent.

    Limitations
    -----------
    The fallback above is the one case where the phase convention is not what the
    summary says.

    Provenance
    ----------
    .. [1] The legacy ``vest_filter`` design, whose window, order and
       forward-backward application this reproduces.
    """
    values = np.asarray(values, dtype=float)
    taps = signal.firwin(_FIR_TAPS, cutoff_hz, pass_zero="lowpass", fs=sample_rate)
    # The shared length rule; this check used to stop three samples short (#893).
    if values.shape[-1] >= _filtfilt_min_length(taps.size):
        return signal.filtfilt(taps, 1, values, axis=-1)
    return signal.lfilter(taps, 1, values, axis=-1)

Zero-phase low pass reproducing the legacy filter design.

NameTypeUnitDescription
valuesarray_likeany

Waveform or stack of them; the sample axis is the last.

cutoff_hzfloatHz

Cut-off frequency.

sample_ratefloatHz

Sample rate.

Returns
—np.ndarrayany

The filtered waveform, same shape.

Convention

Zero phase where it can be. The forward-backward filter moves no feature in time, which matters because the array’s channels are compared against each other and against the coil current. A record too short for the padding that needs falls back to a single forward pass, which is causal and therefore delays every feature; the convention silently changes with record length, and only tiny synthetic records are short enough for it.

Defaults · Applicability · Limitations · Provenance

Defaults

The tap count is a legacy compatibility value: the donor design is a Hamming-window filter whose order follows from the sample rate, giving the same 26 taps this uses.

Applicability

Machine-independent.

Limitations

The fallback above is the one case where the phase convention is not what the summary says.

Provenance

  1. The legacy vest_filter design, whose window, order and forward-backward application this reproduces.

legacy_impa_compensation

VEST-specificConvention-sensitive source
legacy_impa_compensation(time, raw, tf_raw, r, *, target_time=0.29, sample_rate=25000.0, cutoff_hz=250.0, gain=-0.13333333333333333, tf_gain=30000.0, turns=24, tilt_bounds_deg=(-10.0, 10.0))

Faithful port of the legacy compensation script, at one time sample.

Kept for comparison against the donor, not as the maintained path; the current chain is fit_impa_tf_coupling with remove_tf_pickup.

NameTypeUnitDescription
timearray_likes

Sample times.

rawarray_likeV

Raw probe records as (n_channels, n_samples).

tf_rawarray_likeV

Raw toroidal-field coil trace.

rarray_likem

Major radius of each probe.

target_timefloat, optionals

The single sample the fit is evaluated at.

sample_ratefloat, optionalHz

Sample rate.

cutoff_hzfloat, optionalHz

Conditioning low-pass cut-off.

gainfloat, optionalT/V

Hall calibration factor.

tf_gainfloat, optionalA/V

Raw-to-amperes factor for the coil trace.

turnsint, optional-

Coil turns.

tilt_bounds_degtuple of float, optionaldeg

Bounds on the probe tilt.

Returns
—ImpaCouplingFit-

The per-channel coupling and the compensated field at that sample.

Convention

The donor’s order, which differs from the position script’s: here the low pass comes before the gain, and both traces are offset-corrected. The sign pairing is also the donor’s, a negative gain with a positive coil factor, the mirror of the other script. Both are reproduced rather than harmonized.

Processing steps · Defaults · Applicability · Limitations · Provenance

Processing steps

  1. Low-pass each probe, apply the gain, subtract the first sample.
  2. Low-pass the coil trace and subtract its first sample.
  3. Take the sample nearest the target time.
  4. Solve a bounded tilt per channel, build the pickup, and divide it out.

Defaults

Every default is a legacy compatibility value from the donor script, including its evaluation time, which differs from the position script’s.

Applicability

VEST-specific. A port of a VEST script carrying that machine’s coil factor, sample rate and calibration as defaults, reproducing one historical routine rather than a general method.

Limitations

One time sample only. The donor also processed a reference shot through the same path; that branch is deliberately absent here, so this is the single-shot half of the original. The tilt model assumes a near-vertical probe and saturates on an array that faces the toroidal field.

Provenance

  1. VEST_IMPAProcessing.m, ported faithfully including its stage order and its sign pairing; the omitted reference-shot branch is noted above.

legacy_impa_position

VEST-specificConvention-sensitive source
legacy_impa_position(time, raw, tf_raw, *, target_time=0.3, sample_rate=25000.0, cutoff_hz=2500.0, gain=0.13333333333333333, tf_gain=-30000.0, turns=24, pitch=0.05, r0_initial=0.4, r_bounds=(0.1, 0.9), baseline_samples=2500)

Faithful port of the legacy position script, at one time sample.

Kept so the current chain can be compared against what the donor actually did, not so it can be used in preference; fit_impa_geometry is the maintained path.

NameTypeUnitDescription
timearray_likes

Sample times.

rawarray_likeV

Raw probe records as (n_channels, n_samples).

tf_rawarray_likeV

Raw toroidal-field coil trace.

target_timefloat, optionals

The single sample the fit is evaluated at.

sample_ratefloat, optionalHz

Sample rate.

cutoff_hzfloat, optionalHz

Conditioning low-pass cut-off.

gainfloat, optionalT/V

Hall calibration factor.

tf_gainfloat, optionalA/V

Raw-to-amperes factor for the coil trace.

turnsint, optional-

Coil turns.

pitchfloat, optionalm

As-built channel spacing.

r0_initialfloat, optionalm

Starting guess for the innermost radius.

r_boundstuple of float, optionalm

Bounds on that radius.

baseline_samplesint, optional-

Leading samples forming the baseline.

Returns
—ImpaGeometryFit-

The fitted radii and spacing at that one sample.

Convention

The donor’s order, kept deliberately, including the asymmetry that the coil trace is not offset-corrected while the probes are. The sign pairing is the donor’s too, a positive gain with a negative coil factor, which differs from both the datasheet and the other legacy script; see the module’s conventions.

Processing steps · Defaults · Applicability · Limitations · Provenance

Processing steps

  1. Subtract each probe’s first sample, apply the gain, low-pass, then subtract the mean of the leading samples.
  2. Condition the coil trace with gain and low pass, without removing any offset.
  3. Take the sample nearest the target time.
  4. Solve the bounded least squares for the innermost radius.

Defaults

Every default here is a legacy compatibility value reproducing the donor script: its single evaluation time, its sample rate, its cut-off, its two gains and its baseline length.

Applicability

VEST-specific. A port of a VEST script, carrying that machine’s coil factor, sample rate and array spacing as its defaults; it reproduces one historical routine rather than describing a general method.

Limitations

One time sample, not a time series, and no residual quality reported. It assumes unit coupling, which the reference shots show is nearly true and the rejected shots show is not.

Provenance

  1. vest_impa_position.m, ported faithfully including its stage order and its sign pairing.

process_impa

Machine-independentConvention-sensitive source
process_impa(time, raw, i_tf, *, config=None, criteria=None, ip=None, pf_currents=None, channel_valid=None, r=None, z=0.0, pitch=0.05, r_bounds=(0.1, 0.9), r0_initial=0.4, max_normalized_rmse=0.15, reference=None, b_z_raw=None, bz_channel_valid=None, fit_pitch=False, max_crosstalk_angle_deg=30.0, min_crosstalk_r_squared=0.8, bz_gain=None, bz_radial_offset=0.01)

Run the whole array chain for one shot, from raw records to a graded result.

NameTypeUnitDescription
timearray_likes

Sample times.

rawarray_likeV

Raw probe records as (n_channels, n_samples).

i_tfarray_likeA

Toroidal field coil current.

configImpaProcessingConfig, optional-

Conditioning settings.

criteriaTfWindowCriteria, optional-

Window-selection thresholds.

iparray_like, optionalA

Plasma current.

pf_currentsarray_like, optionalA

Poloidal field coil currents.

channel_validarray_like, optional-

Which probe channels to use.

rarray_like, optionalm

Configured radii, which take precedence when supplied.

zfloat, optionalm

Height of the array.

pitchfloat, optionalm

As-built channel spacing.

r_boundstuple of float, optionalm

Bounds on the fitted radius.

r0_initialfloat, optionalm

Starting guess for it.

max_normalized_rmsefloat, optional-

Largest acceptable geometry residual.

referenceMapping, optional-

A reference shot supplying the calibration instead of this shot’s own.

b_z_rawarray_like, optionalV

Raw vertical-sensor records.

bz_channel_validarray_like, optional-

Which vertical sensors to use.

fit_pitchbool, optional-

Whether to fit the spacing too.

max_crosstalk_angle_degfloat, optionaldeg

Largest misalignment treated as physical.

min_crosstalk_r_squaredfloat, optional-

Smallest acceptable crosstalk goodness of fit.

bz_gainfloat, optionalT/V

Volts-to-tesla gain for the vertical sensors.

bz_radial_offsetfloat, optionalm

Radial offset of the vertical sensors from their Hall neighbours.

Returns
—ImpaResult-

The conditioned fields, the geometry and coupling, the compensated vertical field, the quality verdict, and a provenance record.

Convention

Geometry precedence is deliberate and ordered. Self-calibration from the shot’s own window is the primary source, not a fallback, because the array is insertable and its position is a per-shot quantity. A configured radius wins only where an era was surveyed or left fixed.

The vertical sensors are not co-located with the Hall channel of the same index; the offset is a hardware fact supplied by the caller.

Processing steps · Defaults · Applicability · Limitations · Provenance

Processing steps

  1. Condition the raw records into field units.
  2. Mask the invalid channels.
  3. Find the interval driven by the toroidal field alone.
  4. Resolve the geometry by precedence: a reference shot, then a configured radius, then a fit on this shot’s own window, then the nominal uncalibrated positions.
  5. Resolve the coupling, from the reference if there is one, else by fitting.
  6. Remove the toroidal pickup, branching on the array’s orientation.
  7. Optionally fit and remove the vertical sensors’ crosstalk.
  8. Grade the result and record what was used.

Defaults

The spacing, bounds, starting guess and channel count are machine-specific VEST values. The residual threshold and the radial offset disagree with what vest.yaml carries, which is tracked in #625; the VEST pipeline passes the configured values, so the disagreement bites only a direct caller.

Applicability

Machine-independent. Every machine number is an argument, and the VEST pipeline supplies them from configuration.

Limitations

Inherits every assumption of the steps it orchestrates, above all that the selected window is genuinely driven by the toroidal field alone. A shot whose array faces that field yields a compensated vertical field that is not a measurement, which the grading flags rather than the chain refusing.

Provenance

  1. The stages this orchestrates, each documented on its own function; vest.yaml impa for the configuration the VEST pipeline passes in.

remove_bz_crosstalk

Machine-independentConvention-sensitive source
remove_bz_crosstalk(b_z_raw, b_toroidal, crosstalk)
Show source vaft/process/impa.py, lines 1157–1210
def remove_bz_crosstalk(
    b_z_raw: np.ndarray,
    b_toroidal: np.ndarray,
    crosstalk: ImpaCrosstalkFit,
) -> np.ndarray:
    """Subtract a vertical sensor's toroidal crosstalk.

    Parameters
    ----------
    b_z_raw : array_like
        Raw vertical-sensor records, in the sensor's native units [V].
    b_toroidal : array_like
        The toroidal field at each sensor [T].
    crosstalk : ImpaCrosstalkFit
        The fitted per-sensor slope and offset [-].

    Returns
    -------
    np.ndarray
        The records with the crosstalk removed, still in native units [V].

    Convention
    ----------
    **The output stays in volts.**  The wiring datasheet leaves the vertical
    sensors' volts-to-tesla gain unspecified, so nothing here converts them; the
    fitted slope is therefore volts per tesla rather than a dimensionless
    projection.

    Applicability
    -------------
    Machine-independent.

    Limitations
    -----------
    Removes only the linear crosstalk the fit describes. A sensor whose response
    to the toroidal field is not linear keeps its residual.

    Provenance
    ----------
    .. [1] :func:`fit_impa_crosstalk`, which supplies the coefficients, and the
       wiring datasheet that leaves the vertical gain unspecified.
    """
    b_z_raw = np.atleast_2d(np.asarray(b_z_raw, dtype=float))
    b_toroidal = np.atleast_2d(np.asarray(b_toroidal, dtype=float))
    channels = min(b_z_raw.shape[0], b_toroidal.shape[0])
    corrected = np.full_like(b_z_raw, np.nan)
    for channel in range(channels):
        slope = crosstalk.slope_v_per_t[channel]
        if not np.isfinite(slope):
            continue
        corrected[channel] = (
            b_z_raw[channel] - slope * b_toroidal[channel] - crosstalk.offset[channel]
        )
    return corrected

Subtract a vertical sensor’s toroidal crosstalk.

NameTypeUnitDescription
b_z_rawarray_likeV

Raw vertical-sensor records, in the sensor’s native units.

b_toroidalarray_likeT

The toroidal field at each sensor.

crosstalkImpaCrosstalkFit-

The fitted per-sensor slope and offset.

Returns
—np.ndarrayV

The records with the crosstalk removed, still in native units.

Convention

The output stays in volts. The wiring datasheet leaves the vertical sensors’ volts-to-tesla gain unspecified, so nothing here converts them; the fitted slope is therefore volts per tesla rather than a dimensionless projection.

Applicability · Limitations · Provenance

Applicability

Machine-independent.

Limitations

Removes only the linear crosstalk the fit describes. A sensor whose response to the toroidal field is not linear keeps its residual.

Provenance

  1. fit_impa_crosstalk, which supplies the coefficients, and the wiring datasheet that leaves the vertical gain unspecified.

remove_tf_pickup

Machine-independentConvention-sensitive source
remove_tf_pickup(b_measured, tf_pickup, alpha)
Show source vaft/process/impa.py, lines 1213–1261
def remove_tf_pickup(b_measured: np.ndarray, tf_pickup: np.ndarray, alpha: np.ndarray) -> np.ndarray:
    """Recover the vertical field by removing a probe's toroidal pickup.

    Parameters
    ----------
    b_measured : array_like
        What the probe measured [T].
    tf_pickup : array_like
        The toroidal field at that probe [T].
    alpha : array_like
        The probe's coupling to the toroidal field [-].

    Returns
    -------
    np.ndarray
        The compensated vertical field, NaN where the probe is toroidally
        aligned [T].

    Convention
    ----------
    Inverts the measurement model: subtract the coupled toroidal part, then
    divide by the remaining poloidal sensitivity. A probe with unit coupling
    faces the toroidal field and has **no** sensitivity left for the vertical
    one, so the result is NaN rather than a division blowing up. That is not an
    edge case on this array: the reference shots put the coupling at 1.01 to
    1.045, which is exactly that condition.

    Applicability
    -------------
    Machine-independent.

    Limitations
    -----------
    The compensated field is only as good as the coupling it was given, and the
    division amplifies its error as the coupling approaches one. Trust the
    result only where the array is genuinely near-vertical.

    Provenance
    ----------
    .. [1] The measurement model in this module's conventions, of which this is
       the inversion.
    """
    b_measured = np.atleast_2d(np.asarray(b_measured, dtype=float))
    tf_pickup = np.atleast_2d(np.asarray(tf_pickup, dtype=float))
    alpha = np.asarray(alpha, dtype=float)
    with np.errstate(invalid="ignore", divide="ignore"):
        projection = np.sqrt(1.0 - np.clip(alpha, -1.0, 1.0) ** 2)
        projection = np.where(projection > 1e-3, projection, np.nan)
        return (b_measured - tf_pickup) / projection[:, None]

Recover the vertical field by removing a probe’s toroidal pickup.

NameTypeUnitDescription
b_measuredarray_likeT

What the probe measured.

tf_pickuparray_likeT

The toroidal field at that probe.

alphaarray_like-

The probe’s coupling to the toroidal field.

Returns
—np.ndarrayT

The compensated vertical field, NaN where the probe is toroidally aligned.

Convention

Inverts the measurement model: subtract the coupled toroidal part, then divide by the remaining poloidal sensitivity. A probe with unit coupling faces the toroidal field and has no sensitivity left for the vertical one, so the result is NaN rather than a division blowing up. That is not an edge case on this array: the reference shots put the coupling at 1.01 to 1.045, which is exactly that condition.

Applicability · Limitations · Provenance

Applicability

Machine-independent.

Limitations

The compensated field is only as good as the coupling it was given, and the division amplifies its error as the coupling approaches one. Trust the result only where the array is genuinely near-vertical.

Provenance

  1. The measurement model in this module’s conventions, of which this is the inversion.

toroidal_field

Machine-independentConvention-sensitive source
toroidal_field(r, i_tf, turns=24)
Show source vaft/process/impa.py, lines 474–520
def toroidal_field(r: np.ndarray | float, i_tf: np.ndarray | float, turns: int = 24) -> np.ndarray:
    """Vacuum toroidal field at a radius, from the coil current.

    Parameters
    ----------
    r : array_like
        Major radius, strictly positive [m].
    i_tf : array_like
        Toroidal field coil current [A].
    turns : int, optional
        Coil turns [-].

    Returns
    -------
    np.ndarray
        The vacuum toroidal field [T].

    Convention
    ----------
    ``mu0 * N * I / (2 * pi * R)``, the vacuum field of an ideal toroidal
    solenoid, so it carries the sign of the current as given. It is the field the
    array is calibrated against, not a measurement.

    Defaults
    --------
    ``turns = 24`` is machine-specific, the VEST toroidal field coil's turn count.
    A caller on another machine passes its own.

    Applicability
    -------------
    Machine-independent.  Only the default turn count is a VEST number.

    Limitations
    -----------
    Vacuum field only: it ignores the plasma's own diamagnetic or paramagnetic
    contribution, which is the assumption that makes a coil-driven interval usable
    for calibration in the first place.

    Provenance
    ----------
    .. [1] The ideal toroidal solenoid field; the same relation
       :mod:`vaft.machine_mapping.tf` uses for the coil current.
    """
    r_array = np.asarray(r, dtype=float)
    if np.any(r_array <= 0):
        raise ValueError("IMPA probe radii must be positive")
    return MU0 * int(turns) * np.asarray(i_tf, dtype=float) / (2.0 * math.pi * r_array)

Vacuum toroidal field at a radius, from the coil current.

NameTypeUnitDescription
rarray_likem

Major radius, strictly positive.

i_tfarray_likeA

Toroidal field coil current.

turnsint, optional-

Coil turns.

Returns
—np.ndarrayT

The vacuum toroidal field.

Convention

mu0 * N * I / (2 * pi * R), the vacuum field of an ideal toroidal solenoid, so it carries the sign of the current as given. It is the field the array is calibrated against, not a measurement.

Defaults · Applicability · Limitations · Provenance

Defaults

turns = 24 is machine-specific, the VEST toroidal field coil’s turn count. A caller on another machine passes its own.

Applicability

Machine-independent. Only the default turn count is a VEST number.

Limitations

Vacuum field only: it ignores the plasma’s own diamagnetic or paramagnetic contribution, which is the assumption that makes a coil-driven interval usable for calibration in the first place.

Provenance

  1. The ideal toroidal solenoid field; the same relation vaft.machine_mapping.tf uses for the coil current.

validate_impa

Deprecated source
validate_impa(*args, **kwargs)
Show source vaft/process/impa.py, lines 1796–1805
def validate_impa(*args: Any, **kwargs: Any) -> ImpaQuality:
    """Deprecated compatibility wrapper for :func:`grade_impa_quality`."""
    warnings.warn(
        "vaft.process.validate_impa() is deprecated; use grade_impa_quality(). "
        "vaft.process does not reach verdicts (issues #253, #337); the grading "
        "itself moves to vaft.validation.impa under #339.",
        DeprecationWarning,
        stacklevel=2,
    )
    return grade_impa_quality(*args, **kwargs)

Deprecated compatibility wrapper for grade_impa_quality.

results matching ""

    No results matching ""