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 |