Source code for exosim.tasks.instrument.computeSourcesPointingOffset

import astropy.units as u
from astropy.coordinates import SkyCoord

from exosim.tasks.task import Task


[docs]class ComputeSourcesPointingOffset(Task): """ It computes the source offset on the focal plane respect to the pointing direction. The offset is in units of subpixels. Returns ------- int offset in the spatial direction int offset in the spectral direction """ def __init__(self): """ Parameters __________ parameters: dict channel parameter dictionary. This is usually parsed from :class:`~exosim.tasks.load.loadOptions.LoadOptions` source: dict dictionary containing :class:`~exosim.models.signal.Sed` metadata pointing: tuple telescope pointing direction, expressed as a tuple of RA and DEC. Default is ``None`` """ self.add_task_param("parameters", "channel parameters dict") self.add_task_param("source", "source source description dictionary") self.add_task_param("pointing", "telescope pointing")
[docs] def execute(self): parameters = self.get_task_param("parameters") source = self.get_task_param("source") pointing = self.get_task_param("pointing") compute = True if pointing else False if "ra" in source["parsed_parameters"].keys(): self.debug("RA found in source description") compute *= True else: compute *= False if "dec" in source["parsed_parameters"].keys(): self.debug("DEC found in source description") compute *= True else: compute *= False if "plate_scale" in parameters["detector"].keys(): self.debug("plate scale found in source description") compute *= True else: compute *= False if compute: aov_spatial, aov_spectral = angle_of_view( parameters["detector"]["plate_scale"], parameters["detector"]["delta_pix"], parameters["detector"]["oversampling"], ) self.debug( "Angle of View estimated: {}, {}".format( aov_spatial, aov_spectral ) ) c_tel = SkyCoord(pointing[0], pointing[1], frame="icrs") c_source = SkyCoord( source["parsed_parameters"]["ra"], source["parsed_parameters"]["dec"], frame="icrs", ) offset_spatial = ( c_tel.ra.deg - c_source.ra.deg ) / aov_spatial.value offset_spectral = ( c_tel.dec.deg - c_source.dec.deg ) / aov_spectral.value self.debug( "offset estimated:{} {}".format( offset_spectral, offset_spatial ) ) else: self.debug( "Angle of View computation skipped: missing information" ) offset_spectral = offset_spatial = 0 self.set_output([int(offset_spatial), int(offset_spectral)])
[docs]def angle_of_view(plate_scale, delta_pix, ovs): """ Computes the Angle of View for a single pixel Parameters ---------- plate_scale: :class:`astropy.units.Quantity` plate scale delta_pix: :class:`astropy.units.Quantity` size of a pixel Returns ------- :class:`astropy.units.Quantity` angle of view in deg of each subpixel in the spatial direction :class:`astropy.units.Quantity` angle of view in deg of each subpixel in the spectral direction """ def _compute_angle(plate_scale): if isinstance(plate_scale, u.Quantity): try: plate_scale.to(u.deg / u.micron) angle = plate_scale * delta_pix / ovs except u.UnitConversionError: try: plate_scale.to(u.arcsec / u.pixel) angle = plate_scale * u.pixel / ovs except u.UnitConversionError: raise u.UnitConversionError( "wrong plate scale units: {}".format(plate_scale.unit) ) else: raise OSError("missing plate scale units") return angle.to(u.deg) if isinstance(plate_scale, dict): spatial_angle = _compute_angle(plate_scale["spatial"]) spectral_angle = _compute_angle(plate_scale["spectral"]) else: spatial_angle = spectral_angle = _compute_angle(plate_scale) return spatial_angle, spectral_angle