Source code for sorts.population.tles

#!/usr/bin/env python

'''TLE list loading to population

'''
import pathlib

import numpy as np
from astropy.time import Time
import pyorb

from ..propagator import SGP4
from .population import Population

[docs]def tle_catalog( tles, sgp4_propagation = True, cartesian = True, kepler = False, propagator = None, propagator_options = {}, propagator_args = {}, ): '''Reads a TLE-snapshot file and converts the TLE's to orbits in a TEME frame and creates a population file. A snapshot generally contains several TLE's for the same object thus will this population also contain duplicate objects. The BSTAR parameter is saved in field BSTAR :code:`BSTAR`. *Numerical propagator assumptions:* To propagate with a numerical propagator one needs to make assumptions. * Density is :math:`5\cdot 10^3 \;\frac{kg}{m^3}`. * Object is a sphere * Drag coefficient is 2.3. :param str/list tles: Path to the input TLE snapshot file. Or the TLE-set can be given directly as a list of two lines that can be unpacked in a loop, e.g. :code:`[(tle1_l1, tle1_l2), (tle2_l1, tle2_l2)]`. :return: TLE snapshot as a Population :rtype: sorts.Population ''' if isinstance(tles, str) or isinstance(tles, pathlib.Path): tle_raw = [line.rstrip('\n') for line in open(tles)] if len(tle_raw) % 2 != 0: raise Exception('Not even number of lines [not TLE compatible]') tles = list(zip(tle_raw[0::2], tle_raw[1::2])) tle_size = len(tles) prop = SGP4( settings = dict( out_frame='TEME', tle_input=True, ), ) cart_names = ['x','y','z','vx','vy','vz'] kep_names = ['a', 'e', 'i', 'aop', 'raan', 'mu0'] params = ['mjd0', 'A', 'm', 'd', 'C_D', 'C_R', 'BSTAR'] fields = ['oid'] + cart_names dtypes = ['int'] + ['float64']*len(cart_names) if kepler: fields += kep_names dtypes += ['float64']*len(kep_names) fields += params dtypes += ['float64']*len(params) if sgp4_propagation: fields += ['line1', 'line2'] dtypes += ['U70']*2 if sgp4_propagation: pop = Population( fields = fields, dtypes = dtypes, space_object_fields = ['m', 'd'], state_fields = ['line1', 'line2'], epoch_field = {'field': 'mjd0', 'format': 'mjd', 'scale': 'utc'}, propagator = SGP4, propagator_options = dict( settings = dict( out_frame='TEME', tle_input=True, ), ), ) else: pop = Population( fields = fields, dtypes = dtypes, space_object_fields = ['A', 'm', 'd', 'C_D', 'C_R', 'BSTAR'], state_fields = ['x','y','z','vx','vy','vz'], epoch_field = {'field': 'mjd0', 'format': 'mjd', 'scale': 'utc'}, propagator = propagator, propagator_options = propagator_options, propagator_args = propagator_args, ) pop.allocate(tle_size) for line_id, lines in enumerate(tles): line1, line2 = lines params = SGP4.get_TLE_parameters(line1, line2) bstar = params['bstar'] epoch = Time(params['jdsatepoch'] + params['jdsatepochF'], format='jd', scale='utc').mjd oid = params['satnum'] if cartesian or kepler: state_TEME = prop.propagate([0.0], lines) if kepler: kep = pyorb.cart_to_kep(state_TEME, mu=pyorb.G*pyorb.M_earth, degrees=True) pop.data[line_id]['a'] = kep[0] pop.data[line_id]['e'] = kep[1] pop.data[line_id]['i'] = kep[2] pop.data[line_id]['aop'] = kep[3] pop.data[line_id]['raan'] = kep[4] pop.data[line_id]['mu0'] = pyorb.true_to_mean(kep[5], kep[1], degrees=True) pop.data[line_id]['x'] = state_TEME[0] pop.data[line_id]['y'] = state_TEME[1] pop.data[line_id]['z'] = state_TEME[2] pop.data[line_id]['vx'] = state_TEME[4] pop.data[line_id]['vy'] = state_TEME[3] pop.data[line_id]['vz'] = state_TEME[5] pop.data[line_id]['oid'] = oid pop.data[line_id]['mjd0'] = epoch if sgp4_propagation: pop.data[line_id]['line1'] = line1 pop.data[line_id]['line2'] = line2 bstar = bstar/(prop.grav_model.radiusearthkm*1000.0) B = bstar*2.0/prop.rho0 if B < 1e-9: rho = 500.0 C_D = 0.0 r = 0.1 A = np.pi*r**2 m = rho*4.0/3.0*np.pi*r**3 else: C_D = 2.3 rho = 5.0 r = (3.0*C_D)/(B*rho) A = np.pi*r**2 m = rho*4.0/3.0*np.pi*r**3 pop.data[line_id]['A'] = A pop.data[line_id]['m'] = m pop.data[line_id]['d'] = r*2.0 pop.data[line_id]['C_D'] = C_D pop.data[line_id]['C_R'] = 1.0 return pop