open-space-toolkit-astrodynamics 10.0.0__py310-none-manylinux2014_x86_64.whl → 10.1.0__py310-none-manylinux2014_x86_64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: open-space-toolkit-astrodynamics
3
- Version: 10.0.0
3
+ Version: 10.1.0
4
4
  Summary: Orbit, attitude, access.
5
5
  Author: Open Space Collective
6
6
  Author-email: contact@open-space-collective.org
@@ -2,9 +2,10 @@ ostk/__init__.py,sha256=epnVn2PwdQkUDZ1msqBRO5nEZIOUBIq-IfK3IlNPijE,21
2
2
  ostk/astrodynamics/OpenSpaceToolkitAstrodynamicsPy.cpython-310-x86_64-linux-gnu.so,sha256=Nyt1LHvXCuRprozBe4r0J9g2ZhaoD8xJd6GUAn6xJAg,2320256
3
3
  ostk/astrodynamics/__init__.py,sha256=3gWyqFIbhAfcdeMhmfBPQPlPQTmaOzm-6flkJe745Zk,251
4
4
  ostk/astrodynamics/converters.py,sha256=vsm7SHdlPIyIxW1h5ZGAizl284koGaRmyPCu--AQJfA,4670
5
+ ostk/astrodynamics/dataframe.py,sha256=njimcfT2cvnSOp9eBR1Ej-LuYpXbVieAVEBk2tYW4Vg,18761
5
6
  ostk/astrodynamics/display.py,sha256=KiEGsjNftQfoUe-HfZeYpQQQ4TkaEnxtEl6p5_LX5f0,6303
6
7
  ostk/astrodynamics/libopen-space-toolkit-astrodynamics.so.10,sha256=JKGGWpUWmd9uKuF4Xgd7y3j5MaQggDNV1w3MFKEyNLY,81543536
7
- ostk/astrodynamics/utilities.py,sha256=Jw-AT9CU-a2ERDDSNp7rEhZQKhbmZSCr2flGti9XysU,4813
8
+ ostk/astrodynamics/utilities.py,sha256=Yu5Yydq22gNIHi6ylqeujDENcueb1JfUE6d93h1m9XE,4795
8
9
  ostk/astrodynamics/viewer.py,sha256=8UxqsvU5wui7gPUwxXaKcIB-509NJiih9Df3mQgXyXY,11776
9
10
  ostk/astrodynamics/pytrajectory/__init__.py,sha256=epnVn2PwdQkUDZ1msqBRO5nEZIOUBIq-IfK3IlNPijE,21
10
11
  ostk/astrodynamics/pytrajectory/pystate.py,sha256=ByOq8szit74xQ-pnLz0uGGxM6Jqfa17dFJyFB8qIXUg,1033
@@ -12,7 +13,8 @@ ostk/astrodynamics/test/__init__.py,sha256=epnVn2PwdQkUDZ1msqBRO5nEZIOUBIq-IfK3I
12
13
  ostk/astrodynamics/test/conftest.py,sha256=fsdUQnLxyfvBzfaSCkgipkPIhkPHchQqbeAro1pF648,2717
13
14
  ostk/astrodynamics/test/test_access.py,sha256=MCBsUPtuVm7NgHZR0z0DpWnPZ_qBu4aRhLI2PnRNUYs,3940
14
15
  ostk/astrodynamics/test/test_converters.py,sha256=hnvqOCtUGrzBvjv7GnmaRdl2mlKM3eWuJUspe305B-A,12114
15
- ostk/astrodynamics/test/test_display.py,sha256=YnwnqXh-a1OODN2YqHr-l5-q1DrgZ-P4pOY5gxJp4II,3732
16
+ ostk/astrodynamics/test/test_dataframe.py,sha256=IJMOODzTVYtiPxekmltH6lOMArPXbHwSEAl-jg0Ab2g,28414
17
+ ostk/astrodynamics/test/test_display.py,sha256=Ykvw2rUWWw8jsX0Suy11X27bHjwm_ira__xj0ZyHHxw,3672
16
18
  ostk/astrodynamics/test/test_event_condition.py,sha256=mhMTH7wAoYFWRYt_8l2d1vjNPrFhVjMAEET4INLCVXY,1472
17
19
  ostk/astrodynamics/test/test_import.py,sha256=py_hALBR0IYuUzv9dfgQZzrrLHJIpnyKvt3Oi1XBqCg,1251
