Skip to main content

Python Validation Tool for the Ionosphere

Project description

Black circle with lion ionospheric vertical profile

PyVALION (Python VALidation for IONosphere)

PyVALION Package latest release Build Status Documentation Status DOI

PyVALION is a Python-based software package for validating ionospheric electron density model outputs.

For a given day, it downloads ionospheric parameters (such as NmF2, hmF2, B0, and B1) from the Global Ionosphere Radio Observatory (GIRO) and constructs a forward operator (geometry matrix) to compute the model-expected observations. It then calculates residuals between the observed ionospheric parameters and the model predictions and provides visual diagnostics.

A key advantage of PyVALION is its efficiency: if you need to validate multiple model runs on the same grid, the geometry matrix only needs to be computed once. This significantly speeds up and simplifies the validation process.

If you're validating your model across multiple days, you can run PyVALION in a loop and concatenate the residuals into 1-D arrays for broader analysis.

Installation

PyVALION can be installed from PyPI, which handles all dependencies:

pip install PyVALION

Alternatively, you can clone and install it from GitHub:

git clone https://github.com/victoriyaforsythe/PyVALION.git
cd PyVALION
pip install .

See the documentation for details about the required dependencies.

Example Workflow for GIRO Parameter Validation

  1. Create the model output dictionary: Record your model output into a dictionary called model with the following keys: 'NmF2', 'hmF2', 'B0', and 'B1', shaped as [N_time, N_lat, N_lon].

N_time: number of time steps (e.g., 96 for 15-minute resolution)

N_lat: number of geographic latitudes

N_lon: number of geographic longitudes

All arrays must have the same shape. Otherwise, the forward operator G cannot be applied consistently.

  1. Define the units dictionary:
units = {'NmF2': 'm$^{-3}$', 'hmF2': 'km', 'B0': 'km', 'B1': ' '}

Ensure your model output is in these units.

  1. Create the atime array: This array should have N_time elements and must be a list of datetime objects that match the time dimension of your model dictionary. Example for 15-minute resolution:
dtime = datetime.datetime(year, month, day)
atime = pd.to_datetime(np.arange(dtime,
                                 dtime + datetime.timedelta(days=1),
                                 datetime.timedelta(minutes=15)))
  1. Define the latitude array alat: This array must have N_lat elements and match the second dimension in the model dictionary.

  2. Define the longitude array alon: This array must have N_lon elements and match the third dimension in the model dictionary.

  3. Load the list of GIRO ionosondes:

file_ion_name = os.path.join(PyVALION.giro_names_dir, 'GIRO_Ionosondes.p')
giro_name = pickle.load(open(file_ion_name, 'rb'))

If you wish to exclude ionosondes used in your data assimilation, simply modify the giro_name['name'] array.

  1. Download GIRO parameters:
raw_data = PyVALION.library.download_GIRO_parameters(atime[0],
                                                     atime[-1],
                                                     giro_name['name'],
                                                     data_save_dir,
                                                     save_res_dir,
                                                     name_run,
                                                     clean_directory=True,
                                                     filter_CS=90)

data_save_dir: path to save downloaded data

save_res_dir: path to save processed results

name_run: your chosen name for this run

  1. Create the forward operator:
obs_data, obs_units, G, obs_info = PyVALION.library.find_G_and_y(atime,
                                                                 alon,
                                                                 alat,
                                                                 raw_data,
                                                                 save_res_dir,
                                                                 name_run,
                                                                 True)
  1. Compute residuals:
model_data, residuals, model_units, res_ion = PyVALION.library.find_residuals(
    model, G, obs_data, obs_info, units)
  1. Plot results:
# Map of ionosonde locations
PyVALION.plotting.plot_ionosondes(obs_info,
                                  dtime,
                                  save_res_dir,
                                  plot_name='Ionosondes_Map.pdf')

Ionosondes_Map

Histogram of residuals

PyVALION.plotting.plot_histogram(residuals,
                                 model_units,
                                 dtime,
                                 save_res_dir,
                                 plot_name='Residuals.pdf')

Residuals

Mean residuals for each ionosonde

PyVALION.plotting.plot_individual_mean_residuals(res_ion,
                                                 obs_info,
                                                 model_units,
                                                 dtime,
                                                 save_res_dir,
                                                 plot_name='IonRes.pdf')

