Source code for pyrfu.pyrf.edb

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# 3rd party imports
import numpy as np
import xarray as xr

# Local imports
from .resample import resample
from .ts_scalar import ts_scalar
from .ts_vec_xyz import ts_vec_xyz

__author__ = "Louis Richard"
__email__ = "louisr@irfu.se"
__copyright__ = "Copyright 2020-2023"
__license__ = "MIT"
__version__ = "2.4.2"
__status__ = "Prototype"


def _check_method(flag_method):
    default_value = 0
    if flag_method.lower() == "e_perp+nan":
        default_value = np.nan

        flag_method = "e.b=0"

    assert flag_method.lower() in ["e.b=0", "e_par"], "Invalid flag"

    return flag_method, default_value


[docs]def edb(e_xyz, b_bgd, angle_lim: float = 20.0, flag_method: str = "E.B=0"): r"""Compute Ez under assumption :math:`\mathbf{E}.\mathbf{B}=0` or :math:`\mathbf{E}.\mathbf{B} \approx 0` Parameters ---------- e_xyz : xarray.DataArray Time series of the electric field. b_bgd : xarray.DataArray Time series of the background magnetic field. angle_lim : float, Optional B angle with respect to the spin plane should be less than angle_lim degrees otherwise Ez is set to 0. Default is 20. flag_method : str, Optional Assumption on the direction of the measured electric field : "e.b=0" : :math:`\mathbf{E}.\mathbf{B}=0`. (Default) "e_par" : :math:`\mathbf{E}` field along the B projection is coming from parallelelectric field. "e_perp+nan" : to fill. Returns ------- ed : xarray.DataArray Time series of the electric field output. d : xarray.DataArray Time series of the B elevation angle above spin plane. Examples -------- >>> from pyrfu import mms, pyrf Time interval >>> tint = ["2019-09-14T07:54:00.000","2019-09-14T08:11:00.000"] Spacecraft indices >>> mms_id = 1 Load magnetic field, electric field and spacecraft position >>> b_xyz = mms.get_data("B_gse_fgm_srvy_l2", tint, mms_id) >>> e_xyz = mms.get_data("E_gse_edp_fast_l2", tint, mms_id) Compute Ez >>> e_z, alpha = pyrf.edb(e_xyz, b_xyz) """ assert isinstance(e_xyz, xr.DataArray), "e_xyz must be a xarray.DataArray" assert isinstance(b_bgd, xr.DataArray), "b_bgd must be a xarray.DataArray" assert isinstance(angle_lim, (int, float)), "angle_lime must be int or float" flag_method, default_value = _check_method(flag_method) # Make sure that background magnetic field sampling matches the # electric field sampling b_bgd = resample(b_bgd, e_xyz) b_data = b_bgd.data e_data = e_xyz.data e_data[:, -1] *= default_value if flag_method.lower() == "e.b=0": # Calculate using assumption E.B=0 b_angle = np.arctan2( b_data[:, 2], np.linalg.norm(b_data[:, :2], axis=1), ) b_angle = np.rad2deg(b_angle) ind = np.abs(b_angle) > angle_lim if True in ind: e_data[ind, 2] = -np.sum( e_data[ind, :2] * b_data[ind, :2], axis=1, ) e_data[ind, 2] /= b_data[ind, 2] else: # Calculate using assumption that E field along the B projection is # coming from parallel electric field b_angle = np.arctan2( b_data[:, 2], np.linalg.norm(b_data[:, :2], axis=1), ) b_angle = np.rad2deg(b_angle) ind = np.abs(b_angle) < angle_lim if True in ind: e_data[ind, 2] = np.sum(e_data[ind, :2] * b_data[ind, :2], axis=1) e_data[ind, 2] *= b_data[ind, 2] e_data[ind, 2] /= np.linalg.norm(b_data[ind, :2], axis=1) ** 2 b_angle = ts_scalar(e_xyz.time.data, b_angle, {"UNITS": "degrees"}) e_data = ts_vec_xyz( e_xyz.time.data, e_data, e_xyz.attrs, ) return e_data, b_angle