18
20
  ostk/astrodynamics/test/test_root_solver.py,sha256=hQ8O6g-WP49gZH_H3Rdufv0F0gQorpzJyIcjBGGUQ34,1831
@@ -86,13 +88,13 @@ ostk/astrodynamics/test/trajectory/orbit/models/sgp4/__init__.py,sha256=epnVn2Pw
86
88
  ostk/astrodynamics/test/trajectory/orbit/models/sgp4/test_tle.py,sha256=jkyRr5NJQMaSpI3ey7cKcH0E-BlalaUlf_mZPYTSow8,11482
87
89
  ostk/astrodynamics/test/trajectory/state/test_coordinate_broker.py,sha256=ho5FBfB3IvIjfQl7EYoIN1KBuH9lu76IiNMuweq8cqg,2844
88
90
  ostk/astrodynamics/test/trajectory/state/test_coordinate_subset.py,sha256=KjltLEPbxMfyebwjG5mulyGCT5INtiItPq6ID6sP9jI,1289
89
- ostk/astrodynamics/test/trajectory/state/test_numerical_solver.py,sha256=_t4OKnYLzTjOhSkVTgT2307DQkz_DnGxqqLx8mmzLRA,9389
91
+ ostk/astrodynamics/test/trajectory/state/test_numerical_solver.py,sha256=PcLU8XTiDHZ-yplYvHZFX32yTUoua9MhKrMmQPINl9w,9386
90
92
  ostk/astrodynamics/test/trajectory/state/coordinate_subset/test_angular_velocity.py,sha256=xjyGREKpxDuT8gjtBPkV4osfW-6UyWv9hgvBXZVb_wk,625
91
93
  ostk/astrodynamics/test/trajectory/state/coordinate_subset/test_attitude_quaternion.py,sha256=UEu9ApzQLmT87eeISw6_gcHTlX-4b2scIvHz-uE1p_c,393
92
94
  ostk/astrodynamics/test/trajectory/state/coordinate_subset/test_cartesian_position.py,sha256=XvHdk1KjacTwtkgx2jUAc9I9N3nvjPDv03FAanpv8jQ,2702
93
95
  ostk/astrodynamics/test/trajectory/state/coordinate_subset/test_cartesian_velocity.py,sha256=-kd5TZO5TICihbkqDTew2i_tDpggdpe3Yf23046FATM,3057
