Source code for spinifex.ionospheric.tec_data

"""data objects and options for ionospheric models"""

from __future__ import annotations

from enum import Enum
from pathlib import Path
from typing import Literal, NamedTuple

import astropy.units as u
import numpy as np
from numpy.typing import NDArray
from pydantic import Field

from spinifex.options import Options

[docs] SOLUTION = Literal["final", "rapid"]
[docs] CENTER_NAMES = { "cod", "esa", "igs", "jpl", "upc", "irt", "uqr", }
[docs] DEFAULT_TIME_RESOLUTIONS: dict[str, u.Quantity] = { "cod": 1 * u.hour, "esa": 2 * u.hour, "igs": 2 * u.hour, "jpl": 2 * u.hour, "upc": 2 * u.hour, "irt": 2 * u.hour, "uqr": 15 * u.min, # Chapman only provides 15 minute resolution right now }
assert set(DEFAULT_TIME_RESOLUTIONS.keys()) == CENTER_NAMES, ( "Time resolutions must be defined for all analysis centres" )
[docs] NAME_SWITCH_WEEK = 2238 # GPS Week where the naming convention changed
[docs] class Servers(str, Enum):
[docs] CDDIS = ("cddis", "https://cddis.nasa.gov/archive/gnss/products/ionex")
[docs] CHAPMAN = ("chapman", "http://chapman.upc.es/tomion/rapid")
[docs] IGSIONO = ("igsiono", "ftp://igs-final.man.olsztyn.pl")
def __new__(cls, value: str, _url: str) -> Servers: obj = str.__new__(cls, value) obj._value_ = value obj._url = _url # type: ignore[attr-defined] return obj @property
[docs] def url(self) -> str: return str(self._url) # type: ignore[attr-defined]
@classmethod
[docs] def get_url(cls, server: Servers) -> str: return str(server.url) # Retrieve URL given an Enum value
[docs] class IonexOptions(Options): """Options for ionex model"""
[docs] server: Servers = Field( Servers.CHAPMAN, description="Server to download ionex files from" )
[docs] prefix: str = Field("uqr", description="Analysis centre prefix")
[docs] url_stem: str | None = Field(None, description="URL stem")
[docs] time_resolution: u.Quantity | None = Field( None, description="Time resolution for ionex files" )
[docs] solution: SOLUTION = Field("final", description="Solution type")
[docs] output_directory: Path | None = Field( None, description="Output directory for ionex files" )
[docs] correct_uqrg_rms: bool = Field( True, description="Correct overestimated rms of uqr maps" )
[docs] height: u.Quantity = Field( 350 * u.km, description="altitude of single layer ionosphere" )
[docs] remove_midnight_jumps: bool = Field( True, description="mitigate midnight jumps in the ionex files by inserting the data of the next day", )
[docs] class TomionOptions(Options): """Options for tomion model"""
[docs] output_directory: Path | None = Field( None, description="Output directory for tomion files" )
[docs] class ElectronDensity(NamedTuple): """object containing interpolated electron density values and their estimated uncertainty"""
[docs] electron_density: NDArray[np.float64]
"""electron density in TECU"""
[docs] electron_density_error: NDArray[np.float64]
"""uncertainty in TECU"""