Skip to content

Compute invariant mu

el_paso.processing.compute_invariant_mu

Functions:

el_paso.processing.compute_invariant_mu.compute_invariant_mu

compute_invariant_mu

Computes the first adiabatic invariant (mu) for given particle species.

The first adiabatic invariant (\(\mu\)) is calculated using the formula: \(\mu = \frac{p_{\perp}^2}{2mB}\), where \(p_{\perp}\) is the perpendicular momentum, \(m\) is the particle's rest mass, and \(B\) is the local magnetic field strength.

The momentum is derived from the total energy and local pitch angle. The result is in units of \(MeV/G\).

Parameters:

Name Type Description Default
energy_var Variable

A Variable object containing the total energy of the particles in MeV. Expected to be a 2D array (time, energy_bins).

required
alpha_local_var Variable

A Variable object containing the local pitch angles in radians. Expected to be a 2D array (time, angle_bins).

required
B_local_var Variable

A Variable object containing the local magnetic field strength in nT. Expected to be a 1D array (time).

required
particle_species ParticleLiteral

The species of the particles (e.g., "electron", "proton").

required

Returns:

Type Description
Variable

ep.Variable: A new Variable object containing the computed invariant mu data, with dimensions (time, energy_bins, angle_bins) and unit \(MeV/G\).

Raises:

Type Description
ValueError

If input variables do not have the correct dimensions (energy, alpha_local must be 2D; B_local must be 1D) or if their time dimensions do not match.

Notes

Values of invariant mu that are less than or equal to zero are replaced with NaN.

Source code in el_paso/processing/compute_invariant_mu.py
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
def compute_invariant_mu(
    energy_var: ep.Variable,
    alpha_local_var: ep.Variable,
    B_local_var: ep.Variable,
    particle_species: ParticleLiteral,
) -> ep.Variable:
    r"""Computes the first adiabatic invariant (mu) for given particle species.

    The first adiabatic invariant ($\mu$) is calculated using the formula:
    $\mu = \frac{p_{\perp}^2}{2mB}$, where $p_{\perp}$ is the perpendicular
    momentum, $m$ is the particle's rest mass, and $B$ is the local magnetic
    field strength.

    The momentum is derived from the total energy and local pitch angle.
    The result is in units of $MeV/G$.

    Args:
        energy_var (ep.Variable): A Variable object containing the total energy
            of the particles in MeV. Expected to be a 2D array (time, energy_bins).
        alpha_local_var (ep.Variable): A Variable object containing the local
            pitch angles in radians. Expected to be a 2D array (time, angle_bins).
        B_local_var (ep.Variable): A Variable object containing the local magnetic
            field strength in nT. Expected to be a 1D array (time).
        particle_species (ParticleLiteral): The species of the particles
            (e.g., "electron", "proton").

    Returns:
        ep.Variable: A new Variable object containing the computed invariant mu
            data, with dimensions (time, energy_bins, angle_bins) and unit $MeV/G$.

    Raises:
        ValueError: If input variables do not have the correct dimensions
            (energy, alpha_local must be 2D; B_local must be 1D)
            or if their time dimensions do not match.

    Notes:
        Values of invariant mu that are less than or equal to zero are replaced with `NaN`.
    """
    energy = energy_var.get_data(u.MeV)
    alpha_local = alpha_local_var.get_data(u.radian)
    magnetic_field = B_local_var.get_data(u.G)

    if energy.ndim != 2 or alpha_local.ndim != 2 or magnetic_field.ndim != 1:
        msg = (
            "Input variables must have the correct dimensions: energy (2D), alpha_local (2D), and magnetic_field (1D)."
        )
        raise ValueError(msg)

    if energy.shape[0] != alpha_local.shape[0] or energy.shape[0] != magnetic_field.shape[0]:
        msg = (
            "Input variables must have matching time dimensions: "
            f"energy ({energy.shape[0]}), alpha_local ({alpha_local.shape[0]}), "
            f"and magnetic_field ({magnetic_field.shape[0]})."
        )
        raise ValueError(msg)

    mc2 = rest_energy(particle_species)
    pct = en2pc(energy, particle_species)  # Relativistic energy for the particles

    # Calculate InvMu using broadcasting
    sin_alpha_eq = np.sin(alpha_local)

    inv_mu = (pct[:, :, np.newaxis] * sin_alpha_eq[:, np.newaxis, :]) ** 2 / (
        magnetic_field[:, np.newaxis, np.newaxis] * 2 * mc2
    )  # MeV/G

    inv_mu[inv_mu <= 0] = np.nan

    inv_mu_var = ep.Variable(data=inv_mu, original_unit=u.MeV / u.G)

    inv_mu_var.metadata.add_processing_note(f"Created with compute_invariant_mu for {particle_species} particles")

    return inv_mu_var