swarmpal.toolboxes.dsecs.dsecs_algorithms
=========================================

.. py:module:: swarmpal.toolboxes.dsecs.dsecs_algorithms

.. autoapi-nested-parse::

   Algorithms for low latitude spherical elementary current system analysis.

   Adapted from MatLab code by Heikki Vanhamäki.



Attributes
----------

.. autoapisummary::

   swarmpal.toolboxes.dsecs.dsecs_algorithms.logger


Classes
-------

.. autoapisummary::

   swarmpal.toolboxes.dsecs.dsecs_algorithms.grid2D
   swarmpal.toolboxes.dsecs.dsecs_algorithms.grid1D
   swarmpal.toolboxes.dsecs.dsecs_algorithms.dsecsgrid
   swarmpal.toolboxes.dsecs.dsecs_algorithms.dsecsdata


Functions
---------

.. autoapisummary::

   swarmpal.toolboxes.dsecs.dsecs_algorithms._DSECS_steps
   swarmpal.toolboxes.dsecs.dsecs_algorithms._legPol_n1
   swarmpal.toolboxes.dsecs.dsecs_algorithms._legPol
   swarmpal.toolboxes.dsecs.dsecs_algorithms.SECS_1D_DivFree_vector
   swarmpal.toolboxes.dsecs.dsecs_algorithms.SECS_1D_DivFree_magnetic
   swarmpal.toolboxes.dsecs.dsecs_algorithms.SECS_1D_CurlFree_vector
   swarmpal.toolboxes.dsecs.dsecs_algorithms.SECS_1D_CurlFree_magnetic
   swarmpal.toolboxes.dsecs.dsecs_algorithms.SECS_2D_DivFree_vector
   swarmpal.toolboxes.dsecs.dsecs_algorithms.SECS_2D_DivFree_magnetic
   swarmpal.toolboxes.dsecs.dsecs_algorithms.SECS_2D_CurlFree_antisym_vector
   swarmpal.toolboxes.dsecs.dsecs_algorithms.SECS_2D_CurlFree_antisym_magnetic
   swarmpal.toolboxes.dsecs.dsecs_algorithms.secs_2d_curlFree_antisym_lineintegral
   swarmpal.toolboxes.dsecs.dsecs_algorithms._calc_root
   swarmpal.toolboxes.dsecs.dsecs_algorithms.getUnitVectors
   swarmpal.toolboxes.dsecs.dsecs_algorithms.getLocalDipoleFPtrack1D
   swarmpal.toolboxes.dsecs.dsecs_algorithms.getLocalDipoleFPtrack2D
   swarmpal.toolboxes.dsecs.dsecs_algorithms.mag_transform_dsecs
   swarmpal.toolboxes.dsecs.dsecs_algorithms.trim_data
   swarmpal.toolboxes.dsecs.dsecs_algorithms.get_exclusion_zone


Module Contents
---------------

.. py:data:: logger

