Exemple #1
0
class DetectorFrame(ITRS):
    """A coordinate frames to visualize triangulation rings from pairs of
    gravitational-wave detectors."""

    site_1 = EarthLocationAttribute()
    site_2 = EarthLocationAttribute()

    default_representation = SphericalRepresentation
Exemple #2
0
 def __init__(self, *args, **kwargs):
     loc = kwargs.get('location', None)
     if isinstance(loc, MoonLocation):
         frame_transform_graph.frame_attributes['location'] = MoonLocationAttribute(default=None)
     elif isinstance(loc, EarthLocation):
         frame_transform_graph.frame_attributes['location'] = \
             EarthLocationAttribute(default=None)
     super().__init__(*args, **kwargs)
     # Set the graph to its default
     frame_transform_graph.frame_attributes['location'] = EarthLocationAttribute(default=None)
Exemple #3
0
class CameraFrame(BaseCoordinateFrame):
    '''
    Astropy CoordinateFrame representing coordinates in the CameraPlane

    Attributes
    ----------
    pointing_direction: astropy.coordinates.AltAz
        The pointing direction of the telescope
    obstime: astropy.Time
        The timestamp of the observation, only needed to directly transform
        to Equatorial coordinates, transforming to AltAz does not need this.
    location: astropy.coordinates.EarthLocation
        The location of the observer,  only needed to directly transform
        to Equatorial coordinates, transforming to AltAz does not need this,
        default is FACT's location
    rotated: bool
        True means x points right and y points up when looking on the camera
        from the dish, which is the efinition of FACT-Tools >= 1.0 and Mars.
        False means x points up and y points left,
        which is definition in the original FACTPixelMap file.
    '''
    default_representation = PlanarRepresentation
    pointing_direction = CoordinateAttribute(frame=AltAz, default=None)
    obstime = TimeAttribute(default=None)
    location = EarthLocationAttribute(default=LOCATION)
    rotated = Attribute(default=True)
Exemple #4
0
class TelescopeFrame(BaseCoordinateFrame):
    """
    Telescope coordinate frame.

    A Frame using a UnitSphericalRepresentation.
    This is basically the same as a HorizonCoordinate, but the
    origin is at the telescope's pointing direction.

    This is used to specify coordinates in the field of view of a
    telescope that is independent of the optical properties of the telescope.

    ``fov_lon`` is aligned with azimuth and ``fov_lat`` is aligned with altitude
    of the horizontal coordinate frame as implemented in ``astropy.coordinates.AltAz``.

    This is what astropy calls a SkyOffsetCoordinate.

    Attributes
    ----------

    telescope_pointing: SkyCoord[AltAz]
        Coordinate of the telescope pointing in AltAz
    obstime: Tiem
        Observation time
    location: EarthLocation
        Location of the telescope
    """

    frame_specific_representation_info = {
        UnitSphericalRepresentation: [
            RepresentationMapping("lon", "fov_lon"),
            RepresentationMapping("lat", "fov_lat"),
        ]
    }
    default_representation = UnitSphericalRepresentation

    telescope_pointing = CoordinateAttribute(default=None, frame=AltAz)

    obstime = TimeAttribute(default=None)
    location = EarthLocationAttribute(default=None)

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # make sure telescope coordinate is in range [-180°, 180°]
        if isinstance(self._data, UnitSphericalRepresentation):
            self._data.lon.wrap_angle = Angle(180, unit=u.deg)
Exemple #5
0
class NominalFrame(BaseCoordinateFrame):
    """
    Nominal coordinate frame.

    A Frame using a UnitSphericalRepresentation.
    This is basically the same as a HorizonCoordinate, but the
    origin is at an arbitray position in the sky.
    This is what astropy calls a SkyOffsetCoordinate

    If the telescopes are in divergent pointing, this Frame can be
    used to transform to a common system.

    Attributes
    ----------

    origin: SkyCoord[AltAz]
        Origin of this frame as a HorizonCoordinate
    obstime: Tiem
        Observation time
    location: EarthLocation
        Location of the telescope
    """

    frame_specific_representation_info = {
        UnitSphericalRepresentation: [
            RepresentationMapping("lon", "fov_lon"),
            RepresentationMapping("lat", "fov_lat"),
        ]
    }
    default_representation = UnitSphericalRepresentation

    origin = CoordinateAttribute(default=None, frame=AltAz)

    obstime = TimeAttribute(default=None)
    location = EarthLocationAttribute(default=None)

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # make sure telescope coordinate is in range [-180°, 180°]
        if isinstance(self._data, UnitSphericalRepresentation):
            self._data.lon.wrap_angle = Angle(180, unit=u.deg)
