Coverage for python/lsst/sims/GalSimInterface/galSimCameraWrapper.py : 15%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1"""
2This module provides wrappers for afwCameraGeom camera objects.
3This is necessary because of a 90-degree rotation between how
4the LSST Data Management software team defines coordinate
5axes on the focal plane and how the LSST Camera team defines
6coorindate axes on the focal plane. Specifically
8Camera +y = DM +x
9Camera +x = DM -y
11Because we want ImSim images to have the same WCS conventions
12as PhoSim e-images, we need to apply this rotation to the
13mappings between RA, Dec and pixel coordinates. We may not
14wish to do that for arbitrary cameras, so we will give
15users the ability to apply a no-op wrapper to their cameras.
17The class LSSTCameraWrapper applies this transformation.
18In cases where users do not wish to apply any transformation
19to their pixel coordinate system, the class GalSimCameraWrapper
20provides the same API as LSSTCamerWrapper, but treats the
21software-based pixel coordinates as truth.
23In order to implement your own camera wrapper, create a python
24class that inherits from GalSimCameraWrapper. This class will
25need:
27- a property self.camera that is an afwCamerGeom camera object
29- a method getBBox() that returns the bounding box in pixel space
30 of a detector, given that detector's name
32- a method getCenterPixel() that returns the central pixel of a
33 detector, given that detector's name
35- a method getCenterPupil() that returns the pupil coordinates
36 (or field angle) in radians of the center of a detector given
37 that detector's name
39- a method getCornerPupilList that returns the pupil coordinates
40 (or field angles) in radians of the corners of a detector given
41 that detector's name
43- a method getTanPixelBounds() that returns the minimum and maximum
44 x and y pixel values of a detector, ignoring radial distortions,
45 given that detector's name
47- wrappers to the corresponding methods in lsst.sims.coordUtils that
48 use the self.camera property and apply the necessary transformations
49 to pixel space coordinates:
50 pixelCoordsFromPupilCoords()
51 pupilCoordsFromPixelCoords()
52 pixelCoordsFromRaDec()
53 _pixelCoordsFromRaDec()
54 raDecFromPixelCoords()
55 _raDecFromPixelCoords()
56"""
58import numpy as np
59from lsst.afw.cameraGeom import FOCAL_PLANE, PIXELS, TAN_PIXELS
60from lsst.afw.cameraGeom import FIELD_ANGLE
61import lsst.geom as LsstGeom
62import lsst.sims.coordUtils as coordUtils
63import lsst.sims.utils as simsUtils
65__all__ = ["GalSimCameraWrapper", "LSSTCameraWrapper"]
67class GalSimCameraWrapper(object):
68 """
69 This is a no-op camera wrapper.
70 """
72 def __init__(self, camera):
73 """
74 Parameters
75 ----------
76 camera is an instantiation of an afwCameraGeom camera
77 """
78 self._camera = camera
80 @property
81 def camera(self):
82 return self._camera
84 @property
85 def focal_to_field(self):
86 """
87 Transformation to go from FOCAL_PLANE to FIELD_ANGLE
88 """
89 if not hasattr(self, '_focal_to_field'):
90 self._focal_to_field = self.camera.getTransformMap().getTransform(FOCAL_PLANE, FIELD_ANGLE)
91 return self._focal_to_field
93 def getBBox(self, detector_name):
94 """
95 Return the bounding box for the detector named by detector_name
96 """
97 return self._camera[detector_name].getBBox()
99 def getCenterPixel(self, detector_name):
100 """
101 Return the central pixel for the detector named by detector_name
102 """
103 if not hasattr(self, '_center_pixel_cache'):
104 self._center_pixel_cache = {}
106 if detector_name not in self._center_pixel_cache:
107 centerPoint = self._camera[detector_name].getCenter(FOCAL_PLANE)
108 centerPixel = self._camera[detector_name].getTransform(FOCAL_PLANE, PIXELS).applyForward(centerPoint)
109 self._center_pixel_cache[detector_name] = centerPixel
111 return self._center_pixel_cache[detector_name]
113 def getCenterPupil(self, detector_name):
114 """
115 Return the pupil coordinates of the center of the named detector
116 as an LsstGeom.Point2D
117 """
118 if not hasattr(self, '_center_pupil_cache'):
119 self._center_pupil_cache = {}
121 if detector_name not in self._center_pupil_cache:
122 dd = self._camera[detector_name]
123 centerPoint = dd.getCenter(FOCAL_PLANE)
124 pupilPoint = self.focal_to_field.applyForward(centerPoint)
125 self._center_pupil_cache[detector_name] = pupilPoint
127 return self._center_pupil_cache[detector_name]
129 def getCornerPupilList(self, detector_name):
130 """
131 Return a list of the pupil coordinates of the corners of the named
132 detector as a list of LsstGeom.Point2D objects
133 """
134 if not hasattr(self, '_corner_pupil_cache'):
135 self._corner_pupil_cache = {}
137 if detector_name not in self._corner_pupil_cache:
138 dd = self._camera[detector_name]
139 cornerPointList = dd.getCorners(FOCAL_PLANE)
140 pupil_point_list = self.focal_to_field.applyForward(cornerPointList)
141 self._corner_pupil_cache[detector_name] = pupil_point_list
143 return self._corner_pupil_cache[detector_name]
145 def getTanPixelBounds(self, detector_name):
146 """
147 Return the min and max pixel values of a detector, assuming
148 all radial distortions are set to zero (i.e. using the afwCameraGeom
149 TAN_PIXELS coordinate system)
151 Parameters
152 ----------
153 detector_name is a string denoting the name of the detector
155 Returns
156 -------
157 xmin, xmax, ymin, ymax pixel values
158 """
159 if not hasattr(self, '_tan_pixel_bounds_cache'):
160 self._tan_pixel_bounds_cache = {}
162 if detector_name not in self._tan_pixel_bounds_cache:
163 afwDetector = self._camera[detector_name]
164 focal_to_tan_pix = afwDetector.getTransform(FOCAL_PLANE, TAN_PIXELS)
165 xPixMin = None
166 xPixMax = None
167 yPixMin = None
168 yPixMax = None
169 cornerPointList = focal_to_tan_pix.applyForward(afwDetector.getCorners(FOCAL_PLANE))
170 for cornerPoint in cornerPointList:
171 xx = cornerPoint.getX()
172 yy = cornerPoint.getY()
173 if xPixMin is None or xx < xPixMin:
174 xPixMin = xx
175 if xPixMax is None or xx > xPixMax:
176 xPixMax = xx
177 if yPixMin is None or yy < yPixMin:
178 yPixMin = yy
179 if yPixMax is None or yy > yPixMax:
180 yPixMax = yy
182 self._tan_pixel_bounds_cache[detector_name] = (xPixMin, xPixMax, yPixMin, yPixMax)
184 return self._tan_pixel_bounds_cache[detector_name]
186 def pixelCoordsFromPupilCoords(self, xPupil, yPupil, chipName, obs_metadata,
187 includeDistortion=True):
188 """
189 Get the pixel positions (or nan if not on a chip) for objects based
190 on their pupil coordinates.
192 Parameters
193 ---------
194 xPupil is the x pupil coordinates in radians. Can be either a float
195 or a numpy array.
197 yPupil is the y pupil coordinates in radians. Can be either a float
198 or a numpy array.
200 chipName designates the names of the chips on which the pixel
201 coordinates will be reckoned. Can be either single value, an array, or None.
202 If an array, there must be as many chipNames as there are (RA, Dec) pairs.
203 If a single value, all of the pixel coordinates will be reckoned on the same
204 chip. If None, this method will calculate which chip each(RA, Dec) pair actually
205 falls on, and return pixel coordinates for each (RA, Dec) pair on the appropriate
206 chip.
208 obs_metadata is an ObservationMetaData characterizing the telescope
209 pointing.
211 includeDistortion is a boolean. If True (default), then this method will
212 return the true pixel coordinates with optical distortion included. If False, this
213 method will return TAN_PIXEL coordinates, which are the pixel coordinates with
214 estimated optical distortion removed. See the documentation in afw.cameraGeom for more
215 details.
217 Returns
218 -------
219 a 2-D numpy array in which the first row is the x pixel coordinate
220 and the second row is the y pixel coordinate
221 """
222 if obs_metadata is None:
223 raise RuntimeError("Must pass obs_metdata to "
224 "cameraWrapper.pixelCoordsFromPupilCoords")
226 return coordUtils.pixelCoordsFromPupilCoords(xPupil, yPupil, chipName=chipName,
227 camera=self._camera,
228 includeDistortion=includeDistortion)
230 def pupilCoordsFromPixelCoords(self, xPix, yPix, chipName, obs_metadata,
231 includeDistortion=True):
233 """
234 Convert pixel coordinates into pupil coordinates
236 Parameters
237 ----------
238 xPix is the x pixel coordinate of the point.
239 Can be either a float or a numpy array.
241 yPix is the y pixel coordinate of the point.
242 Can be either a float or a numpy array.
244 chipName is the name of the chip(s) on which the pixel coordinates
245 are defined. This can be a list (in which case there should be one chip name
246 for each (xPix, yPix) coordinate pair), or a single value (in which case, all
247 of the (xPix, yPix) points will be reckoned on that chip).
249 obs_metadata is an ObservationMetaData characterizing the telescope
250 pointing.
252 includeDistortion is a boolean. If True (default), then this method will
253 expect the true pixel coordinates with optical distortion included. If False, this
254 method will expect TAN_PIXEL coordinates, which are the pixel coordinates with
255 estimated optical distortion removed. See the documentation in afw.cameraGeom for more
256 details.
258 Returns
259 -------
260 a 2-D numpy array in which the first row is the x pupil coordinate
261 and the second row is the y pupil coordinate (both in radians)
262 """
264 return coordUtils.pupilCoordsFromPixelCoords(xPix, yPix, chipName,
265 camera=self._camera,
266 includeDistortion=includeDistortion)
268 def _raDecFromPixelCoords(self, xPix, yPix, chipName, obs_metadata,
269 epoch=2000.0, includeDistortion=True):
270 """
271 Convert pixel coordinates into RA, Dec
273 Parameters
274 ----------
275 xPix is the x pixel coordinate. It can be either
276 a float or a numpy array.
278 yPix is the y pixel coordinate. It can be either
279 a float or a numpy array.
281 chipName is the name of the chip(s) on which the pixel coordinates
282 are defined. This can be a list (in which case there should be one chip name
283 for each (xPix, yPix) coordinate pair), or a single value (in which case, all
284 of the (xPix, yPix) points will be reckoned on that chip).
286 obs_metadata is an ObservationMetaData defining the pointing
288 epoch is the mean epoch in years of the celestial coordinate system.
289 Default is 2000.
291 includeDistortion is a boolean. If True (default), then this method will
292 expect the true pixel coordinates with optical distortion included. If False, this
293 method will expect TAN_PIXEL coordinates, which are the pixel coordinates with
294 estimated optical distortion removed. See the documentation in afw.cameraGeom for more
295 details.
297 Returns
298 -------
299 a 2-D numpy array in which the first row is the RA coordinate
300 and the second row is the Dec coordinate (both in radians; in the
301 International Celestial Reference System)
303 WARNING: This method does not account for apparent motion due to parallax.
304 This method is only useful for mapping positions on a theoretical focal plane
305 to positions on the celestial sphere.
306 """
308 return coordUtils._raDecFromPixelCoords(xPix, yPix, chipName,
309 camera=self._camera,
310 obs_metadata=obs_metadata,
311 epoch=epoch,
312 includeDistortion=includeDistortion)
314 def raDecFromPixelCoords(self, xPix, yPix, chipName, obs_metadata,
315 epoch=2000.0, includeDistortion=True):
317 """
318 Convert pixel coordinates into RA, Dec
320 Parameters
321 ----------
322 xPix is the x pixel coordinate. It can be either
323 a float or a numpy array.
325 yPix is the y pixel coordinate. It can be either
326 a float or a numpy array.
328 chipName is the name of the chip(s) on which the pixel coordinates
329 are defined. This can be a list (in which case there should be one chip name
330 for each (xPix, yPix) coordinate pair), or a single value (in which case, all
331 of the (xPix, yPix) points will be reckoned on that chip).
333 obs_metadata is an ObservationMetaData defining the pointing
335 epoch is the mean epoch in years of the celestial coordinate system.
336 Default is 2000.
338 includeDistortion is a boolean. If True (default), then this method will
339 expect the true pixel coordinates with optical distortion included. If False, this
340 method will expect TAN_PIXEL coordinates, which are the pixel coordinates with
341 estimated optical distortion removed. See the documentation in afw.cameraGeom for more
342 details.
344 Returns
345 -------
346 a 2-D numpy array in which the first row is the RA coordinate
347 and the second row is the Dec coordinate (both in degrees; in the
348 International Celestial Reference System)
350 WARNING: This method does not account for apparent motion due to parallax.
351 This method is only useful for mapping positions on a theoretical focal plane
352 to positions on the celestial sphere.
353 """
355 return coordUtils.raDecFromPixelCoords(xPix, yPix, chipName,
356 camera=self._camera,
357 obs_metadata=obs_metadata,
358 epoch=2000.0, includeDistortion=True)
360 def _pixelCoordsFromRaDec(self, ra, dec, pm_ra=None, pm_dec=None,
361 parallax=None, v_rad=None,
362 obs_metadata=None,
363 chipName=None,
364 epoch=2000.0, includeDistortion=True):
365 """
366 Get the pixel positions (or nan if not on a chip) for objects based
367 on their RA, and Dec (in radians)
369 Parameters
370 ----------
371 ra is in radians in the International Celestial Reference System.
372 Can be either a float or a numpy array.
374 dec is in radians in the International Celestial Reference System.
375 Can be either a float or a numpy array.
377 pm_ra is proper motion in RA multiplied by cos(Dec) (radians/yr)
378 Can be a numpy array or a number or None (default=None).
380 pm_dec is proper motion in dec (radians/yr)
381 Can be a numpy array or a number or None (default=None).
383 parallax is parallax in radians
384 Can be a numpy array or a number or None (default=None).
386 v_rad is radial velocity (km/s)
387 Can be a numpy array or a number or None (default=None).
389 obs_metadata is an ObservationMetaData characterizing the telescope
390 pointing.
392 epoch is the epoch in Julian years of the equinox against which
393 RA is measured. Default is 2000.
395 chipName designates the names of the chips on which the pixel
396 coordinates will be reckoned. Can be either single value, an array, or None.
397 If an array, there must be as many chipNames as there are (RA, Dec) pairs.
398 If a single value, all of the pixel coordinates will be reckoned on the same
399 chip. If None, this method will calculate which chip each(RA, Dec) pair actually
400 falls on, and return pixel coordinates for each (RA, Dec) pair on the appropriate
401 chip. Default is None.
403 includeDistortion is a boolean. If True (default), then this method will
404 return the true pixel coordinates with optical distortion included. If False, this
405 method will return TAN_PIXEL coordinates, which are the pixel coordinates with
406 estimated optical distortion removed. See the documentation in afw.cameraGeom for more
407 details.
409 Returns
410 -------
411 a 2-D numpy array in which the first row is the x pixel coordinate
412 and the second row is the y pixel coordinate
413 """
415 return coordUtils._pixelCoordsFromRaDec(ra, dec, pm_ra=pm_ra, pm_dec=pm_dec,
416 parallax=parallax, v_rad=v_rad,
417 obs_metadata=obs_metadata,
418 chipName=chipName, camera=self._camera,
419 epoch=epoch, includeDistortion=includeDistortion)
421 def pixelCoordsFromRaDec(self, ra, dec, pm_ra=None, pm_dec=None, parallax=None, v_rad=None,
422 obs_metadata=None,
423 chipName=None, camera=None,
424 epoch=2000.0, includeDistortion=True):
425 """
426 Get the pixel positions (or nan if not on a chip) for objects based
427 on their RA, and Dec (in degrees)
429 Parameters
430 ----------
431 ra is in degrees in the International Celestial Reference System.
432 Can be either a float or a numpy array.
434 dec is in degrees in the International Celestial Reference System.
435 Can be either a float or a numpy array.
437 pm_ra is proper motion in RA multiplied by cos(Dec) (arcsec/yr)
438 Can be a numpy array or a number or None (default=None).
440 pm_dec is proper motion in dec (arcsec/yr)
441 Can be a numpy array or a number or None (default=None).
443 parallax is parallax in arcsec
444 Can be a numpy array or a number or None (default=None).
446 v_rad is radial velocity (km/s)
447 Can be a numpy array or a number or None (default=None).
449 obs_metadata is an ObservationMetaData characterizing the telescope
450 pointing.
452 epoch is the epoch in Julian years of the equinox against which
453 RA is measured. Default is 2000.
455 chipName designates the names of the chips on which the pixel
456 coordinates will be reckoned. Can be either single value, an array, or None.
457 If an array, there must be as many chipNames as there are (RA, Dec) pairs.
458 If a single value, all of the pixel coordinates will be reckoned on the same
459 chip. If None, this method will calculate which chip each(RA, Dec) pair actually
460 falls on, and return pixel coordinates for each (RA, Dec) pair on the appropriate
461 chip. Default is None.
463 includeDistortion is a boolean. If True (default), then this method will
464 return the true pixel coordinates with optical distortion included. If False, this
465 method will return TAN_PIXEL coordinates, which are the pixel coordinates with
466 estimated optical distortion removed. See the documentation in afw.cameraGeom for more
467 details.
469 Returns
470 -------
471 a 2-D numpy array in which the first row is the x pixel coordinate
472 and the second row is the y pixel coordinate
473 """
475 return coordUtils.pixelCoordsFromRaDec(ra, dec, pm_ra=pm_ra, pm_dec=pm_dec,
476 parallax=parallax, v_rad=v_rad,
477 obs_metadata=obs_metadata,
478 chipName=chipName, camera=self._camera,
479 epoch=epoch, includeDistortion=includeDistortion)
483class LSSTCameraWrapper(coordUtils.DMtoCameraPixelTransformer,
484 GalSimCameraWrapper):
486 def getTanPixelBounds(self, detector_name):
487 """
488 Return the min and max pixel values of a detector, assuming
489 all radial distortions are set to zero (i.e. using the afwCameraGeom
490 TAN_PIXELS coordinate system)
492 Parameters
493 ----------
494 detector_name is a string denoting the name of the detector
496 Returns
497 -------
498 xmin, xmax, ymin, ymax pixel values
499 """
500 if not hasattr(self, '_tan_pixel_bounds_cache'):
501 self._tan_pixel_bounds_cache = {}
503 if detector_name not in self._tan_pixel_bounds_cache:
504 dm_xmin, dm_xmax, dm_ymin, dm_ymax = GalSimCameraWrapper.getTanPixelBounds(self, detector_name)
505 self._tan_pixel_bounds_cache[detector_name] = (dm_ymin, dm_ymax, dm_xmin, dm_xmax)
507 return self._tan_pixel_bounds_cache[detector_name]
509 def pixelCoordsFromPupilCoords(self, xPupil, yPupil, chipName, obs_metadata,
510 includeDistortion=True):
511 """
512 Get the pixel positions (or nan if not on a chip) for objects based
513 on their pupil coordinates.
515 Paramters
516 ---------
517 xPupil is the x pupil coordinates in radians. Can be either a float
518 or a numpy array.
520 yPupil is the y pupil coordinates in radians. Can be either a float
521 or a numpy array.
523 chipName designates the names of the chips on which the pixel
524 coordinates will be reckoned. Can be either single value, an array, or None.
525 If an array, there must be as many chipNames as there are (RA, Dec) pairs.
526 If a single value, all of the pixel coordinates will be reckoned on the same
527 chip. If None, this method will calculate which chip each(RA, Dec) pair actually
528 falls on, and return pixel coordinates for each (RA, Dec) pair on the appropriate
529 chip.
531 obs_metadata is an ObservationMetaData characterizing the telescope
532 pointing.
534 includeDistortion is a boolean. If True (default), then this method will
535 return the true pixel coordinates with optical distortion included. If False, this
536 method will return TAN_PIXEL coordinates, which are the pixel coordinates with
537 estimated optical distortion removed. See the documentation in afw.cameraGeom for more
538 details.
540 Returns
541 -------
542 a 2-D numpy array in which the first row is the x pixel coordinate
543 and the second row is the y pixel coordinate. These pixel coordinates
544 are defined in the Camera team system, rather than the DM system.
545 """
546 (dm_x_pix,
547 dm_y_pix) = coordUtils.pixelCoordsFromPupilCoordsLSST(xPupil, yPupil,
548 chipName=chipName,
549 band=obs_metadata.bandpass,
550 includeDistortion=includeDistortion)
552 cam_y_pix = dm_x_pix
553 if isinstance(chipName, list) or isinstance(chipName, np.ndarray):
554 center_pix_dict = {}
555 cam_x_pix = np.zeros(len(dm_y_pix))
556 for ix, (det_name, yy) in enumerate(zip(chipName, dm_y_pix)):
557 if det_name not in center_pix_dict:
558 center_pix = self.getCenterPixel(det_name)
559 center_pix_dict[det_name] = center_pix
560 else:
561 center_pix = center_pix_dict[det_name]
562 cam_x_pix[ix] = 2.0*center_pix[0]-yy
563 else:
564 center_pix = self.getCenterPixel(chipName)
565 cam_x_pix = 2.0*center_pix[0] - dm_y_pix
567 return cam_x_pix, cam_y_pix
569 def pupilCoordsFromPixelCoords(self, xPix, yPix, chipName, obs_metadata,
570 includeDistortion=True):
571 """
572 Convert pixel coordinates into pupil coordinates
574 Parameters
575 ----------
576 xPix is the x pixel coordinate of the point.
577 Can be either a float or a numpy array.
578 Defined in the Camera team system (not the DM system).
580 yPix is the y pixel coordinate of the point.
581 Can be either a float or a numpy array.
582 Defined in the Camera team system (not the DM system).
584 chipName is the name of the chip(s) on which the pixel coordinates
585 are defined. This can be a list (in which case there should be one chip name
586 for each (xPix, yPix) coordinate pair), or a single value (in which case, all
587 of the (xPix, yPix) points will be reckoned on that chip).
589 obs_metadata is an ObservationMetaData characterizing the telescope
590 pointing.
592 includeDistortion is a boolean. If True (default), then this method will
593 expect the true pixel coordinates with optical distortion included. If False, this
594 method will expect TAN_PIXEL coordinates, which are the pixel coordinates with
595 estimated optical distortion removed. See the documentation in afw.cameraGeom for more
596 details.
598 Returns
599 -------
600 a 2-D numpy array in which the first row is the x pupil coordinate
601 and the second row is the y pupil coordinate (both in radians)
602 """
603 dm_xPix = yPix
604 if isinstance(chipName, list) or isinstance(chipName, np.ndarray):
605 dm_yPix = np.zeros(len(xPix))
606 for ix, (det_name, xx) in enumerate(zip(chipName, xPix)):
607 came_center_pix = self.getCenterPixel(det_name)
608 dm_yPix[ix] = 2.0*cam_center_pix.getX()-xPix[ix]
609 else:
610 cam_center_pix = self.getCenterPixel(chipName)
611 dm_yPix = 2.0*cam_center_pix.getX()-xPix
612 return coordUtils.pupilCoordsFromPixelCoordsLSST(dm_xPix, dm_yPix, chipName,
613 band=obs_metadata.bandpass,
614 includeDistortion=includeDistortion)
616 def _raDecFromPixelCoords(self, xPix, yPix, chipName, obs_metadata,
617 epoch=2000.0, includeDistortion=True):
618 """
619 Convert pixel coordinates into RA, Dec
621 Parameters
622 ----------
623 xPix is the x pixel coordinate. It can be either
624 a float or a numpy array. Defined in the Camera
625 team system (not the DM system).
627 yPix is the y pixel coordinate. It can be either
628 a float or a numpy array. Defined in the Camera
629 team system (not the DM system).
631 chipName is the name of the chip(s) on which the pixel coordinates
632 are defined. This can be a list (in which case there should be one chip name
633 for each (xPix, yPix) coordinate pair), or a single value (in which case, all
634 of the (xPix, yPix) points will be reckoned on that chip).
636 obs_metadata is an ObservationMetaData defining the pointing
638 epoch is the mean epoch in years of the celestial coordinate system.
639 Default is 2000.
641 includeDistortion is a boolean. If True (default), then this method will
642 expect the true pixel coordinates with optical distortion included. If False, this
643 method will expect TAN_PIXEL coordinates, which are the pixel coordinates with
644 estimated optical distortion removed. See the documentation in afw.cameraGeom for more
645 details.
647 Returns
648 -------
649 a 2-D numpy array in which the first row is the RA coordinate
650 and the second row is the Dec coordinate (both in radians; in the
651 International Celestial Reference System)
653 WARNING: This method does not account for apparent motion due to parallax.
654 This method is only useful for mapping positions on a theoretical focal plane
655 to positions on the celestial sphere.
656 """
658 if isinstance(chipName, list) or isinstance(chipName, np.ndarray):
659 dm_xPix = yPix
660 dm_yPix = np.zeros(len(xPix))
661 for ix, (det_name, xx) in enumerate(zip(chipName, xPix)):
662 cam_center_pix = self.getCenterPixel(det_name)
663 dm_yPix[ix] = 2.0*cam_center_pix.getX() - xx
664 else:
665 dm_xPix = yPix
666 cam_center_pix = self.getCenterPixel(chipName)
667 dm_yPix = 2.0*cam_center_pix.getX() - xPix
669 return coordUtils._raDecFromPixelCoordsLSST(dm_xPix, dm_yPix, chipName,
670 obs_metadata=obs_metadata,
671 band=obs_metadata.bandpass,
672 epoch=epoch,
673 includeDistortion=includeDistortion)
675 def raDecFromPixelCoords(self, xPix, yPix, chipName, obs_metadata,
676 epoch=2000.0, includeDistortion=True):
677 """
678 Convert pixel coordinates into RA, Dec
680 Parameters
681 ----------
682 xPix is the x pixel coordinate. It can be either
683 a float or a numpy array. Defined in the Camera
684 team system (not the DM system).
686 yPix is the y pixel coordinate. It can be either
687 a float or a numpy array. Defined in the Camera
688 team system (not the DM system).
690 chipName is the name of the chip(s) on which the pixel coordinates
691 are defined. This can be a list (in which case there should be one chip name
692 for each (xPix, yPix) coordinate pair), or a single value (in which case, all
693 of the (xPix, yPix) points will be reckoned on that chip).
695 obs_metadata is an ObservationMetaData defining the pointing
697 epoch is the mean epoch in years of the celestial coordinate system.
698 Default is 2000.
700 includeDistortion is a boolean. If True (default), then this method will
701 expect the true pixel coordinates with optical distortion included. If False, this
702 method will expect TAN_PIXEL coordinates, which are the pixel coordinates with
703 estimated optical distortion removed. See the documentation in afw.cameraGeom for more
704 details.
706 Returns
707 -------
708 a 2-D numpy array in which the first row is the RA coordinate
709 and the second row is the Dec coordinate (both in degrees; in the
710 International Celestial Reference System)
712 WARNING: This method does not account for apparent motion due to parallax.
713 This method is only useful for mapping positions on a theoretical focal plane
714 to positions on the celestial sphere.
715 """
717 _ra, _dec = self._raDecFromPixelCoords(xPix, yPix, chipName,
718 obs_metadata=obs_metadata,
719 epoch=2000.0, includeDistortion=True)
721 return np.degrees(_ra), np.degrees(_dec)
723 def _pixelCoordsFromRaDec(self, ra, dec, pm_ra=None, pm_dec=None, parallax=None, v_rad=None,
724 obs_metadata=None,
725 chipName=None,
726 epoch=2000.0, includeDistortion=True):
727 """
728 Get the pixel positions (or nan if not on a chip) for objects based
729 on their RA, and Dec (in radians)
731 Parameters
732 ----------
733 ra is in radians in the International Celestial Reference System.
734 Can be either a float or a numpy array.
736 dec is in radians in the International Celestial Reference System.
737 Can be either a float or a numpy array.
739 pm_ra is proper motion in RA multiplied by cos(Dec) (radians/yr)
740 Can be a numpy array or a number or None (default=None).
742 pm_dec is proper motion in dec (radians/yr)
743 Can be a numpy array or a number or None (default=None).
745 parallax is parallax in radians
746 Can be a numpy array or a number or None (default=None).
748 v_rad is radial velocity (km/s)
749 Can be a numpy array or a number or None (default=None).
751 obs_metadata is an ObservationMetaData characterizing the telescope
752 pointing.
754 epoch is the epoch in Julian years of the equinox against which
755 RA is measured. Default is 2000.
757 chipName designates the names of the chips on which the pixel
758 coordinates will be reckoned. Can be either single value, an array, or None.
759 If an array, there must be as many chipNames as there are (RA, Dec) pairs.
760 If a single value, all of the pixel coordinates will be reckoned on the same
761 chip. If None, this method will calculate which chip each(RA, Dec) pair actually
762 falls on, and return pixel coordinates for each (RA, Dec) pair on the appropriate
763 chip. Default is None.
765 includeDistortion is a boolean. If True (default), then this method will
766 return the true pixel coordinates with optical distortion included. If False, this
767 method will return TAN_PIXEL coordinates, which are the pixel coordinates with
768 estimated optical distortion removed. See the documentation in afw.cameraGeom for more
769 details.
771 Returns
772 -------
773 a 2-D numpy array in which the first row is the x pixel coordinate
774 and the second row is the y pixel coordinate. These pixel coordinates
775 are defined in the Camera team system, rather than the DM system.
776 """
778 dm_xPix, dm_yPix = coordUtils._pixelCoordsFromRaDecLSST(ra, dec,
779 pm_ra=pm_ra, pm_dec=pm_dec,
780 parallax=parallax, v_rad=v_rad,
781 obs_metadata=obs_metadata,
782 chipName=chipName,
783 band=obs_metadata.bandpass,
784 epoch=epoch,
785 includeDistortion=includeDistortion)
787 return self.cameraPixFromDMPix(dm_xPix, dm_yPix, chipName)
789 def pixelCoordsFromRaDec(self, ra, dec, pm_ra=None, pm_dec=None, parallax=None, v_rad=None,
790 obs_metadata=None, chipName=None,
791 epoch=2000.0, includeDistortion=True):
792 """
793 Get the pixel positions (or nan if not on a chip) for objects based
794 on their RA, and Dec (in degrees)
796 Parameters
797 ----------
798 ra is in degrees in the International Celestial Reference System.
799 Can be either a float or a numpy array.
801 dec is in degrees in the International Celestial Reference System.
802 Can be either a float or a numpy array.
804 pm_ra is proper motion in RA multiplied by cos(Dec) (arcsec/yr)
805 Can be a numpy array or a number or None (default=None).
807 pm_dec is proper motion in dec (arcsec/yr)
808 Can be a numpy array or a number or None (default=None).
810 parallax is parallax in arcsec
811 Can be a numpy array or a number or None (default=None).
813 v_rad is radial velocity (km/s)
814 Can be a numpy array or a number or None (default=None).
816 obs_metadata is an ObservationMetaData characterizing the telescope
817 pointing.
819 epoch is the epoch in Julian years of the equinox against which
820 RA is measured. Default is 2000.
822 chipName designates the names of the chips on which the pixel
823 coordinates will be reckoned. Can be either single value, an array, or None.
824 If an array, there must be as many chipNames as there are (RA, Dec) pairs.
825 If a single value, all of the pixel coordinates will be reckoned on the same
826 chip. If None, this method will calculate which chip each(RA, Dec) pair actually
827 falls on, and return pixel coordinates for each (RA, Dec) pair on the appropriate
828 chip. Default is None.
830 includeDistortion is a boolean. If True (default), then this method will
831 return the true pixel coordinates with optical distortion included. If False, this
832 method will return TAN_PIXEL coordinates, which are the pixel coordinates with
833 estimated optical distortion removed. See the documentation in afw.cameraGeom for more
834 details.
836 Returns
837 -------
838 a 2-D numpy array in which the first row is the x pixel coordinate
839 and the second row is the y pixel coordinate. These pixel coordinates
840 are defined in the Camera team system, rather than the DM system.
841 """
843 if pm_ra is not None:
844 pm_ra_out = simsUtils.radiansFromArcsec(pm_ra)
845 else:
846 pm_ra_out = None
848 if pm_dec is not None:
849 pm_dec_out = simsUtils.radiansFromArcsec(pm_dec)
850 else:
851 pm_dec_out = None
853 if parallax is not None:
854 parallax_out = simsUtils.radiansFromArcsec(parallax)
855 else:
856 parallax_out = None
858 return self._pixelCoordsFromRaDec(np.radians(ra), np.radians(dec),
859 pm_ra=pm_ra_out, pm_dec=pm_dec_out,
860 parallax=parallax_out, v_rad=v_rad,
861 chipName=chipName, obs_metadata=obs_metadata,
862 epoch=2000.0, includeDistortion=includeDistortion)