Skip to content

Compute magnetic field variables

This function serves as a wrapper to calculate a suite of magnetic field and related invariants (like L-star, MLT, B_local, B_eq, invariant Mu, and invariant K) based on provided time and geocentric coordinates. It leverages the IRBEM library for the underlying computations.

var_names_to_compute must be a list of strings containing the requested variable names followed by the magnetic field identifier string.

Supported variable names:

  • B_local
  • B_fofl
  • B_mirr
  • MLT
  • R_eq
  • MLT_eq
  • xGEO_eq
  • B_eq
  • Lstar
  • PA_eq
  • invMu
  • invK
  • XJ

Supported magnetic field strings:

  • OP77Q
  • T89
  • T96
  • T01
  • T01s
  • TS04|TS05|T04s

Examples of valid entries: B_local_T89, Lstar_TS04

el_paso.processing.compute_magnetic_field_variables

Attributes

el_paso.processing.compute_magnetic_field_variables.VariableRequest module-attribute

Type alias for a request to compute magnetic field variables, consisting of a sequence of tuples where each tuple specifies the variable type and the magnetic field model to use for its computation.

Classes

el_paso.processing.compute_magnetic_field_variables.MagFieldVar

Bases: NamedTuple

A named tuple to represent a request for a magnetic field variable.

Attributes:

Name Type Description
type MagFieldVarTypes

The type of magnetic field variable to compute (e.g., "B_local", "Lstar").

mag_field str | MagneticField

The magnetic field model to use for the computation .

Source code in el_paso/processing/compute_magnetic_field_variables.py
31
32
33
34
35
36
37
38
39
40
class MagFieldVar(NamedTuple):
    """A named tuple to represent a request for a magnetic field variable.

    Attributes:
        type (MagFieldVarTypes): The type of magnetic field variable to compute (e.g., "B_local", "Lstar").
        mag_field (str | mag_utils.MagneticField): The magnetic field model to use for the computation .
    """

    type: MagFieldVarTypes
    mag_field: str | mag_utils.MagneticField

Functions:

el_paso.processing.compute_magnetic_field_variables.compute_magnetic_field_variables

compute_magnetic_field_variables

Computes various magnetic field-related variables using the IRBEM library.

This function serves as a wrapper to calculate a suite of magnetic field and related invariants (like L-star, MLT, B_local, B_eq, invariant Mu, and invariant K) based on provided time and geocentric coordinates. It leverages the IRBEM library for the underlying computations.

Parameters:

Name Type Description Default
time_var Variable

A Variable object containing time data. The data should be a 1D array of timestamps.

required
xgeo_var Variable

A Variable object containing geocentric (XGEO) coordinates. Expected to be a 2D array (time, 3) where the last dimension represents X, Y, Z coordinates.

required
variables_to_compute Sequence[tuple[MagFieldVarTypes, str | MagneticField]]

A sequence of tuples, where each tuple specifies a variable to compute. The first element is the variable type (e.g., "Lstar"), and the second is the magnetic field model to use (e.g., "IGRF").

required
irbem_options list[int]

A list of 5 integer options for the IRBEM library calls, controlling aspects like model selection, bounce tracing, etc.

required
num_cores int

The number of CPU cores to use for parallel processing within IRBEM calls.

required
indices_solar_wind dict[str, Variable] | None

Optional. A dictionary containing solar wind indices (e.g., "Kp", "Dst") as Variable objects. Defaults to None.

None
pa_local_var Variable | None

Optional. A Variable object containing local pitch angle data in degrees. Required if any pitch-angle dependent variables (e.g., "PA_eq", "Lstar", "invMu", "invK") are requested. Defaults to None.

None
energy_var Variable | None

Optional. A Variable object containing particle energy data in MeV. Required if "invMu" is requested. Defaults to None.

None
particle_species Literal['electron', 'proton'] | None

Optional. The species of particle (e.g., "electron", "proton"). Required if "invMu" is requested. Defaults to None.

None
irbem_lib_path str | Path

Optional. The file path to the IRBEM library (e.g., "libirbem.so"). Defaults to a path relative to the el_paso package.

parent / 'libirbem.so'

Returns:

Type Description
dict[str, Variable]

dict[str, Variable]: A dictionary where keys are the computed variable

dict[str, Variable]

names and values are their corresponding Variable objects containing

dict[str, Variable]

the calculated data and metadata.

Raises:

Type Description
FileNotFoundError

If no IRBEM library object is found at the provided irbem_lib_path.

ValueError
  • If irbem_options does not contain exactly 5 entries.
  • If a pitch-angle dependent variable is requested but pa_local_var is not provided.
  • If an energy-dependent variable ("invMu") is requested but energy_var is not provided.
  • If a particle-species dependent variable ("invMu") is requested but particle_species is not provided.
NotImplementedError

If a requested variable name in variables_to_compute is not supported by this function.

Notes
  • The function internally constructs an IrbemInput object for each unique magnetic field model encountered in variables_to_compute.
  • Intermediate computed variables (e.g., B_eq, B_local) are cached within the function to avoid redundant IRBEM calls when multiple dependent variables are requested.
