OSTk Cross-Platform Validation Against GMAT/Orekit (Field Data Generation Scenario 1)

This tutorial demonstrates how to compare OSTk field data generation (such as gravity field or atmosphere "field") against other tools. This example will be comparing atmospheric density generated at a sweep of latitudes, longitudes, and altitudes.

import numpy as np
import pandas as pd
import csv
import os

from ostk.physics.unit import Length
from ostk.physics.unit import Angle
from ostk.physics.time import Instant
from ostk.physics.coordinate.spherical import LLA

from ostk.physics.environment.atmospheric import Earth as EarthAtmosphericModel
<frozen importlib._bootstrap>:241: FutureWarning: pybind11-bound class 'ostk.physics.coordinate.frame.provider.Dynamic' is using an old-style placement-new '__init__' which has been deprecated. See the upgrade guide in pybind11's docs. This message is only visible when compiled in debug mode.

Set up and Read In Comparison Files

Define array inputs that can be changed to include/exclude gmat/orekit result comparisons

filenames = [
    "gmat_physics/scenario001-field-data-generation.csv",
    "orekit_physics/scenario001-field-data-generation.csv",
]
comparisons_to_perform = [
    ("OSTk - GMAT", [0, 1]),
    ("OSTk - OREKIT", [0, 2]),
    ("OREKIT - GMAT", [2, 1]),
]

multiplication_factors = [1.0e-9, 1.0]

Setup Comparison Scenario in OSTk

Define the atmospheric model

atmos_model = EarthAtmosphericModel(EarthAtmosphericModel.Type.Exponential)

Create a latitude/longitude/altitude grid from scenario files

latitudes = [-80]
longitudes = [-180]
altitudes = list(range(230000, 980000 + 50000, 50000))
ostk_densities = np.zeros(
    (
        len(latitudes),
        len(longitudes),
        len(altitudes),
    )
)

for k, lat in enumerate(latitudes):
    for j, lon in enumerate(longitudes):
        for i, alt in enumerate(altitudes):
            lla = LLA(
                Angle.degrees(float(lat)),
                Angle.degrees(float(lon)),
                Length.meters(float(alt)),
            )

            # Call the density function
            ostk_densities[k][j][i] = atmos_model.get_density_at(lla, Instant.J2000())

ostk_densities = ostk_densities[0][0].tolist()

Process Cross Platform Results

Read in reference data from CSV file for GMAT and Orekit

all_comparison_densities = [ostk_densities]

for ind, filename in enumerate(filenames):
    with open(f"{os.getcwd()}/data/{filename}") as csvfile:
        reader = csv.DictReader(csvfile)
        comparison_densities = []
        for row in reader:
            density_iter = float(row[reader.fieldnames[4]])

            comparison_densities.append(density_iter * multiplication_factors[ind])

    all_comparison_densities.append(comparison_densities)
---------------------------------------------------------------------------
FileNotFoundError                         Traceback (most recent call last)
Cell In[6], line 4
      1 all_comparison_densities = [ostk_densities]
      3 for ind, filename in enumerate(filenames):
----> 4     with open(f"{os.getcwd()}/data/{filename}") as csvfile:
      5         reader = csv.DictReader(csvfile)
      6         comparison_densities = []

File /usr/local/lib/python3.11/dist-packages/IPython/core/interactiveshell.py:324, in _modified_open(file, *args, **kwargs)
    317 if file in {0, 1, 2}:
    318     raise ValueError(
    319         f"IPython won't let you open fd={file} by default "
    320         "as it is likely to crash IPython. If you know what you are doing, "
    321         "you can use builtins' open."
    322     )
--> 324 return io_open(file, *args, **kwargs)

FileNotFoundError: [Errno 2] No such file or directory: '/app/docs/_notebooks/data/gmat_physics/scenario001-field-data-generation.csv'
def to_dataframe(alt_ind, comparison_pairing):
    first_tool = comparison_pairing[0]
    second_tool = comparison_pairing[1]

    return [
        altitudes[alt_ind],
        all_comparison_densities[first_tool][alt_ind]
        - all_comparison_densities[second_tool][alt_ind],
        (
            all_comparison_densities[first_tool][alt_ind]
            - all_comparison_densities[second_tool][alt_ind]
        )
        / all_comparison_densities[first_tool][alt_ind],
    ]
