docs
0
# DSK (Digital Shape Kernels)
1
2
Advanced 3D shape model operations for celestial bodies using Digital Shape Kernels. DSK files contain high-fidelity surface representations that enable precise geometric calculations, ray tracing, and surface analysis for irregularly shaped objects like asteroids, comet nuclei, and small moons.
3
4
## Capabilities
5
6
### DSK File Operations
7
8
Create, open, and manage DSK files containing 3D shape model data.
9
10
```python { .api }
11
def dskopn(fname: str, ifname: str, ncomch: int) -> int:
12
"""
13
Open new DSK file for writing.
14
15
Parameters:
16
- fname: str, DSK file name
17
- ifname: str, internal file name
18
- ncomch: int, number of comment characters
19
20
Returns:
21
int: file handle
22
"""
23
24
def dskcls(handle: int) -> None:
25
"""
26
Close DSK file.
27
28
Parameters:
29
- handle: int, file handle
30
31
Returns:
32
None
33
"""
34
```
35
36
### Type 2 DSK Operations
37
38
Handle Type 2 DSK segments (triangular plate models).
39
40
```python { .api }
41
def dskw02(handle: int, center: int, surfid: int, dclass: int, frame: str, corsys: int, corpar: ndarray, mncor1: float, mxcor1: float, mncor2: float, mxcor2: float, mncor3: float, mxcor3: float, first: float, last: float, nv: int, vrtces: ndarray, np: int, plates: ndarray, spaixd: ndarray, spaixi: ndarray) -> None:
42
"""
43
Write Type 2 DSK segment to file.
44
45
Parameters:
46
- handle: int, file handle
47
- center: int, central body ID
48
- surfid: int, surface ID
49
- dclass: int, data class
50
- frame: str, reference frame
51
- corsys: int, coordinate system
52
- corpar: ndarray, coordinate parameters
53
- mncor1, mxcor1: float, coordinate 1 bounds
54
- mncor2, mxcor2: float, coordinate 2 bounds
55
- mncor3, mxcor3: float, coordinate 3 bounds
56
- first, last: float, time bounds
57
- nv: int, number of vertices
58
- vrtces: ndarray, vertex coordinates
59
- np: int, number of plates
60
- plates: ndarray, plate vertex indices
61
- spaixd: ndarray, spatial index (double)
62
- spaixi: ndarray, spatial index (integer)
63
64
Returns:
65
None
66
"""
67
68
def dskb02(handle: int, center: int, surfid: int, dclass: int, frame: str, corsys: int, corpar: ndarray, mncor1: float, mxcor1: float, mncor2: float, mxcor2: float, mncor3: float, mxcor3: float, first: float, last: float) -> None:
69
"""
70
Begin new Type 2 DSK segment.
71
72
Parameters:
73
- handle: int, file handle
74
- center: int, central body ID
75
- surfid: int, surface ID
76
- dclass: int, data class
77
- frame: str, reference frame
78
- corsys: int, coordinate system
79
- corpar: ndarray, coordinate parameters
80
- mncor1, mxcor1: float, coordinate 1 bounds
81
- mncor2, mxcor2: float, coordinate 2 bounds
82
- mncor3, mxcor3: float, coordinate 3 bounds
83
- first, last: float, time bounds
84
85
Returns:
86
None
87
"""
88
```
89
90
### Shape Model Queries
91
92
Query shape model data and perform geometric calculations.
93
94
```python { .api }
95
def dskobj(dsk: str) -> List[int]:
96
"""
97
Get object IDs for bodies in DSK file.
98
99
Parameters:
100
- dsk: str, DSK file name
101
102
Returns:
103
List[int]: body ID codes
104
"""
105
106
def dsksrf(dsk: str, bodyid: int) -> List[int]:
107
"""
108
Get surface IDs for body in DSK file.
109
110
Parameters:
111
- dsk: str, DSK file name
112
- bodyid: int, body ID code
113
114
Returns:
115
List[int]: surface ID codes
116
"""
117
118
def dskgd(dsk: str, bodyid: int, surfid: int) -> SpiceDSKDescr:
119
"""
120
Get DSK descriptor for specified surface.
121
122
Parameters:
123
- dsk: str, DSK file name
124
- bodyid: int, body ID code
125
- surfid: int, surface ID code
126
127
Returns:
128
SpiceDSKDescr: DSK descriptor
129
"""
130
```
131
132
### Surface Intersection
133
134
Find intersections between rays and DSK shape models.
135
136
```python { .api }
137
def dskxv(pri: bool, target: str, nsurf: int, srflst: List[int], et: float, fixref: str, vtx: ndarray, raydir: ndarray) -> Tuple[ndarray, bool]:
138
"""
139
Compute ray-surface intercept using DSK data.
140
141
Parameters:
142
- pri: bool, prioritize closer surfaces
143
- target: str, target body name
144
- nsurf: int, number of surfaces
145
- srflst: List[int], surface ID list
146
- et: float, ephemeris time
147
- fixref: str, body-fixed reference frame
148
- vtx: ndarray, ray vertex
149
- raydir: ndarray, ray direction vector
150
151
Returns:
152
Tuple[ndarray, bool]: (intercept_point, found)
153
"""
154
155
def dskxsi(pri: bool, target: str, nsurf: int, srflst: List[int], et: float, fixref: str, vtx: ndarray, raydir: ndarray) -> Tuple[ndarray, int, int, float, float, bool]:
156
"""
157
Compute ray-surface intercept with extended information.
158
159
Parameters:
160
- pri: bool, prioritize closer surfaces
161
- target: str, target body name
162
- nsurf: int, number of surfaces
163
- srflst: List[int], surface ID list
164
- et: float, ephemeris time
165
- fixref: str, body-fixed reference frame
166
- vtx: ndarray, ray vertex
167
- raydir: ndarray, ray direction vector
168
169
Returns:
170
Tuple[ndarray, int, int, float, float, bool]: (point, handle, dladsc, dscdsc, dc, found)
171
"""
172
```
173
174
### Plate Model Access
175
176
Access triangular plate data from Type 2 DSK segments.
177
178
```python { .api }
179
def dskv02(handle: int, dladsc: SpiceDLADescr, start: int, room: int) -> Tuple[int, ndarray]:
180
"""
181
Fetch vertices from Type 2 DSK segment.
182
183
Parameters:
184
- handle: int, DSK file handle
185
- dladsc: SpiceDLADescr, DLA descriptor
186
- start: int, start index (1-based)
187
- room: int, number of vertices to fetch
188
189
Returns:
190
Tuple[int, ndarray]: (n, vertices)
191
"""
192
193
def dskp02(handle: int, dladsc: SpiceDLADescr, start: int, room: int) -> Tuple[int, ndarray]:
194
"""
195
Fetch plates from Type 2 DSK segment.
196
197
Parameters:
198
- handle: int, DSK file handle
199
- dladsc: SpiceDLADescr, DLA descriptor
200
- start: int, start index (1-based)
201
- room: int, number of plates to fetch
202
203
Returns:
204
Tuple[int, ndarray]: (n, plates)
205
"""
206
207
def dskz02(handle: int, dladsc: SpiceDLADescr) -> Tuple[int, int]:
208
"""
209
Get vertex and plate counts from Type 2 DSK segment.
210
211
Parameters:
212
- handle: int, DSK file handle
213
- dladsc: SpiceDLADescr, DLA descriptor
214
215
Returns:
216
Tuple[int, int]: (nv, np) vertex and plate counts
217
"""
218
```
219
220
### Normal Vector Computation
221
222
Compute surface normal vectors at intercept points.
223
224
```python { .api }
225
def dskn02(handle: int, dladsc: SpiceDLADescr, plid: int) -> ndarray:
226
"""
227
Compute outward normal vector for Type 2 DSK plate.
228
229
Parameters:
230
- handle: int, DSK file handle
231
- dladsc: SpiceDLADescr, DLA descriptor
232
- plid: int, plate ID (1-based)
233
234
Returns:
235
ndarray: outward normal unit vector
236
"""
237
```
238
239
### DSK Tolerance Management
240
241
Manage numerical tolerances for DSK operations.
242
243
```python { .api }
244
def dskgtl(keywrd: str) -> float:
245
"""
246
Get DSK tolerance or margin parameter.
247
248
Parameters:
249
- keywrd: str, parameter keyword
250
251
Returns:
252
float: parameter value
253
"""
254
255
def dskstl(keywrd: str, dpval: float) -> None:
256
"""
257
Set DSK tolerance or margin parameter.
258
259
Parameters:
260
- keywrd: str, parameter keyword
261
- dpval: float, parameter value
262
263
Returns:
264
None
265
"""
266
```
267
268
## Common Usage Patterns
269
270
### Ray-Surface Intersection
271
```python
272
import spiceypy as spice
273
import numpy as np
274
275
# Load DSK file
276
spice.furnsh("asteroid_shape.bsp")
277
278
# Define ray from spacecraft to surface
279
spacecraft_pos = np.array([100.0, 0.0, 0.0]) # km
280
look_direction = np.array([-1.0, 0.0, 0.0]) # toward surface
281
282
# Find intersection with asteroid surface
283
target = "ASTEROID"
284
et = spice.str2et("2023-01-01T12:00:00")
285
frame = "ASTEROID_FIXED"
286
287
intercept, found = spice.dskxv(
288
True, # prioritize closer surfaces
289
target, # target body
290
0, # use all surfaces
291
[], # surface list (empty = all)
292
et, # time
293
frame, # reference frame
294
spacecraft_pos, # ray vertex
295
look_direction # ray direction
296
)
297
298
if found:
299
print(f"Surface intercept at: {intercept} km")
300
301
# Get extended intersection information
302
point, handle, dladsc, dscdsc, dc, found = spice.dskxsi(
303
True, target, 0, [], et, frame, spacecraft_pos, look_direction
304
)
305
306
if found:
307
# Get surface normal at intercept
308
plate_id = int(dc) # plate ID from intersection
309
normal = spice.dskn02(handle, dladsc, plate_id)
310
print(f"Surface normal: {normal}")
311
```
312
313
### Creating DSK File from Shape Model
314
```python
315
import numpy as np
316
317
# Open new DSK file
318
handle = spice.dskopn("asteroid_model.bsp", "Asteroid Shape Model", 0)
319
320
# Define shape model parameters
321
center = 1000023 # asteroid ID
322
surface_id = 1
323
data_class = 1
324
frame = "ASTEROID_FIXED"
325
coord_sys = 1 # rectangular coordinates
326
coord_params = np.zeros(10)
327
328
# Time bounds (entire mission)
329
first_time = spice.str2et("2020-01-01")
330
last_time = spice.str2et("2025-12-31")
331
332
# Coordinate bounds (computed from shape model)
333
min_x, max_x = -50.0, 50.0
334
min_y, max_y = -30.0, 30.0
335
min_z, max_z = -25.0, 25.0
336
337
# Begin Type 2 DSK segment
338
spice.dskb02(
339
handle, center, surface_id, data_class, frame,
340
coord_sys, coord_params,
341
min_x, max_x, min_y, max_y, min_z, max_z,
342
first_time, last_time
343
)
344
345
# Add plate model data (vertices and triangular plates)
346
# vertices: N x 3 array of vertex coordinates
347
# plates: M x 3 array of vertex indices for each triangular plate
348
# spatial_index_double, spatial_index_int: acceleration structures
349
350
spice.dskw02(
351
handle, center, surface_id, data_class, frame,
352
coord_sys, coord_params,
353
min_x, max_x, min_y, max_y, min_z, max_z,
354
first_time, last_time,
355
len(vertices), vertices,
356
len(plates), plates,
357
spatial_index_double, spatial_index_int
358
)
359
360
# Close DSK file
361
spice.dskcls(handle)
362
```
363
364
### Querying DSK File Contents
365
```python
366
# Get all objects in DSK file
367
dsk_file = "asteroid_model.bsp"
368
body_ids = spice.dskobj(dsk_file)
369
print(f"Bodies in DSK: {body_ids}")
370
371
# Get surfaces for each body
372
for body_id in body_ids:
373
surface_ids = spice.dsksrf(dsk_file, body_id)
374
print(f"Body {body_id} surfaces: {surface_ids}")
375
376
# Get DSK descriptor for each surface
377
for surface_id in surface_ids:
378
dsk_desc = spice.dskgd(dsk_file, body_id, surface_id)
379
print(f"Surface {surface_id} descriptor: {dsk_desc}")
380
```