Source code in el_paso/processing/compute_magnetic_field_variables.py
 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
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
def compute_magnetic_field_variables(
    time_var: Variable,
    xgeo_var: Variable,
    variables_to_compute: VariableRequest,
    irbem_options: list[int],
    num_cores: int,
    indices_solar_wind: dict[str, Variable] | None = None,
    pa_local_var: Variable | None = None,
    energy_var: Variable | None = None,
    particle_species: Literal["electron", "proton"] | None = None,
    *,
    irbem_lib_path: str | Path = Path(ep.__file__).parent / "libirbem.so",
) -> dict[str, Variable]:
    """Computes various magnetic field-related variables using the IRBEM library.

    This function serves as a wrapper to calculate a suite of magnetic field
    and related invariants (like L-star, MLT, B_local, B_eq, invariant Mu,
    and invariant K) based on provided time and geocentric coordinates. It
    leverages the IRBEM library for the underlying computations.

    Args:
        time_var (Variable): A Variable object containing time data. The data should be a 1D array of timestamps.
        xgeo_var (Variable): A Variable object containing geocentric (XGEO)
            coordinates. Expected to be a 2D array (time, 3) where the last
            dimension represents X, Y, Z coordinates.
        variables_to_compute (Sequence[tuple[MagFieldVarTypes, str | mag_utils.MagneticField]]):
            A sequence of tuples, where each tuple specifies a variable to compute. The first element is the
            variable type (e.g., "Lstar"), and the second is the magnetic field model to use (e.g., "IGRF").
        irbem_options (list[int]): A list of 5 integer options for the IRBEM library
            calls, controlling aspects like model selection, bounce tracing, etc.
        num_cores (int): The number of CPU cores to use for parallel processing
            within IRBEM calls.
        indices_solar_wind (dict[str, Variable] | None): Optional. A dictionary
            containing solar wind indices (e.g., "Kp", "Dst") as `Variable` objects.
            Defaults to None.
        pa_local_var (Variable | None): Optional. A Variable object containing
            local pitch angle data in degrees. Required if any pitch-angle dependent variables
            (e.g., "PA_eq", "Lstar", "invMu", "invK") are requested. Defaults to None.
        energy_var (Variable | None): Optional. A Variable object containing
            particle energy data in MeV. Required if "invMu" is requested. Defaults to None.
        particle_species (Literal["electron", "proton"] | None): Optional. The
            species of particle (e.g., "electron", "proton"). Required if "invMu"
            is requested. Defaults to None.
        irbem_lib_path (str | Path): Optional. The file path to the IRBEM library (e.g., "libirbem.so"). Defaults to a
            path relative to the el_paso package.

    Returns:
        dict[str, Variable]: A dictionary where keys are the computed variable
        names and values are their corresponding `Variable` objects containing
        the calculated data and metadata.

    Raises:
        FileNotFoundError: If no IRBEM library object is found at the provided `irbem_lib_path`.
        ValueError:
            - If `irbem_options` does not contain exactly 5 entries.
            - If a pitch-angle dependent variable is requested but `pa_local_var` is not provided.
            - If an energy-dependent variable ("invMu") is requested but `energy_var` is not provided.
            - If a particle-species dependent variable ("invMu") is requested but `particle_species` is not provided.
        NotImplementedError: If a requested variable name in `variables_to_compute`
            is not supported by this function.

    Notes:
        - The function internally constructs an `IrbemInput` object for each unique
          magnetic field model encountered in `variables_to_compute`.
        - Intermediate computed variables (e.g., `B_eq`, `B_local`) are cached
          within the function to avoid redundant IRBEM calls when multiple
          dependent variables are requested.
    """
    if not Path(irbem_lib_path).is_file():
        msg = f"No library object found under the provided irbem_lib_path: {irbem_lib_path}"
        logger.warning(
            "Ideally this should not happen if the default path is used. If you installed "
            "the package in editable mode, 'libirbem.so' can be found in the ./build/lib/ directory. "
            "Check if the file exists at the provided path."
        )
        raise FileNotFoundError(msg)

    if len(irbem_options) != 5:
        msg = f"irbem_options must be a list with exactly 5 entries! Got: {irbem_options}"
        raise ValueError(msg)

    mag_variables_to_compute = [
        MagFieldVar(mag_field_var[0], mag_field_var[1]) for mag_field_var in variables_to_compute
    ]

    if _requires_pa_var(mag_variables_to_compute) and pa_local_var is None:
        msg = "Pitch-angle dependent variable is requested but local pitch angles are not provided!"
        raise ValueError(msg)
    pa_local_var = typing.cast("Variable", pa_local_var)

    if _requires_energy_var(mag_variables_to_compute) and energy_var is None:
        msg = "Energy dependent variable is requested but energies are not provided!"
        raise ValueError(msg)
    energy_var = typing.cast("Variable", energy_var)

    if _requires_particle_species(mag_variables_to_compute) and particle_species is None:
        msg = "Particle-species dependent variable is requested but particle_species is not provided!"
        raise ValueError(msg)
    particle_species = typing.cast("Literal['electron', 'proton']", particle_species)

    # collect magnetic_field results in this dictionary
    computed_variables: dict[str, Variable] = {}
    var_names_to_compute: list[str] = []

    for mag_field_var in mag_variables_to_compute:
        var_type = mag_field_var.type
        mag_field = mag_field_var.mag_field

        if isinstance(mag_field, str):
            mag_field = mag_utils.MagneticField(mag_field)

        variable_name = mag_utils.create_var_name(var_type, mag_field)
        var_names_to_compute.append(variable_name)

        # check if the value has been calculated already
        if variable_name in computed_variables:
            continue

        indices_solar_wind_hashable = make_dict_hashable(indices_solar_wind)

        maginput = mag_utils.construct_maginput(time_var, mag_field, indices_solar_wind_hashable)

        irbem_input = mag_utils.IrbemInput(
            magnetic_field=mag_field,
            maginput=maginput,
            irbem_options=irbem_options,
            num_cores=num_cores,
            irbem_lib_path=irbem_lib_path,
        )

        computed_variables |= _get_result(
            var_type, xgeo_var, time_var, pa_local_var, energy_var, computed_variables, irbem_input, particle_species
        )

    # only return the requested variables
    computed_variables = {
        var_name: computed_variables[var_name] for var_name in computed_variables if var_name in var_names_to_compute
    }

    return computed_variables