.. py:function:: _DSECS_steps(SwAin, SwCin)

   DSECS analysis for Vires xarray input.

   :param SwAin: Input data for Swarm Alpha
   :type SwAin: xarray from SecsInput
   :param SwCin: Input data for Swarm Charlie
   :type SwCin: xarray from SecsInput

   :returns: Each entry contains the original data ("original_data), the resulting current densities ("current_densities"), the magnetic fit for Swarm A and C ("magnetic_Fit_Alpha", "magnetic_Fit_Charlie") and the dsecsdata object ("case").
   :rtype: List of dicts


.. py:function:: _legPol_n1(n, x, ind=False)

   Evaluate associated Legendre polynomials (l, m=1).

   :param n: max degree of the polynomials
   :type n: int
   :param x: points at which to evaluate the polynomials, -1 <= x >= 1
   :type x: ndarray
   :param ind: Return only the nth degree polynomial, by default False
   :type ind: bool, optional

   :returns: (len(x),n) shaped array of the polynomial values.
   :rtype: ndarray


.. py:function:: _legPol(n, x, ind=False)

   Evaluate Legendre polynomials.

   :param n: max degree of the polynomials
   :type n: int
   :param x: 1D array of points at which to evaluate the polynomials, -1 <= x >= 1
   :type x: ndarray
   :param ind: Return only the nth degree polynomial, by default False
   :type ind: bool, optional

   :returns: (len(x),n+1) shaped array of the polynomial values.
   :rtype: ndarray


.. py:function:: SECS_1D_DivFree_vector(latV, latSECS, ri)

   Calculates the matrix for 1D divergence free current density.

   :param latV: Latitudes of locations where vectors is calculated, in degrees
   :type latV: ndarray
   :param latSECS: Latitudes of the 1D SECS poles, in degrees
   :type latSECS: ndarray
   :param ri: Assumed radius of the spherical shell where the currents flow (km).
   :type ri: int

   :returns: 2D array that maps the 1D elementary current amplitudes to currents.
   :rtype: ndarray


.. py:function:: SECS_1D_DivFree_magnetic(latB, latSECS, rb, rsecs, M)

   Calculates the matrix for magnetic field from 1D divergence free current.

   :param latB: Array of latitudes where the magnetic field is calculated [degree]
   :type latB: ndarray
   :param latSECS: Array of latitudes where 1D CF SECS are located [degree]
   :type latSECS: ndarray
   :param rb: Array of radial distances of the points where the magnetic field is calculated, scalar or vector, [km]
   :type rb: ndarray
   :param rsecs: Radius of the sphere where the 1D CF SECS are located, scalar, [km]
   :type rsecs: float
   :param M: argest order of the Legendre polynomials
   :type M: int

   :returns: * *ndarray* -- 2D array to map the elementary current system amplitudes to radial magnetic field
             * *ndarray* -- 2D array to map the elementary current system amplitudes to meridional magnetic field


.. py:function:: SECS_1D_CurlFree_vector(latV, latSECS, ri)

   Calculates the array relating SECS amplitudes to curl free current.

   :param latV: Array of latitudes where the current is calculated.
   :type latV: ndarray
   :param latSECS: Array of latitudes of the SECS poles.
   :type latSECS: ndarray
   :param ri: Assumed radius of the spherical shell where the currents flow (km).
   :type ri: float

   :returns: 2D array to map the elementary current amplitudes to div free current.
   :rtype: ndarray


.. py:function:: SECS_1D_CurlFree_magnetic(latB, latSECS, rb, rsecs, geometry)

   Calculates the array that maps the CF SECS amplitudes to magnetic field.

   :param latB: Latitudes where the magnetic field is calculated.
   :type latB: ndarray
   :param latSECS: Latitudes of the SECS poles
   :type latSECS: ndarray
   :param rb: Array of radial distances of the points where the magnetic field is calculated, scalar or vector, [km]
   :type rb: ndarray
   :param rsecs: Radius of the sphere where the calculation takes place, [km], scalar
   :type rsecs: float
   :param geometry: If 'radial', assume radial field lines. Else, assume dipolar field.
   :type geometry: string

   :returns: 2D array that maps the SECS amplitudes to magnetic field measurements.
   :rtype: ndarray


.. py:function:: SECS_2D_DivFree_vector(thetaV, phiV, thetaSECS, phiSECS, radius, limitangle)

   Calculates 2D DF SECS matrices for currents densities.

   Function for calculating matrices matVtheta and matVphi which give the theta- and
   phi-components of a vector field from the scaling factors of div-free spherical elementary
   surrent systems (DF SECS).

   :param thetaV: theta coordinate of points where the vector is calculated
   :type thetaV: ndarray
   :param phiV: phi coordinate of points where the vector is calculated
   :type phiV: ndarray
   :param thetaSECS: theta coordinates od SECS poles
   :type thetaSECS: ndarray
   :param phiSECS: phi coordinates of points where the vector is calculated
   :type phiSECS: ndarray
   :param radius: Radius of the sphere where the calculation takes place, [km], scalar
   :type radius: ndarray
   :param limitangle: Half-width of the uniformly distributed SECS, [radian], scalar or Nsecs-dimensional vector.
   :type limitangle: ndarray

   :returns: * *ndarray* -- 2D array to map the elementary current system amplitudes to theta component of current density.
             * *ndarray* -- 2D array to map the elementary current system amplitudes to phi component of current density.


.. py:function:: SECS_2D_DivFree_magnetic(thetaB, phiB, thetaSECS, phiSECS, rb, rsecs)

   Calculates the array that maps the SECS amplitudes to magnetic field.

   :param thetaB: Theta coordinate of the points where magnetic field is calculated.
   :type thetaB: ndarray
   :param phiB: Phi coordinate of the points where magnetic field is calculated.
   :type phiB: ndarray
   :param thetaSECS: Theta coordinate of the SECS poles.
   :type thetaSECS: ndarray
   :param phiSECS: Phi coordinate of the SECS poles.
   :type phiSECS: ndarray
   :param rb: Geocentric radius of the points where the magnetic field is calculated.
   :type rb: ndarray
   :param rsecs: Assumed radius of the spherical shell where the currents flow (km).
   :type rsecs: float

   :returns: * *ndarray* -- 2D array to map the elementary current system amplitudes to radial component of magnetic field.
             * *ndarray* -- 2D array to map the elementary current system amplitudes to theta component of magnetic field.
             * *ndarray* -- 2D array to map the elementary current system amplitudes to phi component of magnetic field.


.. py:function:: SECS_2D_CurlFree_antisym_vector(thetaV, phiV, thetaSECS, phiSECS, radius, limitangle)

   Calculates the mapping from antisymmetric dipolar CF SECS to current density.

   :param thetaV: theta coordinate of points where the vector is calculated
   :type thetaV: ndarray
   :param phiV: phi coordinate of points where the vector is calculated
   :type phiV: ndarray
   :param thetaSECS: theta coordinates od SECS poles
   :type thetaSECS: ndarray
   :param phiSECS: phi coordinates of points where the vector is calculated
   :type phiSECS: ndarray
   :param radius: Radius of the sphere where the calculation takes place, [km], scalar
   :type radius: ndarray
   :param limitangle: Half-width of the uniformly distributed SECS, [radian], scalar or Nsecs-dimensional vector.
   :type limitangle: ndarray

   :returns: * *ndarray* -- 2D array that maps the SECS amplitudes to the theta component of the current density.
             * *ndarray* -- 2D array that maps the SECS amplitudes to the phi component of the current density.


.. py:function:: SECS_2D_CurlFree_antisym_magnetic(thetaB, phiB, thetaSECS, phiSECS, rb, rsecs, limitangle)

   Calculates the mapping from antisymmetric dipolar CF SECS to magnetic field.

   :param thetaB: Theta coordinate of the points where magnetic field is calculated.
   :type thetaB: ndarray
   :param phiB: Phi coordinate of the points where magnetic field is calculated.
   :type phiB: ndarray
   :param thetaSECS: Theta coordinate of the SECS poles.
   :type thetaSECS: ndarray
   :param phiSECS: Phi coordinate of the SECS poles.
   :type phiSECS: ndarray
   :param rb: Geocentric radius of the points where the magnetic field is calculated.
   :type rb: ndarray
   :param rsecs: Assumed radius of the spherical shell where the currents flow (km).
   :type rsecs: float
   :param limitangle: Half-width of the uniformly distributed SECS, [radian], scalar or Nsecs-dimensional vector.
   :type limitangle: ndarray

   :returns: * *ndarray* -- 2D array that maps the SECS amplitudes to the theta component of the current density.
             * *ndarray* -- 2D array that maps the SECS amplitudes to the phi component of the current density.


.. py:function:: secs_2d_curlFree_antisym_lineintegral(thetaB, phiB, thetaSECS, phiSECS, rb, rsecs, smallr)

   Line integral for DSECS 2d curl free.

   :param thetaB: Theta coordinate of the points where magnetic field is calculated.
   :type thetaB: ndarray
   :param phiB: Phi coordinate of the points where magnetic field is calculated.
   :type phiB: ndarray
   :param thetaSECS: Theta coordinate of the SECS pole in radian.
   :type thetaSECS: float
   :param phiSECS: Phi coordinate of the SECS pole in radian.
   :type phiSECS: float
   :param rb: Geocentric radius of the points where the magnetic field is calculated.
   :type rb: ndarray
   :param rsecs: Assumed radius of the spherical shell where the currents flow (km).
   :type rsecs: float
   :param smallr: Limit of "small" radius [km]
   :type smallr: ndarray

   :returns: **bx, by, bz** -- Cartesian components of the magnetic field at the magnetometer locations [nT]
   :rtype: ndarray


.. py:function:: _calc_root(x, y, z)

   _summary_

   :param x: _description_
   :type x: ndarray
   :param y: _description_
   :type y: ndarray
   :param z: _description_
   :type z: ndarray

   :returns: _description_
   :rtype: ndarray


.. py:function:: getUnitVectors(SwA, SwC)

   Calculates the magnetic unit vectors.

   :param SwA: Swarm A and C datasets.
   :type SwA: xarray
   :param SwC: Swarm A and C datasets.
   :type SwC: xarray

   :returns: **SwA, SwC** -- Swarm A and C datasets including magnetic unit vectors 'ggUvT', 'ggUvP' and 'UvR'.
   :rtype: xarray


.. py:class:: grid2D(origin='geo')

   Class for 2D DSECS grids


   .. py:attribute:: ggLat


   .. py:attribute:: ggLon


   .. py:attribute:: magLat


   .. py:attribute:: magLon


   .. py:attribute:: angle2D


   .. py:attribute:: diff2lon2D


   .. py:attribute:: diff2lat2D


   .. py:attribute:: origin
      :value: 'geo'



   .. py:method:: create(lat1, lon1, lat2, lon2, dlat, lonRat, extLat, extLon, poleLat, poleLon)

      Initializes the 2D grid from Swarm data.

      :param lat1: Swarm A and C latitudes, [degree].
      :type lat1: ndarray
      :param lat2: Swarm A and C latitudes, [degree].
      :type lat2: ndarray
      :param lon1: Swarm A and C longitudes, [degree].
      :type lon1: ndarray
      :param lon2: Swarm A and C longitudes, [degree].
      :type lon2: ndarray
      :param dlat: 2D grid spacing in latitudinal direction, [degree].
      :type dlat: float
      :param lonRat: Ratio between the satellite separation and longitudinal spacing of the 2D grid.
      :type lonRat: int or float
      :param extLat: Number of points to extend the 2D grid outside data area in latitudinal and longitudinal directions.
      :type extLat: int
      :param extLon: Number of points to extend the 2D grid outside data area in latitudinal and longitudinal directions.
      :type extLon: int



.. py:class:: grid1D

   Simple class to hold a 1D lat grid


   .. py:attribute:: lat


   .. py:attribute:: diff2


   .. py:method:: create(lat1, lat2, dlat, extLat)

      Initializes the 1D grid from Swarm data.

      :param lat1: Swarm A and C latitudes ,[degree].
      :type lat1: ndarray
      :param lat2: Swarm A and C latitudes ,[degree].
      :type lat2: ndarray
      :param dlat: 1D grid spacing in latitudinal direction, [degree].
      :type dlat: int or float
      :param extLat: Number of points to extend the 1D grid outside data area in latitudinal direction.
      :type extLat: int



.. py:class:: dsecsgrid

   Class for all the grids needed in DSECS analysis


   .. py:attribute:: out


   .. py:attribute:: secs2Ddf


   .. py:attribute:: secs1Ddf


   .. py:attribute:: secs1DcfNorth


   .. py:attribute:: secs1DcfSouth


   .. py:attribute:: secs2DcfNorth


   .. py:attribute:: secs2DcfSouth


   .. py:attribute:: secs2DcfRemoteNorth


   .. py:attribute:: secs2DcfRemoteSouth


   .. py:attribute:: outputlimitlat
      :value: 40



   .. py:attribute:: Re
      :value: 6371



   .. py:attribute:: Ri
      :value: 6501



   .. py:attribute:: poleLat
      :value: 90.0



   .. py:attribute:: poleLon
      :value: 0.0



   .. py:attribute:: dlatOut
      :value: 0.5



   .. py:attribute:: lonRatioOut
      :value: 2



   .. py:attribute:: extLatOut
      :value: 0



   .. py:attribute:: extLonOut
      :value: 3



   .. py:attribute:: extLat1D
      :value: 5



   .. py:attribute:: indsN


   .. py:attribute:: insdS


   .. py:attribute:: extLat2D
      :value: 5



   .. py:attribute:: extLon2D
      :value: 7



   .. py:attribute:: cfremoteN
      :value: 3



   .. py:attribute:: flag
      :value: 0



   .. py:attribute:: test


   .. py:method:: FindPole(SwA)

      Finds the best location for a local magnetic dipole pole based on Swarm measurements.

      :param SwA: Swarm A dataset.
      :type SwA: xarray



   .. py:method:: create(SwA, SwC)

      Initializes the 1D and 2D grids from Swarm data.

      :param SwA: Swarm A and C datasets.
      :type SwA: xarray
      :param SwC: Swarm A and C datasets.
      :type SwC: xarray



.. py:function:: getLocalDipoleFPtrack1D(latB, rB, Ri)

   Finds the local dipole footpoints for the 1D curl-free grid creation.

   :param latB: Magnetic latitude of the satellite, [degree].
   :type latB: ndarrar
   :param rB: Geocentric radius of the satellite, [km].
   :type rB: ndarray
   :param Ri: Assumed radius of the spherical shell where the currents flow, [km].
   :type Ri: int or float

   :returns: **track** -- Latitude of the local dipole footpoints of the satellite, [degree].
   :rtype: ndarray


.. py:function:: getLocalDipoleFPtrack2D(latB, lonB, rB, Ri)

   Finds the local dipole footpoints for the 2D curl-free grid creation.

   :param latB: Magnetic latitude of the satellite, [degree].
   :type latB: ndarray
   :param lonB: Magnetic longitude of the satellite, [degree].
   :type lonB: ndarray
   :param rB: Geocentric radius of the satellite, [km].
   :type rB: ndarray
   :param Ri: Assumed radius of the spherical shell where the currents flow, [km].
   :type Ri: int or float

   :returns: **latFP, lonFP** -- Latidue and longitude of the local dipole footpoints of the satellite, [degree].
   :rtype: ndarray


.. py:function:: mag_transform_dsecs(SwA, SwC, pole_lat, pole_lon)

   Rotates the data to a magnetic coordinate systems.

   :param SwA: Swarm A and C datasets.
   :type SwA: xarray
   :param SwC: Swarm A and C datasets.
   :type SwC: xarray
   :param pole_lat: Latitude and longitude of the new pole in the old coordinates, [degree].
   :type pole_lat: float
   :param pole_lon: Latitude and longitude of the new pole in the old coordinates, [degree].
   :type pole_lon: float

   :returns: **SwA, SwC** -- Swarm A and C datasets including data rotated to the magnetic coordinate system.
   :rtype: xarray


.. py:function:: trim_data(SwA, SwC)

   Finds a period with suitable spaceraft velocity for analysis.

   :param SwA: Swarm A and C datasets.
   :type SwA: xarray
   :param SwC: Swarm A and C datasets.
   :type SwC: xarray

   :returns: **SwA, SwC** -- Swarm A and C datasets trimmed to the suitable period.
   :rtype: xarray


.. py:function:: get_exclusion_zone(SwA, SwC)

.. py:class:: dsecsdata

   Class for DSECS variables and fitting procedures


   .. py:attribute:: lonB


   .. py:attribute:: latB


   .. py:attribute:: rB


   .. py:attribute:: Bt


   .. py:attribute:: Bp


   .. py:attribute:: Br


   .. py:attribute:: Bpara


   .. py:attribute:: uvR


   .. py:attribute:: uvT


   .. py:attribute:: uvP


   .. py:attribute:: grid
      :type:  dsecsgrid


   .. py:attribute:: alpha1Ddf
      :type:  float
      :value: 1e-05



   .. py:attribute:: epsSVD1Ddf
      :type:  float
      :value: 0.0004



   .. py:attribute:: alpha1Dcf
      :type:  float
      :value: 0.0002



   .. py:attribute:: epsSVD1Dcf
      :type:  float
      :value: 0.01



   .. py:attribute:: alpha2D
      :type:  float
      :value: 0.0005



   .. py:attribute:: epsSVD2D
      :type:  float
      :value: 0.001



   .. py:attribute:: epsSVD2dcf
      :type:  float
      :value: 0.002



   .. py:attribute:: alpha2Dcf
      :type:  float
      :value: 1.0



   .. py:attribute:: df1D


   .. py:attribute:: df2D


   .. py:attribute:: cf1D


   .. py:attribute:: cf2D


   .. py:attribute:: df2dBr


   .. py:attribute:: df2dBp


   .. py:attribute:: df2dBt


   .. py:attribute:: df1dBt


   .. py:attribute:: df1dBr


   .. py:attribute:: matBr1Ddf


   .. py:attribute:: matBt1Ddf


   .. py:attribute:: df1DJp


   .. py:attribute:: matBpara1D


   .. py:attribute:: matBpara2D


   .. py:attribute:: apexlats


   .. py:attribute:: cf1dDipMagJp


   .. py:attribute:: cf1dDipMagJt


   .. py:attribute:: cf1dDipJr


   .. py:attribute:: cf1dDipBr


   .. py:attribute:: cf1dDipMagBt


   .. py:attribute:: cf1dDipMagBp


   .. py:attribute:: cf2dDipMagJp


   .. py:attribute:: cf2dDipMagJt


   .. py:attribute:: cf2dDipJr


   .. py:attribute:: cf2dDipBr


   .. py:attribute:: cf2dDipMagBt


   .. py:attribute:: cf2dDipMagBp


   .. py:attribute:: matBp2Ddf


   .. py:attribute:: matBt2Ddf


   .. py:attribute:: matBr2Ddf


   .. py:attribute:: df2dMagJt


   .. py:attribute:: df2dMagJp


   .. py:attribute:: remoteCf2dDipMagBr


   .. py:attribute:: remoteCf2dDipMagBt


   .. py:attribute:: remoteCf2dDipMagBp


   .. py:attribute:: remoteCf2dDipMagJp


   .. py:attribute:: remoteCf2dDipMagJt


   .. py:attribute:: remoteCf2dDipMagJr


   .. py:attribute:: test


   .. py:attribute:: flag
      :value: 0



   .. py:attribute:: QDlats


   .. py:attribute:: apexcrossingA
      :type:  float
      :value: 0



   .. py:attribute:: apexcrossingC
      :type:  float
      :value: 0



   .. py:attribute:: exclusionmax
      :value: 0



   .. py:attribute:: exclusionmin
      :value: 0



   .. py:attribute:: SwA
      :value: None



   .. py:attribute:: SwC
      :value: None



   .. py:method:: populate(SwA, SwC)

      Initializes a DSECS analaysis case from Swarm data.

      :param SwA: Swarm A and C datasets.
      :type SwA: xarray
      :param SwC: Swarm A and C datasets.
      :type SwC: xarray



   .. py:method:: fit1D_df()

      1D divergence-free fitting.



   .. py:method:: fit2D_df()

      2D divergence-free fitting.



   .. py:method:: analyze()

      Perform the DSECS analysis steps.



   .. py:method:: fit1D_cf()

      1D curl-free fitting.



   .. py:method:: fit2D_cf()

      2D curl-free fitting.



   .. py:method:: dump()

      Dump the currents to xarrays.

      :returns: * *dsmag* -- xarray of the results in the magnetic coordinate system.
                * *dsgeo* -- xarray of the results in geographic coordinate system.
                * *fitA* -- xarray with fitted magnetic field for Swarm A
                * *fitC* -- xarray with fitted magnetic field for Swarm C



