Astropy: инициализация определяемого пользователем кадра координат

Я разрабатываю приложение для Raspberry Pi для управления любительским телескопом на монтировке AltAzimutal.

Азимутальная ось не идеально совмещена с зенитом. В этом случае можно указать на 2 или 3 звезды и найти матрицу преобразования между видимым телескопом и экваториальными координатами. Этот метод можно увидеть здесь. Я хочу реализовать этот метод с помощью astropy, но я не понимаю, как я могу определить опорную рамку наклоненного телескопа.

Я вычисляю матрицу трансформатина и даю ее в качестве аргумента для нового кадра. Но получаю ошибку.

Вот код:

 # coding: utf-8

 """ Astropy coordinate class for the tilted telescope coordinate system """

from __future__ import division, print_function

# Third-party
import numpy as np
from numpy import cos, sin

from astropy.coordinates import frame_transform_graph
from astropy.coordinates.angles import rotation_matrix

import astropy.coordinates as coord
import astropy.units as u


__all__ = ["MyFrame"]


import astropy.coordinates as coord


class MyFrame(coord.BaseCoordinateFrame):
    """
    A topocentric spherical coordinate system defined by the telescope on tilted Altzimutal mount
     http://www.geocities.jp/toshimi_taki/aim/aim.htm    

    Parameters
    ----------
    matrix: the transformation matrix obtained by 2 stars method ( http://www.geocities.jp/toshimi_taki/aim/aim.htm)  
    representation : `BaseRepresentation` or None
        A representation object or None to have no data (or use the other keywords)
    Lambda : `Angle`, optional, must be keyword
        The longitude-like angle corresponding to Sagittarius' orbit.
    Beta : `Angle`, optional, must be keyword
        The latitude-like angle corresponding to Sagittarius' orbit.

    """
    default_representation = coord.UnitSphericalRepresentation

    frame_specific_representation_info = {
        'spherical': [coord.RepresentationMapping('lon', 'az'),
                      coord.RepresentationMapping('lat', 'alt'),
                      coord.RepresentationMapping('distance', 'distance')],
        'unitspherical': [coord.RepresentationMapping('lon', 'az'),
                          coord.RepresentationMapping('lat', 'alt')]
    }


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


# equatorial (ICRS )  to tilted telescope AltAz coordinates
@frame_transform_graph.transform(coord.FunctionTransform, coord.ICRS, MyFrame)
def equatorial_to_telescope(icrs_frame, telescope_frame):
    """ Compute the transformation from icrs spherical to
        topocentric telescope coordinates.
    """
    matrix=np.matrix(([1,0,0],[0,1,0],[0,0,1]))
    C0=icrs_frame.represent_as(coord.CartesianRepresentation).xyz.value

    l0=matrix.dot(C0)

    altAZ=coord.SkyCoord(x=l0[0,0],y=l0[0,1],z=l0[0,2],frame='altaz',representation='cartesian').represent_as(coord.UnitSphericalRepresentation)

    return MyFrame(az=altAZ.lon.to(u.deg),  alt=altAZ.lat.to(*u.deg))

Вот вызов этого класса:

import myFrame as fr
import astropy.coordinates as coord
import astropy.units as u
import numpy as np

matrix=np.matrix(([1,0,0],[0,1,0],[0,0,1]))

m=fr.MyFrame()
icrs = coord.ICRS(152.88572*u.degree, 11.57281*u.degree)
mfr=icrs.transform_to(m)

Вот код ошибки:

TypeError                                 Traceback (most recent call last)
<ipython-input-14-33f2cd1fa087> in <module>()
----> 1 mfr=icrs.transform_to(m)

/home/maksim/MyPython/astropy/coordinates/baseframe.pyc in transform_to(self, new_frame)
    839             msg = 'Cannot transform from {0} to {1}'
    840             raise ConvertError(msg.format(self.__class__, new_frame.__class__))
--> 841         return trans(self, new_frame)
    842 
    843     def is_transformable_to(self, new_frame):

/home/maksim/MyPython/astropy/coordinates/transformations.pyc in __call__(self, fromcoord, toframe)
    915                     frattrs[inter_frame_attr_nm] = attr
    916 
--> 917             curr_toframe = t.tosys(**frattrs)
    918             curr_coord = t(curr_coord, curr_toframe)
    919 

TypeError: __init__() takes at least 2 arguments (1 given)

Я понимаю сообщение об ошибке: определение моего конструктора не соответствует ожидаемому astropy BaseFrame.

Как передать внешнюю матрицу в экземпляр BaseCoordinateFrame?


person MaksymMO    schedule 07.02.2016    source источник
comment
Используйте 1_. Вы просто определили свой MyFrame класс: посмотрите, какие аргументы принимает __init__.   -  person    schedule 07.02.2016
comment
MaksymMO Я отредактировал ваш вопрос, чтобы облегчить понимание. Пожалуйста, убедитесь, что я не изменил смысла всего, что вы сказали.   -  person Gabriel    schedule 08.02.2016


Ответы (1)


Вам не нужно и не нужно переопределять __init__ в классе фрейма, чтобы включить матрицу преобразования в качестве аргумента. Вместо этого, поскольку конкретный фрейм, определенный в вашем классе фрейма, зависит от этой матрицы, он должен быть определен как FrameAttribute, как показано в примере в документации: http://docs.astropy.org/en/stable/координаты/frames.html#defining-a-new-frame

Глядя на эти документы, я вижу, что цель определения атрибутов фрейма не так ясна, как могла бы быть. Но вкратце, простое добавление аргумента __init__ ничего не сообщает механизму координат о назначении этого аргумента / атрибута - это никоим образом не указывает на то, что это определяющий параметр фреймов в этом классе фреймов. Это информация, которую фреймворк должен знать и отслеживать.

Когда вы определяете matrix как атрибут фрейма в своем классе, он автоматически настраивает средство доступа для атрибута (т.е. self.matrix), а также принимает матрицу в качестве аргумента инициализатору фрейма.

Одна вещь, которую я не уверен, что это сразу поддерживает, - это FrameAttribute, который требуется для инициализации фрейма (обычно каждый атрибут имеет значение по умолчанию). Это может быть реализовано с помощью простой оболочки вокруг базы __init__, хотя это также может быть неплохой идеей для запроса функции.

person Iguananaut    schedule 08.02.2016