Residuals

Residuals

Example Workflow for Jason TEC Validation

  1. Create the model output dictionary: Record your model output into a dictionary called model with the following key: 'TEC' shaped as [N_time, N_lat, N_lon].

N_time: number of time steps (e.g., 96 for 15-minute resolution)

N_lat: number of geographic latitudes

N_lon: number of geographic longitudes

  1. Define the units dictionary:
units = {'TEC': 'TECU'}

Ensure your model output is in these units.

  1. Create the atime array: This array should have N_time elements and must be a list of datetime objects that match the time dimension of your model dictionary. Example for 15-minute resolution:
dtime = datetime.datetime(year, month, day)
atime = pd.to_datetime(np.arange(dtime,
                                 dtime + datetime.timedelta(days=1),
                                 datetime.timedelta(minutes=15)))
  1. Define the latitude array alat: This array must have N_lat elements and match the second dimension in the model dictionary.

  2. Define the longitude array alon: This array must have N_lon elements and match the third dimension in the model dictionary.

  3. Download the jason_manifest.txt file (provided by PyVALION) and save locally into data_save_dir. The local manifest will be updated with new THREDDS file locations if available.

data_save_dir: path to save downloaded data

  1. Download all raw Jason TEC data for the validation time: If you need to exclude certain satellites, modify the sat_names array.
sat_names = np.array(["JA2", "JA3"])
raw_data = PyVALION.library.download_Jason_TEC(atime[0],
                                               atime[-1],
                                               data_save_dir,
                                               name_run=name_run,
                                               save_data_option=True,
                                               sat_names=sat_names)

data_save_dir: path to save downloaded data

name_run: your chosen name for this run

  1. Downsample Jason TEC data to match model resolution:
data = PyVALION.library.downsample_Jason_TEC(raw_data,
                                             ddeg,
                                             save_dir=data_save_dir,
                                             name_run=name_run,
                                             save_data_option=True)
  1. Create a forward operator for the Jason TEC dataset using the given model grid:
obs_data, obs_units, G = PyVALION.library.find_Jason_G_and_y(atime,
                                                             alon,
                                                             alat,
                                                             data)
  1. Compute residuals:
model_data, residuals, model_units = PyVALION.library.find_Jason_residuals(model,
                                                                           G,
                                                                           obs_data,
                                                                           units)
  1. Plot results:

Map of residuals

PyVALION.plotting.plot_TEC_residuals_map(obs_data['lat'],
                                         obs_data['lon'],
                                         residuals,
                                         atime[0],
                                         save_option=True,
                                         save_dir=save_img_dir,
                                         plot_name='TEC_Residuals_Map')

Ionosondes_Map

Histogram of residuals

PyVALION.plotting.plot_TEC_residuals_histogram(residuals,
                                               model_units,
                                               atime[0],
                                               save_option=True,
                                               save_dir=save_img_dir,
                                               plot_name='TEC_Residuals')

Residuals

Learn More

See the tutorials folder for examples that validate NmF2, hmF2, and TEC from PyIRI.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyvalion-0.2.0.tar.gz (41.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pyvalion-0.2.0-py3-none-any.whl (31.0 kB view details)

Uploaded Python 3

File details

Details for the file pyvalion-0.2.0.tar.gz.

File metadata

  • Download URL: pyvalion-0.2.0.tar.gz
  • Upload date:
  • Size: 41.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for pyvalion-0.2.0.tar.gz
Algorithm Hash digest
SHA256 379bbf1454dcf453ea4e85e3a531ada19346b177a5369b83b79c748da0c5b663
MD5 1fdb5e606724b90405e423ad2a843860
BLAKE2b-256 e9a254b830f36d7deeed344c985ebdf8dae9c574f07ad2ef64adc63f0ceea531

See more details on using hashes here.

File details

Details for the file pyvalion-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: pyvalion-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 31.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for pyvalion-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 2cd29252b7ddea1be64af18de249a5eb480631b59bdf2cfd579aa55ffda20783
MD5 83db4b51d124f27f07638633e54a134e
BLAKE2b-256 1d20d6bc9a7a81601876b32185cb867d2b2f84295f152e7e6ce7fa29822be765

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page