stk-files 0.0.2__tar.gz

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.
Files changed (51) hide show
  1. stk_files-0.0.2/.claude/skills/stk-attitude-format.md +122 -0
  2. stk_files-0.0.2/.claude/skills/stk-ephemeris-format.md +136 -0
  3. stk_files-0.0.2/.claude/skills/stk-interval-format.md +84 -0
  4. stk_files-0.0.2/.claude/skills/stk-sensor-format.md +107 -0
  5. stk_files-0.0.2/.github/workflows/release.yml +29 -0
  6. stk_files-0.0.2/.github/workflows/test.yml +26 -0
  7. stk_files-0.0.2/.gitignore +139 -0
  8. stk_files-0.0.2/CLAUDE.md +50 -0
  9. stk_files-0.0.2/LICENSE +21 -0
  10. stk_files-0.0.2/PKG-INFO +207 -0
  11. stk_files-0.0.2/README.md +191 -0
  12. stk_files-0.0.2/SKILLS.md +414 -0
  13. stk_files-0.0.2/docs/attitude.md +196 -0
  14. stk_files-0.0.2/docs/cli.md +187 -0
  15. stk_files-0.0.2/docs/ephemeris.md +184 -0
  16. stk_files-0.0.2/docs/interval.md +126 -0
  17. stk_files-0.0.2/docs/sensor.md +154 -0
  18. stk_files-0.0.2/pyproject.toml +61 -0
  19. stk_files-0.0.2/src/stk_files/__init__.py +77 -0
  20. stk_files-0.0.2/src/stk_files/__main__.py +5 -0
  21. stk_files-0.0.2/src/stk_files/_coerce.py +106 -0
  22. stk_files-0.0.2/src/stk_files/_formatting.py +99 -0
  23. stk_files-0.0.2/src/stk_files/_gaps.py +60 -0
  24. stk_files-0.0.2/src/stk_files/_parser.py +162 -0
  25. stk_files-0.0.2/src/stk_files/_types.py +101 -0
  26. stk_files-0.0.2/src/stk_files/_validation.py +482 -0
  27. stk_files-0.0.2/src/stk_files/_version.py +34 -0
  28. stk_files-0.0.2/src/stk_files/_writer.py +192 -0
  29. stk_files-0.0.2/src/stk_files/attitude.py +193 -0
  30. stk_files-0.0.2/src/stk_files/cli.py +270 -0
  31. stk_files-0.0.2/src/stk_files/ephemeris.py +192 -0
  32. stk_files-0.0.2/src/stk_files/interval.py +75 -0
  33. stk_files-0.0.2/src/stk_files/py.typed +0 -0
  34. stk_files-0.0.2/src/stk_files/sensor.py +171 -0
  35. stk_files-0.0.2/tests/__init__.py +0 -0
  36. stk_files-0.0.2/tests/conftest.py +0 -0
  37. stk_files-0.0.2/tests/strategies.py +71 -0
  38. stk_files-0.0.2/tests/test_attitude.py +270 -0
  39. stk_files-0.0.2/tests/test_cli.py +126 -0
  40. stk_files-0.0.2/tests/test_coerce.py +214 -0
  41. stk_files-0.0.2/tests/test_conversions.py +116 -0
  42. stk_files-0.0.2/tests/test_ephemeris.py +147 -0
  43. stk_files-0.0.2/tests/test_formatting.py +125 -0
  44. stk_files-0.0.2/tests/test_gaps.py +118 -0
  45. stk_files-0.0.2/tests/test_interval.py +111 -0
  46. stk_files-0.0.2/tests/test_read.py +573 -0
  47. stk_files-0.0.2/tests/test_roundtrip.py +288 -0
  48. stk_files-0.0.2/tests/test_sensor.py +152 -0
  49. stk_files-0.0.2/tests/test_validation.py +451 -0
  50. stk_files-0.0.2/tests/test_writer.py +51 -0
  51. stk_files-0.0.2/uv.lock +1006 -0
