Эффективный способ распространения спутникового каталога во времени

Постановка задачи

Мне нужно распространять весь каталог последних TLE (нужна бесплатная учетная запись для просмотра) с space-track.org, используя skyfield или похожие. Обычно в списке 15–16 тыс. TLE. У меня это работает, но это очень медленно. На порядок часов используется 46 ядер на сервере.

Не замужем за skyfield, Если astropy или же pyephem или что-то еще быстрее, я бы с радостью принял ответ, который показывает, что я пытаюсь сделать, используя это.

Минимальный пример

Для моего приложения я загружаю TLE в фрейм данных Pandas и выполняю там анализ, поэтому я буду держать свой пример в мире Pandas. Ниже приведен минимальный пример.

Предполагая, что каталог спутников был сохранен как catalog.txt, настройте среду, затем прочитайте TLE, сгенерируйте sf.sgp4lib.EarthSatellite объекты, и загрузите все в фрейм данных Pandas. Мы также смещаем позиции к некоторому месту наблюдения. Я оставляю выбор места наблюдения за читателем (0, 0, 0 было бы хорошо):

import skyfield as sf
import pandas as pd
from skyfield.api import load, Topos
from datetime import datetime, timezone, timedelta

with open('catalog.txt', 'r') as f:
    tle_list = [line.strip() for line in f.read().split('\n')
                if line is not '']
data = []
for i in range(0, len(tle), 2):  # every two lines
    temp = {}
    temp['tle1'] = tle_list[i]
    temp['tle2'] = tle_list[i+1]
    temp['earthsat'] = sf.sgp4lib.EarthSatellite(tle_list[i],
                                                 tle_list[i+1])
    data.append(temp)
df = pd.DataFrame(data=data)
site = Topos(latitude_degrees=site_lat,
             longitude_degrees=site_lon,
             elevation_m=site_alt)
df['earthsat'] = df.earthsat - site  # offset to site location

2,1 с ± 20 мс на цикл (среднее ± стандартное отклонение из 7 циклов, по 1 циклу каждый)

Создайте массив объектов datetime с учетом часового пояса, по которым будут распространяться все спутники. Здесь я выбрал каждые 10 минут с 4 часов до полуночи в день, когда я пишу это, до 4 часов после.

ts = load.timescale()
tz = timezone(timedelta(hours=-4))  # Eastern or whatever timezone
midnight = datetime(2018, 4, 4, 0, 0, 0, tzinfo=tz)  # midnight today
start = midnight - timedelta(hours=4)
end = midnight + timedelta(hours=4)
delta_time = timedelta(minutes=10)
# This is ugly, but I had issues using linspace or arange...
times = [start]
now = start
while now <= end:
    now += delta_time
    times.append(now)

189 мс ± 36,9 мс на цикл (среднее ± стандартное отклонение из 7 циклов, по 10 циклов в каждом)

Наконец, рассчитайте астрометрические положения для каждого временного шага для каждого спутника. Это то, что нужно навсегда. Слишком долго, чтобы я мог запустить снова, чтобы получить время, но это порядка нескольких часов при использовании 46 ядер на сервере.

df['astrometric'] = df.earthsat.apply(lambda x: [x.at(ts.utc(time)) for time in times])

Дополнительные детали

Я нашел это обсуждение массивов дат в документации, которая предлагает передать весь массив сразу: x.at(ts.utc(times)), Пока это занимает меньше ядер и работает немного быстрее, но все равно занимает слишком много времени.

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

В случае, если окончательный вариант использования поддается определенному ускорению, мне, в конечном счете, необходимо получить углы наблюдения от объекта из этих объектов, поэтому [x.altaz() for x in row.astrometrics] Тип вещи.

Мысли о решении

Сейчас я думаю, что я вычисляю положение места наблюдения на каждом временном шаге в течение ночи для каждого спутника в каталоге. Я могу ошибаться, но если я прав, то думаю, что я бы увидел довольно приличное ускорение (может быть, недостаточно), рассчитав это один раз, а затем просмотрев его для каждого нового спутника. Кто-нибудь знает, как это сделать?

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

Спасибо.

0 ответов

Мой лучший совет - использовать НАСА SPICE Toolkit для этого вида работ. Это позволяет вам загружать двухстрочные элементы, а затем использовать ядра NAIF/SPICE НАСА для выполнения остальной части работы (вы можете также найти некоторые спутники в других форматах, но TLE в порядке).

Если бы вы работали в C, вы бы использовали метод getelm_c, чтобы прочитать их, и spkpos_c, чтобы получить позицию. К счастью, есть оболочка для Python, которая называется spiceypy!

getelm_c метод обернут в spiceypy.spiceypy.getelm(frstyr, lineln, lines) загрузить в свой TLE. Вы бы их хотели использовать spiceypy.spiceypy.spkpos(targ, et, ref, abcorr, obs) чтобы получить вашу позицию относительно контрольного тела.

Я предлагаю использовать документы из spiceypy, в частности, положение примера Cassini, чтобы убедиться, что у вас есть все правильные файлы на месте, если вы решите использовать ядра SPICE НАСА: https://spiceypy.readthedocs.io/en/master/exampleone.html

Другие вопросы по тегам