So, I’ve slapped something together in python to create a list of dictionary of orbit times with respect to the circumference
import pandas as pd
import numpy as np
def calculate_periods(df:pd.DataFrame) -> pd.DataFrame:
df['orbits'] = np.power((df[['x', 'y', 'z']] - df[['x', 'y', 'z']].shift(1)).prod(axis=1).abs(), 1/3).cumsum() // (2.25 * np.pi * np.power(df_tst[['x', 'y', 'z']].prod(axis=1).abs(), 1/3).mean()) # surface circumference of the earth is about 40075 km, not necessarily orbit circumference
df['t_delta'] = (df['Epoch'] - df['Epoch'].shift(1)).dt.total_seconds()
df_r = df[['t_delta', 'orbits']].groupby(['orbits']).sum()
df_r['e2'] = df[['e', 'orbits']].groupby(['orbits']).last()
df_r['e1'] = df_r['e2'].shift(1)
df_r['e1'].iloc[0] = df['e'].iloc[0]
# df_r['e1'] = df[['e', 'orbits']].groupby(['orbits']).first()
return df_r[['t_delta', 'e1', 'e2']]
def calculate_lead_times(df:pd.DataFrame) -> list[dict]:
df_r = calculate_periods(df)
return df_r.apply(lambda x:{
"interval":f"{x['e1']}/{x['e2']}",
"epoch":x['e1'],
"number":[
0, x['t_delta'],
x['t_delta'], 0
]
}, axis=1).tolist()
def calculate_trail_times(df:pd.DataFrame) -> list[dict]:
df_r = calculate_periods(df)
return df_r.apply(lambda x:{
"interval":f"{x['e1']}/{x['e2']}",
"epoch":x['e1'],
"number":[
0, 0,
x['t_delta'], x['t_delta']
]
}, axis=1).tolist()
It starts by (site note, ‘Epoch’ is a datetime object and ‘e’ a string epoch in the format Cesium likes):
- calculating the orbit length by cumulatively summing the absolute length of vectors between points
- integer dividing it by the orbit circumference calculated from the mean satellite radius vector which is then used to calculate the “mean orbit circumference”. I know it should be 2 * pi * r but 2 tends to fall a bit short because, calculating using a mean value, and 2.25 gives a bit of overlap.
- That gives a count of what orbit each point is in.
- Calculate the change in time ‘t_delta’ in seconds
- Group the data by orbits and:
- Sum the ‘t_delta’ values by orbit so you get how long each orbit is in time
- Get the last string epoch in the orbit.
- Set the first string epoch by shifting the last string epoch.
- Set the first element of the string epoch (previously a NaN object) to the first element in the string epochs.
- Then I return the newly created dataframe in the order I prefer it.
- The functions
calculate_lead_times
andcalculate_trail_times
just reformat the data into dictionaries and return the dictionaries as a list of dictionaries.
The result looks like this:
Edit:
The data from calculate_periods looks like:
orbits | t_delta | e1 | e2 |
---|---|---|---|
0 | 5940 | 2023-07-01T01:39:00Z | 2023-07-01T03:18:00Z |
1 | 5940 | 2023-07-01T03:18:00Z | 2023-07-01T04:57:00Z |
2 | 5940 | 2023-07-01T04:57:00Z | 2023-07-01T06:36:00Z |