Source code for spinifex.ionospheric.iri_density

"""Module to get iri density profile"""

from __future__ import annotations

import astropy.units as u
import numpy as np
from numpy.typing import NDArray
from PyIRI import coeff_dir
from PyIRI.main_library import IRI_density_1day

from spinifex.geometry.get_ipp import IPP
from spinifex.times import get_unique_days

[docs] IRI_HEIGHTS = np.linspace(50, 20000, 100) * u.km
[docs] def get_profile(ipp: IPP) -> NDArray[np.float32]: """Get the normalized electron density profile for all times an altitudes in ipp Parameters ---------- ipp : IPP ionospheric piercepoints Returns ------- NDArray normalied density profile per time """ unique_days = get_unique_days(times=ipp.times) edp = np.zeros(ipp.loc.shape, dtype=float) # electron density profile altitudes = ipp.loc.height.to(u.km).value longitudes = ipp.loc.lon.deg latitudes = ipp.loc.lat.deg f107 = 100 ccir_or_ursi = 0 for u_day in unique_days: year, month, day, _, _, _ = u_day.ymdhms indices = np.floor(ipp.times.mjd) == np.floor(u_day.mjd) index_nr = np.where(indices)[0] aalt = altitudes[indices] # iri input array of heights hidx = np.argmin( np.abs(aalt - 350), axis=1 ) # use lon lat closest to altitude of 350 km for profile alon = longitudes[indices, hidx] # iri input array of longitudes alat = latitudes[indices, hidx] # iri input array of latitude ahr = ipp.times[indices].ymdhms.hour # IRI_density_1day treats lon/lat and hr as two separate arrays with independent lengths # I do not see another solution than to loop for itime, tmidx in zip(range(ahr.shape[0]), index_nr): _, _, _, _, _, _, edpi = IRI_density_1day( year, month, day, ahr[itime : itime + 1], alon[itime : itime + 1], alat[itime : itime + 1], aalt[itime], f107, coeff_dir, ccir_or_ursi, ) edp[tmidx] = edpi.squeeze() edp /= np.sum(edp, axis=1, keepdims=True) return edp