Skip to content

Construct pitch angle distribution

el_paso.processing.construct_pitch_angle_distribution.construct_pitch_angle_distribution

construct_pitch_angle_distribution

Construct a pitch angle distribution from omni-directional flux.

This function calculates a pitch angle distribution based on an omni-directional flux variable and local pitch angles. Currently, it supports a 'sin' distribution method.

Parameters:

Name Type Description Default
omni_flux_var Variable

Omni-directional flux as an el_paso variable. The data is expected to be an array with dimensions (time, energy_channels).

required
pa_local_var Variable

Local pitch angles as an el_paso variable. The data is expected to be an array with dimensions (time, pitch_angles).

required
pa_eq_var Variable

Equatorial pitch angles as an el_paso variable. The data is expected to be an array with dimensions (time, pitch_angles).

required
method str

The method to use for constructing the distribution. Currently, only "sin" is supported. Defaults to "sin".

'sin'

Raises:

Type Description
ValueError

If an unsupported method is provided.

Returns:

Type Description
Variable

ep.Variable: A new el_paso variable containing the differential flux. The returned data is a 3D array with dimensions (time, energy_channels, pitch_angles), and the units are updated accordingly (e.g., flux per steradian).

Source code in el_paso/processing/construct_pitch_angle_distribution.py
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
def construct_pitch_angle_distribution(
    omni_flux_var: ep.Variable,
    pa_local_var: ep.Variable,
    pa_eq_var: ep.Variable,
    method: str = "sin",
) -> ep.Variable:
    """Construct a pitch angle distribution from omni-directional flux.

    This function calculates a pitch angle distribution based on an omni-directional flux
    variable and local pitch angles. Currently, it supports a 'sin' distribution method.

    Args:
        omni_flux_var (ep.Variable): Omni-directional flux as an `el_paso` variable.
                                     The data is expected to be an array with dimensions
                                     (time, energy_channels).
        pa_local_var (ep.Variable): Local pitch angles as an `el_paso` variable.
                                    The data is expected to be an array with dimensions
                                    (time, pitch_angles).
        pa_eq_var (ep.Variable): Equatorial pitch angles as an `el_paso` variable.
                                 The data is expected to be an array with dimensions
                                 (time, pitch_angles).
        method (str, optional): The method to use for constructing the distribution.
                                Currently, only "sin" is supported. Defaults to "sin".

    Raises:
        ValueError: If an unsupported method is provided.

    Returns:
        ep.Variable: A new `el_paso` variable containing the differential flux. The returned data
                     is a 3D array with dimensions (time, energy_channels, pitch_angles),
                     and the units are updated accordingly (e.g., flux per steradian).
    """
    omni_flux = omni_flux_var.get_data()
    pa_local = pa_local_var.get_data(u.rad)

    pa_eq_max = np.max(pa_eq_var.get_data(u.rad), axis=1)

    omni_flux = np.atleast_3d(omni_flux)

    match method:
        case "sin":
            # Create a sin distribution
            # Calculate the factor outside the loops
            sin_pa = np.sin(pa_local)
            mean_sin = np.mean(np.sin(np.linspace(0, np.pi, 36)))

            # Calculate the factor matrix
            fact_matrix = sin_pa / (mean_sin * np.reciprocal(np.sin(pa_eq_max[:, np.newaxis])))

            differential_flux = omni_flux * fact_matrix[:, np.newaxis, :]

        case _:
            msg = f"Encountered invalid method to constrouct pitch angle distribution: {method}!"
            raise ValueError(msg)

    return ep.Variable(data=differential_flux, original_unit=(omni_flux_var.metadata.unit / u.sr))