0
# Base Classes and Utilities
1
2
Foundation classes and utility functions that provide the common infrastructure for all dust map implementations. These components handle coordinate transformations, data loading, map querying, and serialization across the dustmaps ecosystem.
3
4
## Capabilities
5
6
### Abstract Base Classes
7
8
Core abstract classes that define the standard interface for all dust map queries.
9
10
```python { .api }
11
class DustMap:
12
"""Abstract base class for all dust map implementations."""
13
14
def __init__(self):
15
"""Initialize dust map instance."""
16
17
def __call__(self, coords, **kwargs):
18
"""
19
Callable alias for query method.
20
21
Parameters:
22
- coords (SkyCoord): Coordinate positions to query
23
- **kwargs: Additional arguments passed to query
24
25
Returns:
26
- float | np.ndarray: Dust values
27
"""
28
29
def query(self, coords, **kwargs):
30
"""
31
Query dust map at specified coordinates. Must be implemented by subclasses.
32
33
Parameters:
34
- coords (SkyCoord): Coordinate positions to query
35
- **kwargs: Map-specific query parameters
36
37
Returns:
38
- float | np.ndarray: Dust extinction or density values
39
40
Raises:
41
- NotImplementedError: If not implemented by subclass
42
"""
43
44
def query_gal(self, l, b, d=None, **kwargs):
45
"""
46
Query using Galactic coordinates.
47
48
Parameters:
49
- l (float | array): Galactic longitude (degrees)
50
- b (float | array): Galactic latitude (degrees)
51
- d (float | array, optional): Distance (pc, required for 3D maps)
52
- **kwargs: Additional query parameters
53
54
Returns:
55
- float | np.ndarray: Dust values
56
"""
57
58
def query_equ(self, ra, dec, d=None, frame='icrs', **kwargs):
59
"""
60
Query using Equatorial coordinates.
61
62
Parameters:
63
- ra (float | array): Right ascension (degrees)
64
- dec (float | array): Declination (degrees)
65
- d (float | array, optional): Distance (pc, required for 3D maps)
66
- frame (str): Coordinate frame ('icrs', 'fk5', etc.)
67
- **kwargs: Additional query parameters
68
69
Returns:
70
- float | np.ndarray: Dust values
71
"""
72
73
class WebDustMap:
74
"""Base class for web API-based dust map queries."""
75
76
def __init__(self, api_url=None, map_name=''):
77
"""
78
Initialize web dust map query.
79
80
Parameters:
81
- api_url (str, optional): Base URL for web API
82
- map_name (str): Name of dust map for API requests
83
"""
84
85
def __call__(self, coords, **kwargs):
86
"""Callable alias for query method."""
87
88
def query(self, coords, **kwargs):
89
"""
90
Query dust map via web API.
91
92
Parameters:
93
- coords (SkyCoord): Coordinate positions to query
94
- **kwargs: API-specific parameters
95
96
Returns:
97
- float | np.ndarray: Dust values from web service
98
"""
99
100
def query_gal(self, l, b, d=None, **kwargs):
101
"""Query web API using Galactic coordinates."""
102
103
def query_equ(self, ra, dec, d=None, frame='icrs', **kwargs):
104
"""Query web API using Equatorial coordinates."""
105
```
106
107
### HEALPix Map Support
108
109
Base classes for dust maps stored in HEALPix format (Hierarchical Equal Area isoLatitude Pixelization).
110
111
```python { .api }
112
class HEALPixQuery(DustMap):
113
"""Base class for HEALPix-formatted dust maps."""
114
115
def __init__(self, pix_val, nest, coord_frame, flags=None):
116
"""
117
Initialize HEALPix dust map from pixel values.
118
119
Parameters:
120
- pix_val (np.ndarray): HEALPix pixel values
121
- nest (bool): True for nested pixel ordering, False for ring ordering
122
- coord_frame (str): Coordinate frame ('galactic', 'icrs', etc.)
123
- flags (np.ndarray, optional): Quality flags for each pixel
124
"""
125
126
def query(self, coords, return_flags=False):
127
"""
128
Query HEALPix map at coordinates.
129
130
Parameters:
131
- coords (SkyCoord): Query coordinates
132
- return_flags (bool): Return quality flags along with values
133
134
Returns:
135
- float | np.ndarray: Dust values
136
- tuple: (values, flags) if return_flags=True
137
"""
138
139
class HEALPixFITSQuery(HEALPixQuery):
140
"""HEALPix dust maps loaded from FITS files."""
141
142
def __init__(self, fname, coord_frame, hdu=0, field=None, dtype='f8', scale=None):
143
"""
144
Initialize HEALPix map from FITS file.
145
146
Parameters:
147
- fname (str): Path to HEALPix FITS file
148
- coord_frame (str): Coordinate frame of the map
149
- hdu (int): FITS HDU number to read
150
- field (str, optional): Field name for multi-field maps
151
- dtype (str): Data type for pixel values
152
- scale (float, optional): Scaling factor for pixel values
153
"""
154
155
def query(self, coords, **kwargs):
156
"""Query FITS-based HEALPix map."""
157
```
158
159
### Unstructured Map Support
160
161
Base classes for dust maps with irregular spatial sampling.
162
163
```python { .api }
164
class UnstructuredDustMap(DustMap):
165
"""Base class for unstructured (irregular) dust maps."""
166
167
def __init__(self, pix_coords, max_pix_scale, metric_p=2, frame=None):
168
"""
169
Initialize unstructured dust map.
170
171
Parameters:
172
- pix_coords (SkyCoord): Coordinates of map pixels/data points
173
- max_pix_scale (float): Maximum pixel scale (degrees)
174
- metric_p (int): Minkowski metric parameter (1=Manhattan, 2=Euclidean)
175
- frame (str, optional): Coordinate frame
176
"""
177
178
def query(self, coords, return_indices=False):
179
"""
180
Query unstructured map using nearest neighbor interpolation.
181
182
Parameters:
183
- coords (SkyCoord): Query coordinates
184
- return_indices (bool): Return pixel indices along with values
185
186
Returns:
187
- float | np.ndarray: Dust values
188
- tuple: (values, indices) if return_indices=True
189
"""
190
```
191
192
### Equirectangular Map Support
193
194
Base class for maps using Equirectangular (cylindrical) projections.
195
196
```python { .api }
197
class EquirectangularDustMap(DustMap):
198
"""Base class for Equirectangular projection dust maps."""
199
200
def __init__(self, pix_values, lon0, lon1, lat0, lat1,
201
dist0=None, dist1=None,
202
axis_order=('lon','lat','dist'),
203
frame='galactic',
204
dist_interp='linear'):
205
"""
206
Initialize Equirectangular projection map.
207
208
Parameters:
209
- pix_values (np.ndarray): Map pixel values
210
- lon0, lon1 (float): Longitude range (degrees)
211
- lat0, lat1 (float): Latitude range (degrees)
212
- dist0, dist1 (float, optional): Distance range (pc) for 3D maps
213
- axis_order (tuple): Order of array axes
214
- frame (str): Coordinate frame
215
- dist_interp (str): Distance interpolation method ('linear', 'log')
216
"""
217
218
def query(self, coords, **kwargs):
219
"""Query Equirectangular map with bilinear interpolation."""
220
```
221
222
### Coordinate Utility Functions
223
224
Essential functions for coordinate system transformations and array handling.
225
226
```python { .api }
227
def coord2healpix(coords, frame, nside, nest=True):
228
"""
229
Convert astropy SkyCoord to HEALPix pixel indices.
230
231
Parameters:
232
- coords (SkyCoord): Input coordinates
233
- frame (str): Coordinate frame for HEALPix map
234
- nside (int): HEALPix resolution parameter
235
- nest (bool): Use nested pixel ordering
236
237
Returns:
238
- int | np.ndarray: HEALPix pixel indices
239
"""
240
241
def coords_to_shape(gal, shape):
242
"""
243
Reshape coordinate arrays to match target shape.
244
245
Parameters:
246
- gal (tuple): Tuple of coordinate arrays (l, b) or (l, b, d)
247
- shape (tuple): Target array shape
248
249
Returns:
250
- tuple: Reshaped coordinate arrays
251
"""
252
253
def gal_to_shape(gal, shape):
254
"""
255
Reshape Galactic coordinate arrays.
256
257
Parameters:
258
- gal (tuple): Galactic coordinate arrays (l, b, d)
259
- shape (tuple): Target shape
260
261
Returns:
262
- tuple: Reshaped arrays
263
"""
264
```
265
266
### Decorators
267
268
Function decorators that provide common coordinate and data validation functionality.
269
270
```python { .api }
271
@ensure_coord_type
272
def decorated_function(coords, **kwargs):
273
"""
274
Decorator ensuring input coordinates are astropy SkyCoord objects.
275
Converts other coordinate types to SkyCoord if possible.
276
"""
277
278
@ensure_flat_galactic
279
def decorated_function(coords, **kwargs):
280
"""
281
Decorator converting coordinates to flat Galactic coordinate arrays.
282
Handles coordinate frame conversions automatically.
283
"""
284
285
@ensure_flat_coords
286
def decorated_function(coords, **kwargs):
287
"""
288
Decorator ensuring coordinates are provided as flat arrays.
289
Handles shape normalization and validation.
290
"""
291
292
@web_api_method(url, encoder, decoder)
293
def decorated_function(coords, **kwargs):
294
"""
295
Decorator converting local method to web API call.
296
297
Parameters:
298
- url (str): API endpoint URL
299
- encoder (callable): Function to encode request parameters
300
- decoder (callable): Function to decode API response
301
"""
302
```
303
304
### Exception Classes
305
306
Standard exceptions used throughout the dustmaps ecosystem.
307
308
```python { .api }
309
class Error(Exception):
310
"""Base exception class for dustmaps."""
311
312
class CoordFrameError(Error):
313
"""Exception for unsupported coordinate frames."""
314
315
def data_missing_message(package, name):
316
"""
317
Generate helpful error message for missing data files.
318
319
Parameters:
320
- package (str): Package/module name
321
- name (str): Dataset name
322
323
Returns:
324
- str: Formatted error message with download instructions
325
"""
326
```
327
328
### JSON Serialization Support
329
330
Utilities for serializing and deserializing complex data types used in dustmaps.
331
332
```python { .api }
333
def serialize_tuple(o):
334
"""Serialize Python tuples for JSON storage."""
335
336
def deserialize_tuple(d):
337
"""Deserialize tuples from JSON data."""
338
339
def serialize_dtype(o):
340
"""Serialize NumPy dtypes for JSON storage."""
341
342
def deserialize_dtype(d):
343
"""Deserialize NumPy dtypes from JSON data."""
344
345
def serialize_ndarray(o):
346
"""Serialize NumPy arrays for JSON storage."""
347
348
def deserialize_ndarray(d):
349
"""Deserialize NumPy arrays from JSON data."""
350
351
def serialize_quantity(o):
352
"""Serialize Astropy Quantity objects for JSON storage."""
353
354
def deserialize_quantity(d):
355
"""Deserialize Astropy Quantities from JSON data."""
356
357
def serialize_skycoord(o):
358
"""Serialize Astropy SkyCoord objects for JSON storage."""
359
360
def deserialize_skycoord(d):
361
"""Deserialize SkyCoord objects from JSON data."""
362
363
def get_encoder():
364
"""
365
Get JSON encoder with custom serializers for dustmaps types.
366
367
Returns:
368
- json.JSONEncoder: Custom encoder instance
369
"""
370
371
class MultiJSONDecoder(json.JSONDecoder):
372
"""JSON decoder with custom deserializers for dustmaps types."""
373
374
def __init__(self, **kwargs):
375
"""Initialize decoder with custom object hook."""
376
377
def object_hook(self, obj):
378
"""Custom object hook for deserializing complex types."""
379
```
380
381
## Usage Patterns
382
383
### Creating Custom Dust Map
384
385
```python
386
from dustmaps.map_base import DustMap
387
import numpy as np
388
from astropy.coordinates import SkyCoord
389
390
class CustomDustMap(DustMap):
391
def __init__(self, data_file):
392
super().__init__()
393
# Load custom map data
394
self.load_data(data_file)
395
396
def query(self, coords, **kwargs):
397
# Implement custom query logic
398
# Convert coords to map coordinates
399
# Interpolate dust values
400
return dust_values
401
402
# Use custom map
403
custom_map = CustomDustMap('my_dust_map.fits')
404
coord = SkyCoord(ra=180.0, dec=0.0, unit='deg', frame='icrs')
405
extinction = custom_map(coord)
406
```
407
408
### Coordinate Validation
409
410
```python
411
from dustmaps.map_base import ensure_coord_type, ensure_flat_galactic
412
413
@ensure_coord_type
414
@ensure_flat_galactic
415
def my_dust_query(coords, **kwargs):
416
"""Function with automatic coordinate validation and conversion."""
417
# coords are guaranteed to be SkyCoord in flat Galactic coordinates
418
l, b = coords.galactic.l.degree, coords.galactic.b.degree
419
# Perform dust query
420
return dust_values
421
```
422
423
### Web API Integration
424
425
```python
426
from dustmaps.map_base import WebDustMap, web_api_method
427
428
class MyWebDustMap(WebDustMap):
429
def __init__(self):
430
super().__init__(api_url='https://api.example.com/dust', map_name='mymap')
431
432
@web_api_method('/query', encode_coords, decode_response)
433
def query(self, coords, **kwargs):
434
"""Method automatically converted to web API call."""
435
pass
436
```