Exemple #6
0
class CameraFrame(BaseCoordinateFrame):
    """
    Camera coordinate frame.

    The camera frame is a 2d cartesian frame,
    describing position of objects in the focal plane of the telescope.

    The frame is defined as in H.E.S.S., starting at the horizon,
    the telescope is pointed to magnetic north in azimuth and then up to zenith.

    Now, x points north and y points west, so in this orientation, the
    camera coordinates line up with the CORSIKA ground coordinate system.

    MAGIC and FACT use a different camera coordinate system:
    Standing at the dish, looking at the camera, x points right, y points up.
    To transform MAGIC/FACT to ctapipe, do x' = -y, y' = -x.

    Attributes
    ----------

    focal_length : u.Quantity[length]
        Focal length of the telescope as a unit quantity (usually meters)
    rotation : u.Quantity[angle]
        Rotation angle of the camera (0 deg in most cases)
    telescope_pointing : SkyCoord[AltAz]
        Pointing direction of the telescope as SkyCoord in AltAz
    obstime : Time
        Observation time
    location : EarthLocation
        location of the telescope
    """

    default_representation = PlanarRepresentation

    focal_length = QuantityAttribute(default=0, unit=u.m)
    rotation = QuantityAttribute(default=0 * u.deg, unit=u.rad)
    telescope_pointing = CoordinateAttribute(frame=AltAz, default=None)

    obstime = TimeAttribute(default=None)
    location = EarthLocationAttribute(default=None)
Exemple #7
0
class TelescopeFrame(BaseCoordinateFrame):
    '''
    Telescope coordinate frame.

    A Frame using a UnitSphericalRepresentation.
    This is basically the same as a HorizonCoordinate, but the
    origin is at the telescope's pointing direction.
    This is what astropy calls a SkyOffsetCoordinate

    Attributes
    ----------

    telescope_pointing: SkyCoord[HorizonFrame]
        Coordinate of the telescope pointing in HorizonFrame
    obstime: Tiem
        Observation time
    location: EarthLocation
        Location of the telescope
    '''
    frame_specific_representation_info = {
        UnitSphericalRepresentation: [
            RepresentationMapping('lon', 'delta_az'),
            RepresentationMapping('lat', 'delta_alt'),
        ]
    }
    default_representation = UnitSphericalRepresentation

    telescope_pointing = CoordinateAttribute(default=None, frame=HorizonFrame)

    obstime = TimeAttribute(default=None)
    location = EarthLocationAttribute(default=None)

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # make sure telescope coordinate is in range [-180°, 180°]
        if isinstance(self._data, UnitSphericalRepresentation):
            self._data.lon.wrap_angle = Angle(180, unit=u.deg)
Exemple #8
0
    def transform_to(self, frame, merge_attributes=True):
        # a modified version of the corresponding astropy function.
        from astropy.coordinates.errors import ConvertError

        frame_kwargs = {}

        # Frame name (string) or frame class?  Coerce into an instance.
        try:
            frame = _get_frame_class(frame)()
        except Exception:
            pass

        if isinstance(frame, SkyCoord):
            frame = frame.frame  # Change to underlying coord frame instance

        if isinstance(frame, BaseCoordinateFrame):
            new_frame_cls = frame.__class__
            # Get frame attributes, allowing defaults to be overridden by
            # explicitly set attributes of the source if ``merge_attributes``.
            for attr in frame_transform_graph.frame_attributes:
                self_val = getattr(self, attr, None)
                frame_val = getattr(frame, attr, None)
                if (frame_val is not None
                    and not (merge_attributes
                             and frame.is_frame_attr_default(attr))):
                    frame_kwargs[attr] = frame_val
                elif (self_val is not None
                      and not self.is_frame_attr_default(attr)):
                    frame_kwargs[attr] = self_val
                elif frame_val is not None:
                    frame_kwargs[attr] = frame_val
        else:
            raise ValueError('Transform `frame` must be a frame name, class, or instance')

        # Hacky solution here -- Frames other than LunarTopo cannot accept a MoonLocation object
        # and can get confused by it. Do not pass along `location` unless certain it will work.
        moonloc_incompatible = not isinstance(frame, LunarTopo)
        graph_attrs = frame_transform_graph.frame_attributes
        if hasattr(self, 'location'):
            loc = getattr(self, 'location')
            if isinstance(loc, MoonLocation):
                if moonloc_incompatible:
                    frame_kwargs.pop('location')
            elif 'location' in graph_attrs.keys() \
                    and isinstance(graph_attrs['location'], MoonLocationAttribute):
                frame_transform_graph.frame_attributes['location'] = \
                    EarthLocationAttribute(default=None)

        # Get the composite transform to the new frame
        trans = frame_transform_graph.get_transform(self.frame.__class__, new_frame_cls)
        if trans is None:
            raise ConvertError('Cannot transform from {} to {}'
                               .format(self.frame.__class__, new_frame_cls))

        # Make a generic frame which will accept all the frame kwargs that
        # are provided and allow for transforming through intermediate frames
        # which may require one or more of those kwargs.
        generic_frame = GenericFrame(frame_kwargs)

        # Do the transformation, returning a coordinate frame of the desired
        # final type (not generic).
        new_coord = trans(self.frame, generic_frame)

        # Finally make the new SkyCoord object from the `new_coord` and
        # remaining frame_kwargs that are not frame_attributes in `new_coord`.
        for attr in (set(new_coord.get_frame_attr_names())
                     & set(frame_kwargs.keys())):
            frame_kwargs.pop(attr)

        return self.__class__(new_coord, **frame_kwargs)