densities_compared = [
    [
        to_dataframe(alt_ind, comparisons_to_perform[comparison_index][-1])
        for alt_ind in range(0, len(altitudes))
    ]
    for comparison_index in range(0, len(all_comparison_densities))
]
densities_compared_df = [
    pd.DataFrame(
        densities_compared[comparison_index],
        columns=[
            "Alt(m)",
            f"{comparisons_to_perform[comparison_index][0]} Density Error (kg/m^3)",
            f"{comparisons_to_perform[comparison_index][0]} Relative Density Error (fractional)",
        ],
    )
    for comparison_index in range(0, len(all_comparison_densities))
]
ostk_densities_df = pd.DataFrame(
    [[altitudes[alt], ostk_densities[alt]] for alt in range(0, len(altitudes))],
    columns=["Alt(m)", "OSTk Density Value (kg/m^3)"],
)
ostk_densities_df
Alt(m) OSTk Density Value (kg/m^3)
0 230000 1.242551e-10
1 280000 3.751106e-11
2 330000 1.382000e-11
3 380000 5.421171e-12
4 430000 2.230839e-12
5 480000 9.679164e-13
6 530000 4.354141e-13
7 580000 1.989132e-13
8 630000 9.576189e-14
9 680000 4.774266e-14
10 730000 2.576600e-14
11 780000 1.466037e-14
12 830000 9.197168e-15
13 880000 6.157928e-15
14 930000 4.444090e-15
15 980000 3.371671e-15
densities_compared_df[0]
Alt(m) OSTk - GMAT Density Error (kg/m^3) OSTk - GMAT Relative Density Error (fractional)
0 230000 2.344098e-15 0.000019
1 280000 5.765060e-16 0.000015
2 330000 1.803896e-16 0.000013
3 380000 7.119957e-17 0.000013
4 430000 2.668680e-17 0.000012
5 480000 1.113858e-17 0.000012
6 530000 4.775598e-18 0.000011
7 580000 2.181669e-18 0.000011
8 630000 9.331523e-19 0.000010
9 680000 4.652286e-19 0.000010
10 730000 2.034142e-19 0.000008
11 780000 1.157389e-19 0.000008
12 830000 5.165276e-20 0.000006
13 880000 3.458390e-20 0.000006
14 930000 1.718231e-20 0.000004
15 980000 1.303598e-20 0.000004
densities_compared_df[1]
Alt(m) OSTk - OREKIT Density Error (kg/m^3) OSTk - OREKIT Relative Density Error (fractional)
0 230000 -2.584939e-26 -2.080348e-16
1 280000 6.462349e-27 1.722785e-16
2 330000 -4.846761e-27 -3.507064e-16
3 380000 0.000000e+00 0.000000e+00
4 430000 0.000000e+00 0.000000e+00
5 480000 0.000000e+00 0.000000e+00
6 530000 -5.048710e-29 -1.159519e-16
7 580000 0.000000e+00 0.000000e+00
8 630000 0.000000e+00 0.000000e+00
9 680000 0.000000e+00 0.000000e+00
10 730000 6.310887e-30 2.449308e-16
11 780000 0.000000e+00 0.000000e+00
12 830000 0.000000e+00 0.000000e+00
13 880000 0.000000e+00 0.000000e+00
14 930000 0.000000e+00 0.000000e+00
15 980000 -3.944305e-31 -1.169837e-16
densities_compared_df[2]
Alt(m) OREKIT - GMAT Density Error (kg/m^3) OREKIT - GMAT Relative Density Error (fractional)
0 230000 2.344098e-15 0.000019
1 280000 5.765060e-16 0.000015
2 330000 1.803896e-16 0.000013
3 380000 7.119957e-17 0.000013
4 430000 2.668680e-17 0.000012
5 480000 1.113858e-17 0.000012
6 530000 4.775598e-18 0.000011
7 580000 2.181669e-18 0.000011
8 630000 9.331523e-19 0.000010
9 680000 4.652286e-19 0.000010
10 730000 2.034142e-19 0.000008
11 780000 1.157389e-19 0.000008
12 830000 5.165276e-20 0.000006
13 880000 3.458390e-20 0.000006
14 930000 1.718231e-20 0.000004
15 980000 1.303598e-20 0.000004