94
- open_space_toolkit_astrodynamics-10.0.0.dist-info/METADATA,sha256=kTX3aUOHCyRMiuocFwxsUbTMFfv8uFIGSqlSKQAK1KU,1916
95
- open_space_toolkit_astrodynamics-10.0.0.dist-info/WHEEL,sha256=EfzGwk6HazeuFg6dmyxdAa9hqpFBtmJ_haGsqhCVSCQ,110
96
- open_space_toolkit_astrodynamics-10.0.0.dist-info/top_level.txt,sha256=zOR18699uDYnafgarhL8WU_LmTZY_5NVqutv-flp_x4,5
97
- open_space_toolkit_astrodynamics-10.0.0.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
98
- open_space_toolkit_astrodynamics-10.0.0.dist-info/RECORD,,
96
+ open_space_toolkit_astrodynamics-10.1.0.dist-info/METADATA,sha256=4JCiBdx8g8GootL2UgFMCtDDgnNZTRG7yh3IxMaOuNU,1916
97
+ open_space_toolkit_astrodynamics-10.1.0.dist-info/WHEEL,sha256=EfzGwk6HazeuFg6dmyxdAa9hqpFBtmJ_haGsqhCVSCQ,110
98
+ open_space_toolkit_astrodynamics-10.1.0.dist-info/top_level.txt,sha256=zOR18699uDYnafgarhL8WU_LmTZY_5NVqutv-flp_x4,5
99
+ open_space_toolkit_astrodynamics-10.1.0.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
100
+ open_space_toolkit_astrodynamics-10.1.0.dist-info/RECORD,,
@@ -0,0 +1,477 @@
1
+ # Copyright © Loft Orbital Solutions Inc.
2
+
3
+ import numpy as np
4
+
5
+ import pandas as pd
6
+
7
+ from ostk.mathematics.curve_fitting import Interpolator
8
+
9
+ from ostk.physics.environment.object import Celestial
10
+ from ostk.physics.environment.object.celestial import Earth
11
+ from ostk.physics.time import Instant
12
+ from ostk.physics.coordinate import Frame
13
+
14
+ from ostk.astrodynamics.converters import coerce_to_datetime
15
+ from ostk.astrodynamics.converters import coerce_to_instant
16
+ from ostk.astrodynamics.trajectory import State
17
+ from ostk.astrodynamics.trajectory import StateBuilder
18
+ from ostk.astrodynamics.trajectory import Orbit
19
+ from ostk.astrodynamics.trajectory.state import CoordinateSubset
20
+ from ostk.astrodynamics.trajectory.state.coordinate_subset import CartesianPosition
21
+ from ostk.astrodynamics.trajectory.state.coordinate_subset import CartesianVelocity
22
+ from ostk.astrodynamics.trajectory.state.coordinate_subset import AttitudeQuaternion
23
+ from ostk.astrodynamics.trajectory.state.coordinate_subset import AngularVelocity
24
+ from ostk.astrodynamics.trajectory.orbit.model import Tabulated as TabulatedOrbit
25
+ from ostk.astrodynamics.flight import Profile
26
+ from ostk.astrodynamics.flight.profile.model import Tabulated as TabulatedProfile
27
+
28
+
29
+ DEFAULT_REFERENCE_FRAME: Frame = Frame.GCRF()
30
+ DEFAULT_TIME_COLUMN: str = "Timestamp"
31
+ DEFAULT_POSITION_COLUMNS_FORMAT: list[str] = [
32
+ "r_{frame}_x",
33
+ "r_{frame}_y",
34
+ "r_{frame}_z",
35
+ ]
36
+ DEFAULT_VELOCITY_COLUMNS_FORMAT: list[str] = [
37
+ "v_{frame}_x",
38
+ "v_{frame}_y",
39
+ "v_{frame}_z",
40
+ ]
41
+ DEFAULT_ATTITUDE_COLUMNS_FORMAT: list[str] = [
42
+ "q_B_{frame}_x",
43
+ "q_B_{frame}_y",
44
+ "q_B_{frame}_z",
45
+ "q_B_{frame}_s",
46
+ ]
47
+ DEFAULT_ANGULAR_VELOCITY_COLUMNS_FORMAT: list[str] = [
48
+ "w_B_{frame}_in_B_x",
49
+ "w_B_{frame}_in_B_y",
50
+ "w_B_{frame}_in_B_z",
51
+ ]
52
+ CARTESIAN_POSITION_SUBSET: CartesianPosition = CartesianPosition.default()
53
+ CARTESIAN_VELOCITY_SUBSET: CartesianVelocity = CartesianVelocity.default()
54
+ ATTITUDE_QUATERNION_SUBSET: AttitudeQuaternion = AttitudeQuaternion.default()
55
+ ANGULAR_VELOCITY_SUBSET: AngularVelocity = AngularVelocity.default()
56
+
57
+ DEFAULT_INTERPOLATION_TYPE: Interpolator.Type = Interpolator.Type.BarycentricRational
58
+
59
+
60
+ def generate_column_names(
61
+ reference_frame: Frame,
62
+ time_column: str | None = None,
63
+ position_columns: list[str] | None = None,
64
+ velocity_columns: list[str] | None = None,
65
+ attitude_columns: list[str] | None = None,
66
+ angular_velocity_columns: list[str] | None = None,
67
+ ) -> tuple[str, list[str], list[str], list[str], list[str]]:
68
+ """
69
+ Generate column names for a DataFrame containing orbit data.
70
+
71
+ Args:
72
+ reference_frame (Frame): Reference frame.
73
+ time_column (str | None): Name of the column containing the time data in [UTC].
74
+ position_columns (list[str] | None): List of column names containing the position data in [m].
75
+ velocity_columns (list[str] | None): List of column names containing the velocity data in [m/s].
76
+ attitude_columns (list[str] | None): List of column names containing the attitude data in [x, y, z, s] form.
77
+ angular_velocity_columns (list[str] | None): List of column names containing the angular velocity data in [rad/s].
78
+
79
+ Returns:
80
+ tuple[str, list[str], list[str], list[str], list[str]: Tuple containing the column names.
81
+ """
82
+ reference_frame_name: str = reference_frame.get_name()
83
+
84
+ return (
85
+ time_column or DEFAULT_TIME_COLUMN,
86
+ position_columns
87
+ or [
88
+ column.format(frame=reference_frame_name)
89
+ for column in DEFAULT_POSITION_COLUMNS_FORMAT
90
+ ],
91
+ velocity_columns
92
+ or [
93
+ column.format(frame=reference_frame_name)
94
+ for column in DEFAULT_VELOCITY_COLUMNS_FORMAT
95
+ ],
96
+ attitude_columns
97
+ or [
98
+ column.format(frame=reference_frame_name)
99
+ for column in DEFAULT_ATTITUDE_COLUMNS_FORMAT
100
+ ],
101
+ angular_velocity_columns
102
+ or [
103
+ column.format(frame=reference_frame_name)
104
+ for column in DEFAULT_ANGULAR_VELOCITY_COLUMNS_FORMAT
105
+ ],
106
+ )
107
+
108
+
109
+ def generate_states_from_dataframe(
110
+ dataframe: pd.DataFrame,
111
+ reference_frame: Frame | None = None,
112
+ time_column: str | None = None,
113
+ position_columns: list[str] | None = None,
114
+ velocity_columns: list[str] | None = None,
115
+ attitude_columns: list[str] | None = None,
116
+ angular_velocity_columns: list[str] | None = None,
117
+ output_frame: Frame | None = None,
118
+ ) -> list[State]:
119
+ """
120
+ Generate a list of OSTk States from a Pandas DataFrame.
121
+
122
+ Args:
123
+ dataframe (pd.DataFrame): Pandas DataFrame containing the orbit data.
124
+ reference_frame (Frame | None, optional): Reference frame of the states in the dataframe.
125
+ time_column (str | None, optional): Name of the column containing the time data in [UTC].
126
+ position_columns (list[str] | None, optional): List of column names containing the position data in [m].
127
+ velocity_columns (list[str] | None, optional): List of column names containing the velocity data in [m/s].
128
+ attitude_columns (list[str] | None, optional): List of column names containing the attitude data in [x, y, z, s] form.
129
+ angular_velocity_columns (list[str] | None, optional): List of column names containing the angular velocity data in [rad/s].
130
+ output_frame (Frame | None, optional): Output frame for the states.
131
+
132
+ Returns:
133
+ list[State]: List of OSTk States.
134
+ """
135
+
136
+ reference_frame = reference_frame or DEFAULT_REFERENCE_FRAME
137
+
138
+ output_frame = output_frame or reference_frame
139
+
140
+ (
141
+ time_column,
142
+ position_columns,
143
+ velocity_columns,
144
+ attitude_columns,
145
+ angular_velocity_columns,
146
+ ) = generate_column_names(
147
+ reference_frame=reference_frame,
148
+ time_column=time_column,
149
+ position_columns=position_columns,
150
+ velocity_columns=velocity_columns,
151
+ attitude_columns=attitude_columns,
152
+ angular_velocity_columns=angular_velocity_columns,
153
+ )
154
+
155
+ if not set(position_columns).issubset(dataframe.columns):
156
+ raise ValueError("Position columns are not present in the DataFrame.")
157
+
158
+ if not set(velocity_columns).issubset(dataframe.columns):
159
+ raise ValueError("Velocity columns are not present in the DataFrame.")
160
+
161
+ # check if the dataframe contains a timestamp column
162
+ has_timestamp: bool = time_column in dataframe.columns
163
+
164
+ # check if the dataframe contains attitude
165
+ has_attitude: bool = set(attitude_columns).issubset(dataframe.columns)
166
+
167
+ # check if the dataframe contains angular velocity
168
+ has_angular_velocity: bool = set(angular_velocity_columns).issubset(dataframe.columns)
169
+
170
+ coordinate_subsets = [
171
+ CARTESIAN_POSITION_SUBSET,
172
+ CARTESIAN_VELOCITY_SUBSET,
173
+ ]
174
+
175
+ if has_attitude:
176
+ coordinate_subsets.extend([ATTITUDE_QUATERNION_SUBSET])
177
+
178
+ if has_angular_velocity:
179
+ coordinate_subsets.extend([ANGULAR_VELOCITY_SUBSET])
180
+
181
+ state_builder: StateBuilder = StateBuilder(
182
+ frame=reference_frame,
183
+ coordinate_subsets=coordinate_subsets,
184
+ )
185
+
186
+ states: list[State] = []
187
+ for index, row in dataframe.to_dict("index").items():
188
+
189
+ coordinates: list[float] = [
190
+ *[row[column] for column in position_columns],
191
+ *[row[column] for column in velocity_columns],
192
+ ]
193
+
194
+ if has_attitude:
195
+ coordinates.extend([row[column] for column in attitude_columns])
196
+
197
+ if has_angular_velocity:
198
+ coordinates.extend([row[column] for column in angular_velocity_columns])
199
+
200
+ states.append(
201
+ state_builder.build(
202
+ instant=coerce_to_instant(
203
+ row[time_column] if has_timestamp else index,
204
+ ),
205
+ coordinates=coordinates,
206
+ ).in_frame(output_frame)
207
+ )
208
+
209
+ return states
210
+
211
+
212
+ def generate_dataframe_from_states(
213
+ states: list[State],
214
+ reference_frame: Frame | None = None,
215
+ time_column: str | None = None,
216
+ position_columns: list[str] | None = None,
217
+ velocity_columns: list[str] | None = None,
218
+ attitude_columns: list[str] | None = None,
219
+ angular_velocity_columns: list[str] | None = None,
220
+ set_time_index: bool = True,
221
+ ) -> pd.DataFrame:
222
+ """
223
+ Generate a Pandas DataFrame from a list of OSTk States.
224
+
225
+ Args:
226
+ states (list[State]): List of OSTk States.
227
+ reference_frame (Frame | None, optional): The desired reference frame.
228
+ time_column (str | None, optional): Name of the column containing the time data in [UTC].
229
+ position_columns (list[str] | None, optional): List of column names containing the position data in [m].
230
+ velocity_columns (list[str] | None, optional): List of column names containing the velocity data in [m/s].
231
+ attitude_columns (list[str] | None, optional): List of column names containing the attitude data in [x, y, z, s] form.
232
+ angular_velocity_columns (list[str] | None, optional): List of column names containing the angular velocity data in [rad/s].
233
+ set_time_index (bool, optional): Whether to set the time column as the index. Defaults to True.
234
+
235
+ Returns:
236
+ pd.DataFrame: Pandas DataFrame containing the orbit data.
237
+ """
238
+ has_attitude: bool = states[0].has_subset(ATTITUDE_QUATERNION_SUBSET)
239
+ has_angular_velocity: bool = states[0].has_subset(ANGULAR_VELOCITY_SUBSET)
240
+
241
+ reference_frame = reference_frame or DEFAULT_REFERENCE_FRAME
242
+
243
+ (
244
+ time_column,
245
+ position_columns,
246
+ velocity_columns,
247
+ attitude_columns,
248
+ angular_velocity_columns,
249
+ ) = generate_column_names(
250
+ reference_frame=reference_frame,
251
+ time_column=time_column,
252
+ position_columns=position_columns,
253
+ velocity_columns=velocity_columns,
254
+ attitude_columns=attitude_columns,
255
+ angular_velocity_columns=angular_velocity_columns,
256
+ )
257
+
258
+ if len(position_columns) != 3:
259
+ raise ValueError("Position columns must be a list of length 3.")
260
+
261
+ if len(velocity_columns) != 3:
262
+ raise ValueError("Velocity columns must be a list of length 3.")
263
+
264
+ if len(attitude_columns) != 4:
265
+ raise ValueError("Attitude columns must be a list of length 4.")
266
+
267
+ if len(angular_velocity_columns) != 3:
268
+ raise ValueError("Angular velocity columns must be a list of length 3.")
269
+
270
+ data: list[dict] = []
271
+
272
+ for state in states:
273
+ state = state.in_frame(reference_frame)
274
+
275
+ datum: dict = {
276
+ time_column: coerce_to_datetime(state.get_instant()),
277
+ **_get_entry_from_state(state, position_columns, CARTESIAN_POSITION_SUBSET),
278
+ **_get_entry_from_state(state, velocity_columns, CARTESIAN_VELOCITY_SUBSET),
279
+ }
280
+
281
+ if has_attitude:
282
+ datum.update(
283
+ _get_entry_from_state(state, attitude_columns, ATTITUDE_QUATERNION_SUBSET)
284
+ )
285
+ if has_angular_velocity:
286
+ datum.update(
287
+ _get_entry_from_state(
288
+ state, angular_velocity_columns, ANGULAR_VELOCITY_SUBSET
289
+ )
290
+ )
291
+
292
+ data.append(datum)
293
+
294
+ dataframe: pd.DataFrame = pd.DataFrame(data)
295
+ if set_time_index:
296
+ dataframe.set_index(time_column, inplace=True)
297
+
298
+ return dataframe
299
+
300
+
301
+ def generate_orbit_from_dataframe(
302
+ dataframe: pd.DataFrame,
303
+ central_body: Celestial = Earth.default(),
304
+ reference_frame: Frame | None = None,
305
+ time_column: str | None = None,
306
+ position_columns: list[str] | None = None,
307
+ velocity_columns: list[str] | None = None,
308
+ initial_revolution_number: int = 1,
309
+ interpolation_type: Interpolator.Type | None = None,
310
+ output_frame: Frame | None = None,
311
+ ) -> Orbit:
312
+ """
313
+ Generate an OSTk Orbit from a Pandas DataFrame.
314
+
315
+ Args:
316
+ dataframe (pd.DataFrame): Pandas DataFrame containing the orbit data.
317
+ central_body (Celestial, optional): Celestial object around which the Orbit is defined. Defaults to Earth.
318
+ reference_frame (Frame | None, optional): Reference frame.
319
+ time_column (str | None, optional): Name of the column containing the time data in [UTC].
320
+ position_columns (list[str] | None, optional): List of column names containing the position data in [m].
321
+ velocity_columns (list[str] | None, optional): List of column names containing the velocity data in [m/s].
322
+ initial_revolution_number (int, optional): Initial revolution number. Defaults to 1.
323
+ interpolation_type (Interpolator.Type | None, optional): Interpolation type.
324
+ output_frame (Frame | None, optional): Output frame for the states.
325
+
326
+ Returns:
327
+ Orbit: OSTk Orbit.
328
+ """
329
+
330
+ return Orbit(
331
+ model=TabulatedOrbit(
332
+ states=generate_states_from_dataframe(
333
+ dataframe=dataframe,
334
+ time_column=time_column,
335
+ position_columns=position_columns,
336
+ velocity_columns=velocity_columns,
337
+ reference_frame=reference_frame,
338
+ output_frame=output_frame,
339
+ ),
340
+ initial_revolution_number=initial_revolution_number,
341
+ interpolation_type=interpolation_type or DEFAULT_INTERPOLATION_TYPE,
342
+ ),
343
+ celestial_object=central_body,
344
+ )
345
+
346
+
347
+ def generate_dataframe_from_orbit(
348
+ orbit: Orbit,
349
+ instants: list[Instant],
350
+ reference_frame: Frame | None = None,
351
+ time_column: str | None = None,
352
+ position_columns: list[str] | None = None,
353
+ velocity_columns: list[str] | None = None,
354
+ set_time_index: bool = True,
355
+ ) -> pd.DataFrame:
356
+ """
357
+ Generate a Pandas DataFrame from an OSTk Orbit.
358
+
359
+ Args:
360
+ orbit (Orbit): OSTk Orbit.
361
+ instants (list[Instant]): List of instants at which the Orbit is to be evaluated.
362
+ reference_frame (Frame | None, optional): Reference frame.
363
+ time_column (str | None, optional): Name of the column containing the time data in [UTC].
364
+ position_columns (list[str] | None, optional): List of column names containing the position data in [m].
365
+ velocity_columns (list[str] | None, optional): List of column names containing the velocity data in [m/s].
366
+ set_time_index (bool, optional): Whether to set the time column as the DataFrame index. Defaults to True.
367
+
368
+ Returns:
369
+ pd.DataFrame: Pandas DataFrame containing the Orbit data.
370
+ """
371
+
372
+ states: list[State] = orbit.get_states_at(instants)
373
+
374
+ return generate_dataframe_from_states(
375
+ states,
376
+ reference_frame=reference_frame,
377
+ time_column=time_column,
378
+ position_columns=position_columns,
379
+ velocity_columns=velocity_columns,
380
+ set_time_index=set_time_index,
381
+ )
382
+
383
+
384
+ def generate_profile_from_dataframe(
385
+ dataframe: pd.DataFrame,
386
+ reference_frame: Frame | None = None,
387
+ time_column: str | None = None,
388
+ position_columns: list[str] | None = None,
389
+ velocity_columns: list[str] | None = None,
390
+ attitude_columns: list[str] | None = None,
391
+ angular_velocity_columns: list[str] | None = None,
392
+ output_frame: Frame | None = None,
393
+ ) -> Profile:
394
+ """
395
+ Generate an OSTk Profile from a Pandas DataFrame.
396
+
397
+ Args:
398
+ dataframe (pd.DataFrame): Pandas DataFrame containing the Profile data.
399
+ reference_frame (Frame | None, optional): Reference frame.
400
+ time_column (str | None, optional): Name of the column containing the time data in [UTC].
401
+ position_columns (list[str] | None, optional): List of column names containing the position data in [m].
402
+ velocity_columns (list[str] | None, optional): List of column names containing the velocity data in [m/s].
403
+ attitude_columns (list[str] | None, optional): List of column names containing the attitude data in [x, y, z, s] form.
404
+ angular_velocity_columns (list[str] | None, optional): List of column names containing the angular velocity data in [rad/s].
405
+ output_frame (Frame | None, optional): Output frame for the states.
406
+
407
+ Returns:
408
+ Profile: OSTk Profile.
409
+ """
410
+
411
+ return Profile(
412
+ model=TabulatedProfile(
413
+ states=generate_states_from_dataframe(
414
+ dataframe=dataframe,
415
+ reference_frame=reference_frame,
416
+ time_column=time_column,
417
+ position_columns=position_columns,
418
+ velocity_columns=velocity_columns,
419
+ attitude_columns=attitude_columns,
420
+ angular_velocity_columns=angular_velocity_columns,
421
+ output_frame=output_frame,
422
+ ),
423
+ ),
424
+ )
425
+
426
+
427
+ def generate_dataframe_from_profile(
428
+ profile: Profile,
429
+ instants: list[Instant],
430
+ reference_frame: Frame | None = None,
431
+ time_column: str | None = None,
432
+ position_columns: list[str] | None = None,
433
+ velocity_columns: list[str] | None = None,
434
+ attitude_columns: list[str] | None = None,
435
+ angular_velocity_columns: list[str] | None = None,
436
+ set_time_index: bool = True,
437
+ ) -> pd.DataFrame:
438
+ """
439
+ Generate a Pandas DataFrame from an OSTk Profile.
440
+
441
+ Args:
442
+ profile (Profile): OSTk Profile.
443
+ instants (list[Instant]): List of instants at which the Profile is to be evaluated.
444
+ reference_frame (Frame | None, optional): Reference frame.
445
+ time_column (str | None, optional): Name of the column containing the time data in [UTC].
446
+ position_columns (list[str] | None, optional): List of column names containing the position data in [m].
447
+ velocity_columns (list[str] | None, optional): List of column names containing the velocity data in [m/s].
448
+ attitude_columns (list[str] | None, optional): List of column names containing the attitude data in [x, y, z, s] form.
449
+ angular_velocity_columns (list[str] | None, optional): List of column names containing the angular velocity data in [rad/s].
450
+ set_time_index (bool, optional): Whether to set the time column as the DataFrame index. Defaults to True.
451
+
452
+ Returns:
453
+ pd.DataFrame: Pandas DataFrame containing the Profile data.
454
+ """
455
+
456
+ states: list[State] = profile.get_states_at(instants)
457
+
458
+ return generate_dataframe_from_states(
459
+ states,
460
+ reference_frame=reference_frame,
461
+ time_column=time_column,
462
+ position_columns=position_columns,
463
+ velocity_columns=velocity_columns,
464
+ attitude_columns=attitude_columns,
465
+ angular_velocity_columns=angular_velocity_columns,
466
+ set_time_index=set_time_index,
467
+ )
468
+
469
+
470
+ def _get_entry_from_state(
471
+ state: State, columns: list[str], subset: CoordinateSubset
472
+ ) -> dict:
473
+ coordinates: np.ndarray = state.extract_coordinate(subset)
474
+ return {
475
+ column.format(frame=state.get_frame().get_name()): coordinates[idx]
476
+ for idx, column in enumerate(columns)
477
+ }