Astropy: ValueError: один из входных данных для search_around_sky — это скаляр в search_around_sky.

Мне нужно хорошее объяснение или пример того, как работает Astropy search_around_*. К сожалению, туториал с официальной страницы мне не помогает.

У меня есть каталог с источниками наземной истины (GT). У меня также есть несколько патчей (соответствующих изображениям), которые включают в себя некоторые из тех, которые включены в мой каталог GT. Я хочу узнать, какие источники в моем каталоге GT включены в патч для изображений.

Мой каталог GT организован примерно так: ID ... RA, Dec ... и это файл .txt.

Вот я и хочу вернуть какие координаты в ГТ включены в патч.

Что я сделал, так это то, что я получил WCS из заголовка патча, и у меня есть мировой центр изображения. Затем я попытался протестировать фактический код, предоставленный официальной документацией (http://docs.astropy.org/en/stable/coordinates/matchsep.html).

Я использовал следующий код, предполагая, что 2-й аргумент search_around_sky - это градусы, которые он ищет (??)

x,y,w=patch_celestial_center(patch=None) #x,y are the World center of the patch
c=SkyCoord(ra=x*u.deg,dec=y*u.deg,  frame=FK5)

cat=ascii.read("$training_set.txt")

catalogue_coo=SkyCoord(cat["RA(core)"]*u.deg, cat["DEC(core)"]*u.deg, frame=FK5)

idx_1, idx_2 d2d_, d3d_ = catalogue_coo.search_around_sky(c, 1*u.deg)

Я получаю следующую ошибку:

Traceback (most recent call last):
  File "$$/train_utils.py", line 49, in <module>
    x,y,w=patch_celestial_center(patch=None)
  File "$$train_utils.py", line 43, in patch_celestial_center
    idxc, idxcatalog, d2d, d3d = catalog.search_around_sky(c, 1 * u.deg)
  File "$$/lib/python3.5/site-packages/astropy/coordinates/sky_coordinate.py", line 1170, in search_around_sky
    storekdtree='_kdtree_sky')
  File "$$/lib/python3.5/site-packages/astropy/coordinates/matching.py", line 330, in search_around_sky
    raise ValueError('One of the inputs to search_around_sky is a scalar. '
ValueError: One of the inputs to search_around_sky is a scalar. search_around_sky is intended for use with array coordinates, not scalars.  Instead, use ``coord1.separation(coord2) < seplimit`` to find the coordinates near a scalar coordinate.

Process finished with exit code 1

это что-то, что связано с моими данными перед тестированием? Это из-за формирования моего каталога?

Я чего-то не понимаю в функциональности search_around_sky?

Пожалуйста, помогите!


person Andreas Ra    schedule 29.03.2019    source источник


Ответы (2)


В этом смысле это «скаляр», потому что это всего лишь одна координата (которую математически мы могли бы не рассматривать как скаляр, но поскольку SkyCoord может содержать массив координат, это скаляр SkyCoord). Я действительно думаю, что немного странно, что функция search_around_sky не может принять скалярную координату, потому что в принципе она может обнаружить этот случай (на самом деле она уже делает это и вызывает конкретное исключение, которое вы получаете), но вместо того, чтобы вызвать исключение, она может попытаться чтобы «продвинуть» ваш аргумент в однокоординатный массив. Но я также частично понимаю аргументацию.

Согласно этим документам, идея состоит в том, что вы должны иметь возможность вызвать catalog.search_around_sky(some_coords, ...) и получить пару массивов индексов как в some_coords, так и в catalog, где совпадающие координаты находятся в каждом из соответствующих массивов координат. Более того, каждый из этих массивов индексов должен быть одинакового размера и формы, поскольку совпадения должны быть найдены в каждом из массивов координат.

Поэтому, если вы вводите «координаты» — это просто одна координата, а не массив, логика этой функции не имеет никакого смысла. Это также указано в документах:

Однако обратите внимание, что эта двойная индексация означает, что search_around_* не работает, если одна из координат является скаляром, потому что возвращаемый индекс не имеет смысла для скаляра:

>>> scalarc = SkyCoord(1*u.deg, 2*u.deg)  
>>> idxscalarc, idxcatalog, d2d, d3d = catalog.search_around_sky(scalarc, 1*u.deg)  
# THIS DOESN'T ACTUALLY WORK  
>>> scalarc[idxscalarc]  
IndexError: 0-d arrays can't be indexed

В результате (и в любом случае, поскольку алгоритм search_around_* неэффективен в скалярном случае) лучший подход для этого сценария — вместо этого использовать методы separation*:

 >>> d2d = scalarc.separation(catalog)  
 >>> catalogmsk = d2d < 1*u.deg  
 >>> d3d = scalarc.separation_3d(catalog)  
 >>> catalog3dmsk = d3d < 1*u.kpc  

В этом примере d2d представляет собой массив двумерных расстояний между scalarc и координатами в catalog. Тогда catalogmsk — это логическая маска тех элементов в catalog, где расстояние было меньше 1 градуса. Затем вы можете использовать эту маску для извлечения этих элементов именно из catalog, например catalog[catalogmsk]. Или вы можете полностью пропустить назначение маски промежуточной переменной и просто сделать, например, catalog[d2d < 1*u.deg].

Если вы посмотрите на реализация search_around_sky вы можете видеть, что он использует SkyCoord.separation внутри, но все еще немного сложнее, потому что он должен использовать методы поиска, чтобы эффективно находить совпадающие пары координат.

Если у вас есть только одна координата, которую вы хотите найти в пределах некоторого расстояния от координат в каталоге, гораздо проще и понятнее использовать метод SkyCoord.separation напрямую, как описано выше.

person Iguananaut    schedule 01.04.2019
comment
Спасибо за ваш ответ. Я буду использовать это. На самом деле, я хочу получить все истинные источники из полного каталога, которые включены в маленькое изображение. Тем не менее, Search_around_работает правильно с добавлением [ ]. Однако, когда я выбрал в качестве предела разделения расстояние (в угловых минутах) между центром изображения и одним из углов, он возвращал больше источников за пределами моего участка неба. - person Andreas Ra; 02.04.2019
comment
на самом деле SkyCoord.seperation возвращает то же самое, что и search_around_sky с добавлением [ ]. А также возвращает те же источники за пределами моего изображения fits, если бы я мог догадаться, используя информацию wcs - person Andreas Ra; 02.04.2019
comment
Да, следует ожидать, что он вернет то же самое. - person Iguananaut; 03.04.2019

Проблема была с c=SkyCoord(ra=x*u.deg,dec=y*u.deg, frame=FK5). Который считался (не знаю почему) скалярным.

search_around_sky принимает координаты массива.

Так что он отлично работает, когда вместо c=SkyCoord(ra=x*u.deg,dec=y*u.deg, frame=FK5)
я использовал: c=SkyCoord(ra=[x]*u.deg,dec=[y]*u.deg, frame=FK5)

person Andreas Ra    schedule 01.04.2019