@@ -0,0 +1,122 @@
1
+ # STK Attitude File Format (*.a)
2
+
3
+ Reference for STK 13 external attitude data files. Source: AGI/Ansys STK Help `importfiles-01.htm`.
4
+
5
+ ## File Structure
6
+
7
+ ```
8
+ stk.v.11.0
9
+ BEGIN Attitude
10
+ [keywords]
11
+ <FormatKeyword>
12
+ <time> <data...>
13
+ ...
14
+ END Attitude
15
+ ```
16
+
17
+ ## Keywords
18
+
19
+ | Keyword | Required | Description |
20
+ |---------|----------|-------------|
21
+ | `stk.v.X.X` | Yes | Version stamp, must be first line |
22
+ | `BEGIN Attitude` / `END Attitude` | Yes | Brackets all data |
23
+ | `MessageLevel` | No | `Errors`, `Warnings`, or `Verbose` |
24
+ | `ScenarioEpoch` | No | Reference epoch: `dd mmm yyyy hh:mm:ss.s` |
25
+ | `CentralBody` | No | Default: Earth |
26
+ | `CoordinateAxes` | No | Reference coordinate system (see below) |
27
+ | `CoordinateAxesEpoch` | Conditional | Required for epoch-dependent axes |
28
+ | `InterpolationMethod` | No | `Lagrange` (default) or `Hermite` |
29
+ | `InterpolationOrder` | No | Default: 1 |
30
+ | `NumberOfAttitudePoints` | No | Max points to read |
31
+ | `AttitudeDeviations` | No | `Rapid` (default) or `Mild` |
32
+ | `BlockingFactor` | No | Memory allocation for large files |
33
+ | `Sequence` | Conditional | Rotation order for Euler/YPR formats |
34
+ | `InitialQuaternion` | Conditional | `<q1> <q2> <q3> <q4>` (q4=scalar), for AngVels format |
35
+ | `InitialEulerAngle` | Conditional | `<Sequence> <RotA> <RotB> <RotC>`, for EulerAngleRates |
36
+ | `InitialYPRAngle` | Conditional | `<Sequence> <Y> <P> <R>`, for YPRAngleRates |
37
+ | `TimeFormat` | No | Date format abbreviation (default: EpSec) |
38
+ | `RepeatPattern` | No | Cycles data; first/last points should match |
39
+
40
+ ## Coordinate Axes
41
+
42
+ **Standard:** Fixed, J2000, ICRF, Inertial, TrueOfDate, MeanOfDate
43
+
44
+ **Epoch-dependent (require CoordinateAxesEpoch):** MeanOfEpoch, TrueOfEpoch, TEMEOfEpoch, AlignmentAtEpoch
45
+
46
+ **Custom (VGT):** `CoordinateAxes AWB <AxisName> <ObjectPath>`
47
+
48
+ ## Data Formats (16 total)
49
+
50
+ ### Quaternion Formats
51
+
52
+ | Format Keyword | Columns | Notes |
53
+ |----------------|---------|-------|
54
+ | `AttitudeTimeQuaternions` | `time q1 q2 q3 q4` | q4 is scalar (scalar-last). Auto-normalized to unit magnitude. |
55
+ | `AttitudeTimeQuatScalarFirst` | `time q1 q2 q3 q4` | q1 is scalar (scalar-first) |
56
+ | `AttitudeTimeQuatAngVels` | `time q1 q2 q3 q4 wx wy wz` | + angular velocity (deg/s, body frame) |
57
+ | `AttitudeTimeAngVels` | `time rA rB rC` | Rates only (deg/s). Requires `InitialQuaternion`. |
58
+
59
+ ### Euler Angle Formats
60
+
61
+ | Format Keyword | Columns | Notes |
62
+ |----------------|---------|-------|
63
+ | `AttitudeTimeEulerAngles` | `time rotA rotB rotC` | Degrees. Requires `Sequence`. |
64
+ | `AttitudeTimeEulerAngleRates` | `time rateA rateB rateC` | deg/s. Requires `InitialEulerAngle`. |
65
+ | `AttitudeTimeEulerAnglesAndRates` | `time rotA rotB rotC rateA rateB rateC` | Requires `InitialEulerAngle`. |
66
+
67
+ **Valid Euler sequences:** 121, 123, 131, 132, 212, 213, 231, 232, 312, 313, 321, 323 (default: 313)
68
+
69
+ Euler rotations are relative to the rotated frame.
70
+
71
+ ### YPR Angle Formats
72
+
73
+ | Format Keyword | Columns | Notes |
74
+ |----------------|---------|-------|
75
+ | `AttitudeTimeYPRAngles` | `time Y P R` | Degrees. Data always in Y-P-R order. Requires `Sequence`. |
76
+ | `AttitudeTimeYPRAngleRates` | `time rateA rateB rateC` | deg/s. Requires `InitialYPRAngle`. |
77
+ | `AttitudeTimeYPRAnglesAndRates` | `time Y P R rateA rateB rateC` | Requires `InitialYPRAngle`. |
78
+
79
+ **Valid YPR sequences:** 123, 132, 213, 231, 312, 321 (default: 321)
80
+
81
+ YPR rotations are relative to the original reference frame. Sequence controls rotation order, not data column order.
82
+
83
+ ### DCM Formats
84
+
85
+ | Format Keyword | Columns | Notes |
86
+ |----------------|---------|-------|
87
+ | `AttitudeTimeDCM` | `time m11 m12 m13 m21 m22 m23 m31 m32 m33` | Row-major, ref-to-body |
88
+ | `AttitudeTimeDCMAngVels` | `time m11..m33 wx wy wz` | + angular velocity (deg/s, body frame) |
89
+
90
+ ### Vector Formats
91
+
92
+ | Format Keyword | Columns | Notes |
93
+ |----------------|---------|-------|
94
+ | `AttitudeTimeECIVector` | `time V1 V2 V3` | Body X-axis in ECI, Z toward nadir. Ignores CoordinateAxes. |
95
+ | `AttitudeTimeECFVector` | `time V1 V2 V3` | Body X-axis in ECF, Z toward nadir. Ignores CoordinateAxes. |
96
+
97
+ ## Data Conventions
98
+
99
+ - One data point per line, values separated by at least one space
100
+ - Ascending time order, no duplicate timestamps
101
+ - Angular velocities always in degrees/second, body-frame components
102
+ - Quaternions are auto-normalized to unit magnitude by STK
103
+ - For spinning objects: 3-4 points per revolution minimum
104
+ - Neighboring points should span less than half a revolution, or include angular velocity data
105
+ - All attitudes represent rotation from reference frame to body frame
106
+
107
+ ## Example
108
+
109
+ ```
110
+ stk.v.11.0
111
+ BEGIN Attitude
112
+ NumberOfAttitudePoints 3
113
+ ScenarioEpoch 1 Jan 2003 00:00:00.0
114
+ CoordinateAxes J2000
115
+ InterpolationMethod Lagrange
116
+ InterpolationOrder 1
117
+ AttitudeTimeQuaternions
118
+ 0.0 0.0 0.0 0.0 1.0
119
+ 3600.0 0.1 0.2 0.3 0.9274
120
+ 7200.0 0.0 0.0 0.7071 0.7071
121
+ END Attitude
122
+ ```
@@ -0,0 +1,136 @@
1
+ # STK Ephemeris File Format (*.e)
2
+
3
+ Reference for STK 13 external ephemeris data files. Source: AGI/Ansys STK Help `importfiles-02.htm`.
4
+
5
+ ## File Structure
6
+
7
+ ```
8
+ stk.v.12.0
9
+ BEGIN Ephemeris
10
+ [keywords]
11
+ <FormatKeyword>
12
+ <time> <data...>
13
+ ...
14
+ END Ephemeris
15
+ ```
16
+
17
+ ## Keywords
18
+
19
+ | Keyword | Required | Description |
20
+ |---------|----------|-------------|
21
+ | `stk.v.X.X` | Yes | Version stamp, must be first line |
22
+ | `BEGIN Ephemeris` / `END Ephemeris` | Yes | Brackets all data |
23
+ | `ScenarioEpoch` | No | Reference epoch: `dd mmm yyyy hh:mm:ss.s` (UTC) |
24
+ | `CentralBody` | No | Default: Earth |
25
+ | `CoordinateSystem` | No | Default: Fixed. **Note: uses `CoordinateSystem`, not `CoordinateAxes`** |
26
+ | `CoordinateSystemEpoch` | Conditional | Required for epoch-dependent frames |
27
+ | `DistanceUnit` | No | Default: meters |
28
+ | `TimeFormat` | No | Default: EpSec |
29
+ | `TimeScale` | No | Default: TAI. Alternative: TDB |
30
+ | `MessageLevel` | No | `Errors`, `Warnings`, or `Verbose` |
31
+ | `NumberOfEphemerisPoints` | No | Max points to read (optional since STK 11.5) |
32
+ | `InterpolationMethod` | No | `Lagrange` (default), `Hermite`, `LagrangeVOP`, `GreatArc`, `GreatArcTerrain`, `GreatArcMSL` |
33
+ | `InterpolationSamplesM1` | No | Default: 5. One less than interpolation point count. Replaces deprecated `InterpolationOrder`. |
34
+ | `ComputeVelocity` | No | `DerivativeOfInterpolatingPolynomial` (default), `ForwardDifference`, `BackwardDifference`, `CentralDifference` |
35
+ | `SmoothData` | No | `Yes`/`No`, `True`/`False`, `On`/`Off` |
36
+ | `BlockingFactor` | No | Memory allocation hint |
37
+
38
+ ## Coordinate Systems
39
+
40
+ **Standard:** Fixed (default), J2000, ICRF, Inertial, TrueOfDate, MeanOfDate
41
+
42
+ **Epoch-dependent (require CoordinateSystemEpoch):** MeanOfEpoch, TrueOfEpoch, TEMEOfEpoch, AlignmentAtEpoch
43
+
44
+ **Custom (VGT):** `CoordinateSystem AWB <name> <object>`
45
+
46
+ ## Data Formats (14 ephemeris + 3 covariance)
47
+
48
+ ### Cartesian Formats
49
+
50
+ | Format Keyword | Columns | Units |
51
+ |----------------|---------|-------|
52
+ | `EphemerisTimePos` | `time X Y Z` | sec, m |
53
+ | `EphemerisTimePosVel` | `time X Y Z Xdot Ydot Zdot` | sec, m, m/s |
54
+ | `EphemerisTimePosVelAcc` | `time X Y Z Xdot Ydot Zdot Xddot Yddot Zddot` | sec, m, m/s, m/s^2 |
55
+
56
+ ### Geodetic LLA Formats
57
+
58
+ | Format Keyword | Columns | Units |
59
+ |----------------|---------|-------|
60
+ | `EphemerisLLATimePos` | `time Lat Lon Alt` | sec, deg, deg, m |
61
+ | `EphemerisLLATimePosVel` | `time Lat Lon Alt LatDot LonDot AltDot` | sec, deg, deg, m, deg/s, deg/s, m/s |
62
+ | `EphemerisMSLLLATimePos` | `time Lat Lon Alt(MSL)` | sec, deg, deg, m |
63
+ | `EphemerisMSLLLATimePosVel` | `time Lat Lon Alt(MSL) LatDot LonDot AltDot` | same |
64
+ | `EphemerisTerrainLLATimePos` | `time Lat Lon Alt(terrain)` | sec, deg, deg, m |
65
+
66
+ ### Geocentric LLR Formats
67
+
68
+ | Format Keyword | Columns | Units |
69
+ |----------------|---------|-------|
70
+ | `EphemerisLLRTimePos` | `time Lat(geocentric) Lon Radius` | sec, deg, deg, m |
71
+ | `EphemerisLLRTimePosVel` | `time Lat Lon Radius LatDot LonDot RadDot` | sec, deg, deg, m, deg/s, deg/s, m/s |
72
+
73
+ ### Mixed Geodetic/Geocentric Formats
74
+
75
+ | Format Keyword | Columns |
76
+ |----------------|---------|
77
+ | `EphemerisGeocentricLLATimePos` | `time Lat(geocentric) Lon Alt` |
78
+ | `EphemerisGeocentricLLATimePosVel` | `time Lat Lon Alt LatDot LonDot AltDot` |
79
+ | `EphemerisGeodeticLLRTimePos` | `time Lat(geodetic) Lon Radius` |
80
+ | `EphemerisGeodeticLLRTimePosVel` | `time Lat Lon Radius LatDot LonDot RadDot` |
81
+
82
+ ### Covariance Formats
83
+
84
+ | Format Keyword | Values | Notes |
85
+ |----------------|--------|-------|
86
+ | `CovarianceTimePos` | 6 unique | 3x3 position covariance (m^2) |
87
+ | `CovarianceTimePosVel` | 21 unique | 6x6 pos+vel covariance |
88
+ | `StateErrorTransition` | 36 values | 6x6 state transition matrix |
89
+
90
+ Covariance keywords: `CovarianceFormat` (LowerTriangular/UpperTriangular), `CovarianceInterpolationMethod`, `CovarianceCoordinateSystem`.
91
+
92
+ ## Interpolation Methods
93
+
94
+ | Method | Notes |
95
+ |--------|-------|
96
+ | `Lagrange` | Default polynomial interpolation |
97
+ | `Hermite` | Uses velocity for smoother results; requires velocity data |
98
+ | `LagrangeVOP` | Requires mu: `InterpolationMethod LagrangeVOP 3.986e+14` |
99
+ | `GreatArc` | Fixed frame, WGS84 great circle |
100
+ | `GreatArcTerrain` | Terrain-following great arc |
101
+ | `GreatArcMSL` | MSL-following great arc |
102
+
103
+ ## Optional Sections
104
+
105
+ **SegmentBoundaryTimes:** List of times where interpolation should not cross. Allows duplicate times at boundaries.
106
+
107
+ **TrendingControl (STK 11.6+):** `TrendingControlTimes` block or `TrendingControlStep <seconds>`.
108
+
109
+ ## Data Conventions
110
+
111
+ - One data point per line, values separated by at least one space
112
+ - Ascending time order (not necessarily evenly spaced)
113
+ - No duplicate times except at SegmentBoundaryTimes
114
+ - Minimum 90 points per orbital revolution recommended
115
+ - Scientific notation permitted
116
+ - Position-only formats auto-generate velocity via `ComputeVelocity` method
117
+
118
+ ## Example
119
+
120
+ ```
121
+ stk.v.12.0
122
+ BEGIN Ephemeris
123
+ ScenarioEpoch 1 Jan 2003 00:00:00.0
124
+ CentralBody Earth
125
+ CoordinateSystem J2000
126
+ InterpolationMethod Lagrange
127
+ InterpolationSamplesM1 5
128
+ NumberOfEphemerisPoints 3
129
+
130
+ EphemerisTimePosVel
131
+ 0.0 7000000.0 0.0 0.0 0.0 7500.0 0.0
132
+ 60.0 6999500.0 450200.0 10500.0 -100.0 7400.0 50.0
133
+ 120.0 6998000.0 897800.0 40200.0 -300.0 7300.0 150.0
134
+
135
+ END Ephemeris
136
+ ```
@@ -0,0 +1,84 @@
1
+ # STK Interval List File Format (*.int)
2
+
3
+ Reference for STK 13 external interval list files. Source: AGI/Ansys STK Help `importfiles-04.htm`.
4
+
5
+ ## File Structure
6
+
7
+ ```
8
+ stk.v.12.0
9
+ BEGIN IntervalList
10
+ ScenarioEpoch <epoch> (option A: numeric seconds)
11
+ DateUnitAbrv <abbreviation> (option B: formatted dates)
12
+ BEGIN Intervals
13
+ <start> <stop> [optional_data]
14
+ ...
15
+ END Intervals
16
+ END IntervalList
17
+ ```
18
+
19
+ ## Keywords
20
+
21
+ | Keyword | Required | Description |
22
+ |---------|----------|-------------|
23
+ | `stk.v.X.X` | Yes | Version stamp, must be first line |
24
+ | `BEGIN IntervalList` / `END IntervalList` | Yes | Brackets entire keyword group |
25
+ | `BEGIN Intervals` / `END Intervals` | Yes | Brackets data entries |
26
+ | `ScenarioEpoch` | Option A | `dd mmm yyyy hh:mm:ss.s` (Gregorian UTC). Times as seconds past epoch. |
27
+ | `DateUnitAbrv` | Option B | STK date format abbreviation. Non-numeric times must be quoted. |
28
+
29
+ All keywords are case-insensitive.
30
+
31
+ ## Time Format Options
32
+
33
+ ### Option A: ScenarioEpoch (numeric seconds)
34
+ ```
35
+ ScenarioEpoch 1 Jul 2000 00:00:00.00
36
+ BEGIN Intervals
37
+ 0.000000 3600.000000
38
+ 7200.000000 10800.000000
39
+ END Intervals
40
+ ```
41
+
42
+ ### Option B: DateUnitAbrv (formatted dates, quoted)
43
+ ```
44
+ DateUnitAbrv UTCG
45
+ BEGIN Intervals
46
+ "1 Jul 2000 00:00:00.00" "1 Jul 2000 01:30:00.00"
47
+ "1 Jul 2000 02:00:00.00" "1 Jul 2000 03:00:00.00"
48
+ END Intervals
49
+ ```
50
+
51
+ **Supported abbreviations:** EpSec, UTCG, GPSG, GPSZ, TAIG, TDTG, JDate, ModJDate, YYDDD, YYYYDDD, ISO-YMD, ISO-YD, and others.
52
+
53
+ **Not supported:** LCLG (local Gregorian), LCLJ (local Julian), Mission Elapsed.
54
+
55
+ ## Data Line Format
56
+
57
+ Each line: `<start_time> <stop_time> [optional_data_string]`
58
+
59
+ Non-numerical times must be enclosed in quotes.
60
+
61
+ ## Optional Data Strings
62
+
63
+ | Field | Examples |
64
+ |-------|----------|
65
+ | Target/Object | `Facility/Philadelphia`, `Satellite/Sat315` |
66
+ | Color | `Color red`, `Color #0000ff` |
67
+ | Pointing target | `Sun`, `Viewer` |
68
+ | 2D Graphics | `Show On`, `Color`, `LineStyle dotted`, `LineWidth 3`, `MarkerStyle Plus` |
69
+ | 3D Graphics | `Show On`, `Color`, `LineWidth 3`, `Translucency 50` |
70
+
71
+ Invalid optional data is silently ignored.
72
+
73
+ ## Example (ISO-YMD)
74
+
75
+ ```
76
+ stk.v.12.0
77
+ BEGIN IntervalList
78
+ DateUnitAbrv ISO-YMD
79
+ BEGIN Intervals
80
+ "2020-01-01T00:00:00.000" "2020-01-01T00:10:00.000"
81
+ "2020-01-02T00:00:00.000" "2020-01-02T00:20:00.000"
82
+ END Intervals
83
+ END IntervalList
84
+ ```
@@ -0,0 +1,107 @@
1
+ # STK Sensor Pointing File Format (*.sp)
2
+
3
+ Reference for STK 13 external sensor pointing files. Source: AGI/Ansys STK Help `importfiles-07.htm`.
4
+
5
+ ## File Structure
6
+
7
+ ```
8
+ stk.v.11.0
9
+ [keywords outside block]
10
+ BEGIN Attitude
11
+ <FormatKeyword>
12
+ <time> <data...>
13
+ ...
14
+ END Attitude
15
+ ```
16
+
17
+ **Note:** Sensor pointing files use `BEGIN Attitude` / `END Attitude` (same block name as attitude files), despite having `.sp` extension.
18
+
19
+ ## Keywords
20
+
21
+ | Keyword | Required | Description |
22
+ |---------|----------|-------------|
23
+ | `stk.v.X.X` | Yes | Version stamp, must be first line |
24
+ | `BEGIN Attitude` / `END Attitude` | Yes | Brackets data section |
25
+ | `MessageLevel` | No | `Errors`, `Warnings`, or `Verbose` |
26
+ | `CentralBody` | No | Default: parent vehicle's central body |
27
+ | `CoordinateAxes` | No | Reference frame. When unspecified: parent body axes (rotated 180 deg about X for ground objects) |
28
+ | `ScenarioEpoch` | No | Reference epoch: `dd mmm yyyy hh:mm:ss.s` |
29
+ | `TimeFormat` | No | Date format abbreviation |
30
+ | `NumberOfAttitudePoints` | No | Max points to read (recommended) |
31
+ | `Sequence` | Conditional | Rotation order for Euler/YPR/AzEl formats |
32
+ | `RepeatPattern` | No | Cycles data; first/last points should match |
33
+ | `AttitudeDeviations` | No | `Rapid` (default) or `Mild` |
34
+ | `InterpolationMethod` | No | `Lagrange` (default) or `Hermite` |
35
+ | `InterpolationOrder` | No | Default: 1 |
36
+
37
+ ## Coordinate Axes
38
+
39
+ Same as attitude files: Fixed, J2000, ICRF, Inertial, TrueOfDate, MeanOfDate, plus epoch-dependent and custom AWB.
40
+
41
+ **Default behavior when unspecified:**
42
+ - **Vehicle parent:** parent's body axes
43
+ - **Facility/Target/Place parent:** parent's body axes rotated 180 degrees about X-axis
44
+
45
+ ## Data Formats
46
+
47
+ ### Quaternion Formats
48
+
49
+ | Format Keyword | Columns | Notes |
50
+ |----------------|---------|-------|
51
+ | `AttitudeTimeQuaternions` | `time q1 q2 q3 q4` | q4 is scalar (scalar-last) |
52
+ | `AttitudeTimeQuatScalarFirst` | `time q1 q2 q3 q4` | q1 is scalar |
53
+
54
+ ### Angle Formats
55
+
56
+ | Format Keyword | Columns | Notes |
57
+ |----------------|---------|-------|
58
+ | `AttitudeTimeEulerAngles` | `time rotA rotB rotC` | Degrees. Requires `Sequence`. |
59
+ | `AttitudeTimeYPRAngles` | `time Y P R` | Degrees. Data always in Y-P-R order. |
60
+ | `AttitudeTimeAzElAngles` | `time azimuth elevation` | Degrees. Sensor-specific format. |
61
+
62
+ ### AzElAngles Details
63
+
64
+ - **Azimuth:** positive counter-clockwise about +Z axis (vehicles) or -Z axis (ground locations)
65
+ - **Elevation:** degrees above XY plane, positive toward +Z axis
66
+ - Third rotation is always 0.0 (not provided in data)
67
+
68
+ ## Rotation Sequences
69
+
70
+ **Euler sequences:** 121, 123, 131, 132, 212, 213, 231, 232, 312, 313, 321, 323 (default: 313)
71
+
72
+ **YPR sequences:** 123, 132, 213, 231, 312 (default: **312**, differs from attitude file default of 321)
73
+
74
+ **AzEl sequences:** 323 (default, "Rotate About Boresight"), 213 ("Hold About Boresight")
75
+
76
+ ## Data Conventions
77
+
78
+ - One data point per line, values separated by at least one space
79
+ - Ascending time order, no duplicate timestamps
80
+ - For dynamic attitudes: 3-4 points per revolution minimum
81
+ - Sensor boresight is the Z-axis of the sensor body frame
82
+
83
+ ## Example (AzEl)
84
+
85
+ ```
86
+ stk.v.11.0
87
+ ScenarioEpoch 1 Jan 2003 00:00:00.0
88
+ Sequence 323
89
+ BEGIN Attitude
90
+ AttitudeTimeAzElAngles
91
+ 0.0 45.0 30.0
92
+ 3600.0 90.0 45.0
93
+ 7200.0 135.0 60.0
94
+ END Attitude
95
+ ```
96
+
97
+ ## Example (Quaternions)
98
+
99
+ ```
100
+ stk.v.11.0
101
+ CoordinateAxes J2000
102
+ BEGIN Attitude
103
+ AttitudeTimeQuaternions
104
+ 0.0 0.0 0.0 0.0 1.0
105
+ 3600.0 0.1 0.2 0.3 0.9274
106
+ END Attitude
107
+ ```
@@ -0,0 +1,29 @@
1
+ name: "Publish"
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ jobs:
8
+ publish:
9
+ runs-on: ubuntu-latest
10
+ environment:
11
+ name: pypi
12
+ permissions:
13
+ id-token: write
14
+ contents: read
15
+ steps:
16
+ - name: Checkout
17
+ uses: actions/checkout@v6
18
+
19
+ - name: Install uv
20
+ uses: astral-sh/setup-uv@v7
21
+
22
+ - name: Install Python 3.13
23
+ run: uv python install 3.13
24
+
25
+ - name: Build
26
+ run: uv build
27
+
28
+ - name: Publish
29
+ run: uv publish
@@ -0,0 +1,26 @@
1
+ name: Test
2
+
3
+ on: [push, pull_request]
4
+
5
+ jobs:
6
+ build:
7
+ runs-on: ubuntu-latest
8
+ strategy:
9
+ fail-fast: false
10
+ matrix:
11
+ python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
12
+
13
+ steps:
14
+ - uses: actions/checkout@v6
15
+
16
+ - name: Install uv and set the Python version
17
+ uses: astral-sh/setup-uv@v7
18
+ with:
19
+ enable-cache: true
20
+ python-version: ${{ matrix.python-version }}
21
+
22
+ - name: Install the project
23
+ run: uv sync --locked --all-extras --dev
24
+
25
+ - name: Run pytest
26
+ run: uv run pytest tests/
@@ -0,0 +1,139 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ pip-wheel-metadata/
24
+ share/python-wheels/
25
+ *.egg-info/
26
+ .installed.cfg
27
+ *.egg
28
+ MANIFEST
29
+ **/_version.py
30
+
31
+ # PyInstaller
32
+ # Usually these files are written by a python script from a template
33
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
34
+ *.manifest
35
+ *.spec
36
+
37
+ # Installer logs
38
+ pip-log.txt
39
+ pip-delete-this-directory.txt
40
+
41
+ # Unit test / coverage reports
42
+ htmlcov/
43
+ .tox/
44
+ .nox/
45
+ .coverage
46
+ .coverage.*
47
+ .cache
48
+ nosetests.xml
49
+ coverage.xml
50
+ *.cover
51
+ *.py,cover
52
+ .hypothesis/
53
+ .pytest_cache/
54
+
55
+ # Translations
56
+ *.mo
57
+ *.pot
58
+
59
+ # Django stuff:
60
+ *.log
61
+ local_settings.py
62
+ db.sqlite3
63
+ db.sqlite3-journal
64
+
65
+ # Flask stuff:
66
+ instance/
67
+ .webassets-cache
68
+
69
+ # Scrapy stuff:
70
+ .scrapy
71
+
72
+ # Sphinx documentation
73
+ docs/_build/
74
+
75
+ # PyBuilder
76
+ target/
77
+
78
+ # Jupyter Notebook
79
+ .ipynb_checkpoints
80
+
81
+ # IPython
82
+ profile_default/
83
+ ipython_config.py
84
+
85
+ # pyenv
86
+ .python-version
87
+
88
+ # pipenv
89
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
90
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
91
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
92
+ # install all needed dependencies.
93
+ #Pipfile.lock
94
+
95
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow
96
+ __pypackages__/
97
+
98
+ # Celery stuff
99
+ celerybeat-schedule
100
+ celerybeat.pid
101
+
102
+ # SageMath parsed files
103
+ *.sage.py
104
+
105
+ # Environments
106
+ .env
107
+ .venv
108
+ env/
109
+ venv/
110
+ ENV/
111
+ env.bak/
112
+ venv.bak/
113
+
114
+ # Spyder project settings
115
+ .spyderproject
116
+ .spyproject
117
+
118
+ # Rope project settings
119
+ .ropeproject
120
+
121
+ # mkdocs documentation
122
+ /site
123
+
124
+ # mypy
125
+ .mypy_cache/
126
+ .dmypy.json
127
+ dmypy.json
128
+
129
+ # Pyre type checker
130
+ .pyre/
131
+
132
+ # VSCode
133
+ .vscode/
134
+
135
+ # ruff
136
+ .ruff_cache/
137
+
138
+ # claude
139
+ .claude/settings.local.json
@@ -0,0 +1,50 @@
1
+ # CLAUDE.md — stk-files
2
+
3
+ ## What this is
4
+
5
+ Python package for generating STK (Systems Tool Kit) external data files. Provides a programmatic API and CLI to write attitude, ephemeris, sensor pointing, and interval list data in STK-compatible formats.
6
+
7
+ ## Quick reference
8
+
9
+ ```bash
10
+ uv sync # Install dependencies
11
+ pytest # Run tests
12
+ ruff check src/ tests/ # Lint
13
+ ruff format src/ tests/ # Format
14
+ mypy src/ # Type check (strict mode)
15
+ ```
16
+
17
+ ## Project layout
18
+
19
+ - `src/stk_files/` — package source
20
+ - `attitude.py`, `ephemeris.py`, `interval.py`, `sensor.py` — file type modules (each has a frozen Config dataclass + `write_*` function)
21
+ - `_types.py` — type literals, column count dicts, format constants
22
+ - `_validation.py` — shape/quaternion/angle/sequence validation + filtering
23
+ - `_formatting.py` — row formatting (ISO-YMD timestamps, EpSec, quaternions, generic)
24
+ - `_coerce.py` — runtime coercion of pandas/polars Series/DataFrames to numpy arrays
25
+ - `_writer.py` — `stk_writer()` context manager, `RowWriter`
26
+ - `cli.py` — Click CLI with subcommands (attitude, ephemeris, interval, sensor)
27
+ - `__init__.py` — public API exports
28
+ - `tests/` — pytest + hypothesis tests
29
+ - `strategies.py` — custom hypothesis strategies (quaternions, angles, sorted datetimes)
30
+
31
+ ## Conventions
32
+
33
+ - **Python >=3.9**, strict mypy, ruff (line-length 99)
34
+ - Private modules prefixed with `_`, config classes suffixed with `Config`
35
+ - `from __future__ import annotations` in all modules
36
+ - Timestamps are `np.datetime64[ms]`; data arrays are numpy ndarrays (pandas/polars inputs are coerced automatically via `_coerce.py`)
37
+ - pandas and polars are optional dependencies (`pip install stk-files[pandas]` / `stk-files[polars]`)
38
+ - Validation has strict mode (raise on invalid) and non-strict (filter invalid rows)
39
+ - Frozen dataclasses for configs; each config has `header()` and `footer()` methods
40
+ - Tests use hypothesis property-based testing with custom strategies in `strategies.py`
41
+
42
+ ## Adding a new file format
43
+
44
+ 1. Add type literals and column counts to `_types.py`
45
+ 2. Add validation rules to `_validation.py` if needed
46
+ 3. Add formatter to `_formatting.py` if special formatting needed
47
+ 4. Create module with Config dataclass and `write_*` function
48
+ 5. Export in `__init__.py`
49
+ 6. Add CLI subcommand in `cli.py`
50
+ 7. Add tests with hypothesis strategies