Ejemplo n.º 1
0
    def test_true2mean(self):
        nu = n.linspace(0, 1.5 * n.pi, num=100, dtype=n.float)
        M = dpt.true2mean(nu, 0.0)
        nt.assert_array_almost_equal(nu, M, decimal=7)

        e = n.linspace(0, 0.9, num=100, dtype=n.float)
        M = dpt.true2mean(n.pi, e)
        M0 = n.ones(e.shape, dtype=n.float) * n.pi
        nt.assert_array_almost_equal(M0, M, decimal=7)
Ejemplo n.º 2
0
    def get_orbit_cart(self, t, x, y, z, vx, vy, vz, mjd0, **kwargs):
        '''
        **Implementation:**
    
        All state-vector units are in meters.

        Keyword arguments contain only mass :code:`m` in kg and is not required.

        They also contain a option to give angles in radians or degrees. By default input is assumed to be degrees.

        **Frame:**

        The input frame is always the same as the output frame.
    
        :param float m: Mass of the object in kg.
        :param bool radians: If true, all angles are assumed to be in radians.
        '''

        radians = kwargs.setdefault('radians', False)
        m = kwargs.setdefault('m', 0.0)

        cart0 = np.array([x, y, z, vx, vy, vz], dtype=np.float64)
        orb0 = dpt.cart2kep(cart0, m=m, M_cent=M_earth, radians=radians)
        a = orb0[0]
        e = orb0[1]
        inc = orb0[2]
        aop = orb0[3]
        raan = orb0[4]
        mu0 = dpt.true2mean(orb0[5], orb0[1], radians=radians)

        return self.get_orbit(t, a, e, inc, raan, aop, mu0, mjd0, **kwargs)
Ejemplo n.º 3
0
    def test_orbit_inverse_error_kep(self):
        mjd0 = dpt.jd_to_mjd(2457126.2729)

        orb_init_list = self._gen_orbits(1000)

        prop = PropagatorKepler(
                in_frame='EME',
                out_frame='EME',
        )

        t = n.array([0.0])
        
        for kep in orb_init_list:
            state_ref = dpt.kep2cart(kep, m=self.init_data['m'], M_cent=M_earth, radians=False)

            state = prop.get_orbit(
                t=t, mjd0=mjd0,
                a=kep[0], e=kep[1], inc=kep[2],
                raan=kep[4], aop=kep[3], mu0=dpt.true2mean(kep[5], kep[1], radians=False),
                m=self.init_data['m'],
                radians=False,
            )

            state_diff1 = n.abs(state_ref - state[:,0])

            nt.assert_array_less(state_diff1[:3], n.full((3,), 1e-5, dtype=state_diff1.dtype))
            nt.assert_array_less(state_diff1[3:], n.full((3,), 1e-7, dtype=state_diff1.dtype))
Ejemplo n.º 4
0
    def get_orbit_cart(self, t, x, y, z, vx, vy, vz, mjd0, **kwargs):
        '''
        **Implementation:**

        Converts Cartesian vector to Kepler elements and calls :func:`propagator_orekit.PropagatorOrekit.get_orbit`.

        All units are in m and m/s.

        **Uses:**
            * :func:`dpt_tools.cart2kep`
            * :func:`dpt_tools.true2mean`

        See :func:`propagator_base.PropagatorBase.get_orbit_cart`.
        '''
        cart = np.array([x, y, z, vx, vy, vz], dtype=np.float)
        orb = dpt.cart2kep(
            cart,
            m=kwargs['m'],
            M_cent=self.M_earth,
            radians=False,
        )

        a = orb[0]
        e = orb[1]
        inc = orb[2]
        aop = orb[3]
        raan = orb[4]
        mu0 = dpt.true2mean(orb[5], e, radians=False)

        return self.get_orbit(t, a, e, inc, raan, aop, mu0, mjd0, **kwargs)
Ejemplo n.º 5
0
    def test_orbit_kep_cart_correspondance(self):
        mjd0 = dpt.jd_to_mjd(2457126.2729)

        orb_init_list = self._gen_orbits(100)

        prop = PropagatorKepler(
                in_frame='EME',
                out_frame='EME',
        )

        t = n.linspace(0, 12*3600, num=100, dtype=n.float)
        
        for kep in orb_init_list:
            state_ref = dpt.kep2cart(kep, m=self.init_data['m'], M_cent=M_earth, radians=False)

            state_kep = prop.get_orbit(
                t=t, mjd0=mjd0,
                a=kep[0], e=kep[1], inc=kep[2],
                raan=kep[4], aop=kep[3], mu0=dpt.true2mean(kep[5], kep[1], radians=False),
                m=self.init_data['m'], 
                radians=False,
            )
            state_cart = prop.get_orbit_cart(
                t=t, mjd0=mjd0,
                x=state_ref[0], y=state_ref[1], z=state_ref[2],
                vx=state_ref[3], vy=state_ref[4], vz=state_ref[5],
                m=self.init_data['m'],
            )

            state_diff1 = n.abs(state_kep - state_cart)

            nt.assert_array_less(state_diff1[:3,:], n.full((3,t.size), 1e-5, dtype=state_diff1.dtype))
            nt.assert_array_less(state_diff1[3:,:], n.full((3,t.size), 1e-7, dtype=state_diff1.dtype))
Ejemplo n.º 6
0
    def test_mean_true_inverse_array(self):
        M = n.linspace(0.0, 1.5 * n.pi, num=100, dtype=n.float)
        e = n.linspace(0, 0.99, num=100, dtype=n.float)

        Mv, ev = n.meshgrid(M, e)

        nu_test = dpt.mean2true(Mv, ev)
        M_test = dpt.true2mean(nu_test, ev)
        nt.assert_array_almost_equal(M_test, Mv, decimal=7)
Ejemplo n.º 7
0
    def test_mean_true_inverse_float(self):
        M = n.linspace(0.0, 1.5 * n.pi, num=100, dtype=n.float)
        e = n.linspace(0, 0.99, num=100, dtype=n.float)

        for eit in e:
            for Mit in M:
                nu_test = dpt.mean2true(Mit, eit)
                M_test = dpt.true2mean(nu_test, eit)
                nt.assert_almost_equal(M_test, Mit, decimal=7)
Ejemplo n.º 8
0
def propagate_population(population, mjd):

    obj_gen = population.object_generator()

    new_elements = np.empty((6,len(population)), dtype=np.float64)
    prop_ok = np.full((len(population),), True, dtype=np.bool)

    my_iter = list(range(comm.rank, len(population), comm.size))

    for ind, obj in enumerate(obj_gen):
        if ind in my_iter:
            tt = (mjd - obj.mjd0)*3600.0*24.0
            print('PID{}: propagating obj {} {:.2f} h'.format(comm.rank, ind, tt/3600.0))

            try:
                state = obj.get_state(tt)
            except:
                prop_ok[ind] = False
                continue

            kep = dpt.cart2kep(state, m=obj.m, M_cent=obj.M_cent, radians=False)

            if np.any(np.isnan(kep))\
             or kep[1] > 1.0:
                prop_ok[ind] = False
                continue

            new_elements[0,ind] = kep[0]*1e-3
            new_elements[1,ind] = kep[1]
            new_elements[2,ind] = kep[2]
            new_elements[3,ind] = kep[4]
            new_elements[4,ind] = kep[3]
            new_elements[5,ind] = dpt.true2mean(kep[5], kep[1], radians=False)

    for pid in range(comm.size):
        for ind in range(pid, len(population), comm.size):
            new_elements[:,ind] = comm.bcast(new_elements[:,ind], root=pid)
            prop_ok[ind] = comm.bcast(prop_ok[ind], root=pid)

    population.objs['a'] = new_elements[0,:]
    population.objs['e'] = new_elements[1,:]
    population.objs['i'] = new_elements[2,:]
    population.objs['raan'] = new_elements[3,:]
    population.objs['aop'] = new_elements[4,:]
    population.objs['mu0'] = new_elements[5,:]
    population.objs['mjd0'] = mjd

    population.objs = population.objs[prop_ok]

    return population
Ejemplo n.º 9
0
def _cart2sgp4_elems(cart, radians=True):
    '''Cartesian coordinates to orbital elements. Wrap DPT-function to use mean anomaly, km and reversed order on aoe and raan.
    
    Neglecting mass is sufficient for this calculation (the standard gravitational parameter is 24 orders larger then the change).
    '''
    kep = dpt.cart2kep(cart * 1e3,
                       m=0.0,
                       M_cent=propagator_sgp4.M_earth,
                       radians=radians)
    kep[0] *= 1e-3
    tmp = kep[4]
    kep[4] = kep[3]
    kep[3] = tmp
    kep[5] = dpt.true2mean(kep[5], kep[1], radians=radians)
    return kep
Ejemplo n.º 10
0
def get_orbit(o):
    #print('{:.2f}, {:.2f}, {:.2f}, {:.2f}, {:.2f}, {:.2f}'.format(*o.tolist()))
    ecef = prop.get_orbit(
        t=0.0,
        a=o[0],
        e=o[1],
        inc=o[2],
        raan=o[4],
        aop=o[3],
        mu0=dpt.true2mean(o[5], o[1], radians=False),
        mjd0=dpt.jd_to_mjd(2457126.2729),
        C_D=2.3,
        A=1.0,
        m=1.0,
    )
    return ecef
Ejemplo n.º 11
0
def get_orbit2(o):
    init_data = {
        'a': o[0],
        'e': o[1],
        'inc': o[2],
        'raan': o[4],
        'aop': o[3],
        'mu0': dpt.true2mean(o[5], o[1], radians=False),
        'mjd0': mjd0,
        'C_D': 2.3,
        'C_R': 1,
        'm': 8000,
        'A': 1.0,
    }
    state = prop2.get_orbit(n.array([0.0], dtype=n.float), **init_data)
    return state
Ejemplo n.º 12
0
    def update(self, **kwargs):
        '''Updates the orbital elements and Cartesian state vector of the space object.

        Can update any of the related state parameters, all others will automatically update.

        Cannot update Keplerian and Cartesian elements simultaneously.

        :param float a: Semi-major axis in km
        :param float e: Eccentricity
        :param float i: Inclination in degrees
        :param float aop: Argument of perigee in degrees
        :param float raan: Right ascension of the ascending node in degrees
        :param float mu0: Mean anomaly in degrees
        :param float x: X position in km
        :param float y: Y position in km
        :param float z: Z position in km
        :param float vx: X-direction velocity in km/s
        :param float vy: Y-direction velocity in km/s
        :param float vz: Z-direction velocity in km/s
        '''

        kep = ['a', 'e', 'i', 'raan', 'aop', 'mu0']
        cart = ['x', 'y', 'z', 'vx', 'vy', 'vz']

        kep_orb = False
        cart_orb = False

        for key, val in kwargs.items():
            if key in kep:
                kep_orb = True
                setattr(self, key, val)

            elif key in cart:
                cart_orb = True
                setattr(self, key, val)

            else:
                raise TypeError('{} variable cannot be updated'.format(key))

        if kep_orb and cart_orb:
            raise TypeError(
                'Cannot update both Cartesian and Kepler elements at the same time'
            )

        if kep_orb:
            orb = n.array([
                self.a * 1e3, self.e, self.i, self.aop, self.raan,
                dpt.mean2true(self.mu0, self.e, radians=False)
            ],
                          dtype=n.float)
            state_c = dpt.kep2cart(
                orb, m=n.array([self.m
                                ]), M_cent=self.M_cent, radians=False) * 1e-3

        if cart_orb:
            state = n.array(
                [self.x, self.y, self.z, self.vx, self.vy, self.vz],
                dtype=n.float) * 1e3
            self.state_cart = state
            orb_c = dpt.cart2kep(state,
                                 m=self.m,
                                 M_cent=self.M_cent,
                                 radians=False)

        if kep_orb:
            self.x = state_c[0]
            self.y = state_c[1]
            self.z = state_c[2]
            self.vx = state_c[3]
            self.vy = state_c[4]
            self.vz = state_c[5]
            self.state_cart = state_c * 1e3

        if cart_orb:
            self.a = orb_c[0] * 1e-3
            self.e = orb_c[1]
            self.i = orb_c[2]
            self.raan = orb_c[4]
            self.aop = orb_c[3]
            self.mu0 = dpt.true2mean(orb_c[5], orb_c[1], radians=False)
Ejemplo n.º 13
0
    def cartesian(so_class,
                  x,
                  y,
                  z,
                  vx,
                  vy,
                  vz,
                  d=0.01,
                  C_D=2.3,
                  A=1.0,
                  m=1.0,
                  mjd0=57125.7729,
                  oid=42,
                  M_cent=M_e,
                  C_R=1.0,
                  propagator=default_propagator,
                  propagator_options={},
                  **kwargs):
        '''Creates a space object using Cartesian elements.

            :param float x: X position in km
            :param float y: Y position in km
            :param float z: Z position in km
            :param float vx: X-direction velocity in km/s
            :param float vy: Y-direction velocity in km/s
            :param float vz: Z-direction velocity in km/s
            :param float C_D: Drag coefficient
            :param float C_R: Radiation pressure coefficient
            :param float A: Area
            :param float m: Mass in kg
            :param float mjd0: Epoch for state
            :param int oid: Identifying object ID
            :param float d: Diameter in meters
            :param float M_cent: Mass of central body
            :param PropagatorBase propagator: Propagator class pointer
            :param dict propagator_options: Propagator initialization keyword arguments
            :param dict kwargs: All additional keyword arguments will be passed to the propagator call.
        '''

        state = n.array([x, y, z, vx, vy, vz], dtype=n.float) * 1e3
        eart_rot_inv = dpt.rot_mat_z(-dpt.gmst(mjd0))
        #state[3:] = eart_rot_inv.dot(state[3:])
        #state[:3] = eart_rot_inv.dot(state[:3])
        orb_c = dpt.cart2kep(state, m=m, M_cent=M_cent, radians=False)

        a = orb_c[0] * 1e-3
        e = orb_c[1]
        i = orb_c[2]
        raan = orb_c[4]
        aop = orb_c[3]
        mu0 = dpt.true2mean(orb_c[5], orb_c[1], radians=False)

        return so_class(a=a,
                        e=e,
                        i=i,
                        raan=raan,
                        aop=aop,
                        mu0=mu0,
                        d=d,
                        C_D=C_D,
                        A=A,
                        m=m,
                        mjd0=mjd0,
                        oid=oid,
                        M_cent=M_cent,
                        C_R=C_R,
                        propagator=propagator,
                        propagator_options=propagator_options,
                        **kwargs)
Ejemplo n.º 14
0
import numpy as n
import space_object as so
import plothelp
import sys
import matplotlib.pyplot as plt
from scipy.constants import au
import dpt_tools as dpt

o = n.array([25000e3, 0.7, 72.0, 45.0, 45.0, 25.0], dtype=n.float)
o.shape = (6, 1)
obj = so.space_object(a=o[0] * 1e-3,
                      e=o[1],
                      i=o[2],
                      raan=o[4],
                      aop=o[3],
                      mu0=dpt.true2mean(o[5], o[1], radians=False),
                      C_D=2.3,
                      A=1.0,
                      m=1.0,
                      diam=0.1)

#ecef needs earth rotation as a function of time
from keplerian_sgp4 import gmst
theta = gmst(obj.mjd0)
eart_rot = dpt.rot_mat_z(-theta)

x = obj.get_state(0.0)

M_e = 5.972e24

x_dpt = dpt.kep2cart(o, m=n.array([1.0]), M_cent=M_e, radians=False)
Ejemplo n.º 15
0
    def test_PropagatorSGP4_cart_kep_cases(self):

        R_E = 6353.0e3
        mjd0 = dpt.jd_to_mjd(2457126.2729)
        a = R_E*2.0
        orb_init_list = []

        orb_range = np.array([a, 0.9, 180, 360, 360, 360], dtype=np.float)
        orb_offset = np.array([R_E*1.1, 0, 0.0, 0.0, 0.0, 0.0], dtype=np.float)
        test_n = 100
        while len(orb_init_list) < test_n:
            orb = np.random.rand(6)
            orb = orb_offset + orb*orb_range
            if orb[0]*(1.0 - orb[1]) > R_E+200e3:
                orb_init_list.append(orb)

        orb_init_list.append(np.array([R_E*1.2, 0, 0.0, 0.0, 0.0, 0.0], dtype=np.float))
        orb_init_list.append(np.array([R_E*1.2, 0, 0.0, 0.0, 0.0, 270], dtype=np.float))
        orb_init_list.append(np.array([R_E*1.2, 1e-9, 0.0, 0.0, 0.0, 0.0], dtype=np.float))
        orb_init_list.append(np.array([R_E*1.2, 0.1, 0.0, 0.0, 0.0, 0.0], dtype=np.float))
        orb_init_list.append(np.array([R_E*1.2, 0.1, 75.0, 0.0, 0.0, 0.0], dtype=np.float))
        orb_init_list.append(np.array([R_E*1.2, 0.1, 0.0, 120.0, 0.0, 0.0], dtype=np.float))
        orb_init_list.append(np.array([R_E*1.2, 0.1, 0.0, 0.0, 35.0, 0.0], dtype=np.float))
        orb_init_list.append(np.array([R_E*1.2, 0.1, 75.0, 120.0, 0.0, 0.0], dtype=np.float))
        orb_init_list.append(np.array([R_E*1.2, 0.1, 75.0, 0.0, 35.0, 0.0], dtype=np.float))
        orb_init_list.append(np.array([R_E*1.2, 0.1, 75.0, 120.0, 35.0, 0.0], dtype=np.float))

        prop = propagator_sgp4.PropagatorSGP4(polar_motion=False)

        t = np.linspace(0, 12*3600, num=100, dtype=np.float)
        M_earth = propagator_sgp4.SGP4.GM*1e9/consts.G
        
        for kep in orb_init_list:
            state_TEME = dpt.kep2cart(kep, m=self.m, M_cent=M_earth, radians=False)

            ecefs_kep = prop.get_orbit(
                t=t, mjd0=mjd0,
                a=kep[0], e=kep[1], inc=kep[2],
                raan=kep[4], aop=kep[3], mu0=dpt.true2mean(kep[5], kep[1], radians=False),
                C_D=self.C_D, m=self.m, A=self.A,
                radians=False,
            )
            ecefs_cart = prop.get_orbit_cart(
                t=t, mjd0=mjd0,
                x=state_TEME[0], y=state_TEME[1], z=state_TEME[2],
                vx=state_TEME[3], vy=state_TEME[4], vz=state_TEME[5],
                C_D=self.C_D, m=self.m, A=self.A,
            )

            p = ecefs_kep[:3,:]*1e-3
            v = ecefs_kep[3:,:]*1e-3
            kep_TEME = propagator_sgp4.ecef2teme(t, p, v, mjd0=mjd0)*1e3

            p = ecefs_kep[:3,:]*1e-3
            v = ecefs_kep[3:,:]*1e-3
            cart_TEME = propagator_sgp4.ecef2teme(t, p, v, mjd0=mjd0)*1e3

            state_diff1 = np.abs(kep_TEME - cart_TEME)

            nt.assert_array_less(state_diff1[:3,:], np.full((3,t.size), 1e-5, dtype=state_diff1.dtype))
            nt.assert_array_less(state_diff1[3:,:], np.full((3,t.size), 1e-7, dtype=state_diff1.dtype))
Ejemplo n.º 16
0
def tryTest1():
    init_data = {
        'a': 7500e3,
        'e': 0,
        'inc': 90.0,
        'raan': 10,
        'aop': 10,
        'mu0': 40.0,
        'mjd0': 57125.7729,
        'C_D': 2.3,
        'C_R': 1.0,
        'm': 8000,
        'A': 1.0,
    }

    mjd0 = dpt.jd_to_mjd(2457126.2729)

    orb_init_list = _gen_orbits(100)

    prop = PropagatorOrekit(
        in_frame='EME',
        out_frame='EME',
    )

    t = np.linspace(0, 12 * 3600, num=100, dtype=np.float)

    for kep in orb_init_list:
        state_ref = dpt.kep2cart(kep,
                                 m=init_data['m'],
                                 M_cent=prop.M_earth,
                                 radians=False)

        state_kep = prop.get_orbit(
            t=t,
            mjd0=mjd0,
            a=kep[0],
            e=kep[1],
            inc=kep[2],
            raan=kep[4],
            aop=kep[3],
            mu0=dpt.true2mean(kep[5], kep[1], radians=False),
            C_D=init_data['C_D'],
            m=init_data['m'],
            A=init_data['A'],
            C_R=init_data['C_R'],
            radians=False,
        )
        state_cart = prop.get_orbit_cart(
            t=t,
            mjd0=mjd0,
            x=state_ref[0],
            y=state_ref[1],
            z=state_ref[2],
            vx=state_ref[3],
            vy=state_ref[4],
            vz=state_ref[5],
            C_D=init_data['C_D'],
            m=init_data['m'],
            A=init_data['A'],
            C_R=init_data['C_R'],
        )

        state_diff1 = np.abs(state_kep - state_cart)

        try:
            nt.assert_array_less(
                state_diff1[:3, :],
                np.full((3, t.size), 1e-5, dtype=state_diff1.dtype))
            nt.assert_array_less(
                state_diff1[3:, :],
                np.full((3, t.size), 1e-7, dtype=state_diff1.dtype))

        except:

            fig = plt.figure(figsize=(15, 15))
            ax = fig.add_subplot(211)
            ax.plot(t / 3600.0,
                    np.sqrt(np.sum(state_diff1[:3, :], axis=0)) * 1e-3)
            ax.set_xlabel('Time [h]')
            ax.set_ylabel('Position difference [km]')
            ax.set_title(
                'Propagation difference diameter simple vs advanced models')
            ax = fig.add_subplot(212)
            ax.plot(t / 3600.0,
                    np.sqrt(np.sum(state_diff1[3:, :], axis=0)) * 1e-3)
            ax.set_xlabel('Time [h]')

            fig = plt.figure(figsize=(15, 15))
            ax = fig.add_subplot(111, projection='3d')
            plothelp.draw_earth_grid(ax)
            ax.plot(state_kep[0, :],
                    state_kep[1, :],
                    state_kep[2, :],
                    "-",
                    alpha=0.5,
                    color="green",
                    label='KEP input')
            ax.plot(state_cart[0, :],
                    state_cart[1, :],
                    state_cart[2, :],
                    "-",
                    alpha=0.5,
                    color="red",
                    label='CART input')
            plt.legend()

            plt.show()
Ejemplo n.º 17
0
#prop2 = orekit_p(in_frame='TEME', out_frame=outf, earth_gravity='Newtonian', radiation_pressure=False, solarsystem_perturbers=[])
#model = 'simple'

prop = sgp_p(out_frame=outf)

mjd0 = dpt.jd_to_mjd(2457126.2729)

o = n.array([7500e3, 0.05, 45, 90, 90, 123], dtype=n.float)
init_data = {
    'a': o[0],
    'e': o[1],
    'inc': o[2],
    'raan': o[4],
    'aop': o[3],
    'mu0': dpt.true2mean(o[5], o[1], radians=False),
    'mjd0': mjd0,
    'C_D': 2.3,
    'C_R': 1,
    'm': 8000,
    'A': 1.0,
}
t = n.linspace(0, 5 * 3600, num=300, dtype=n.float)
state = prop.get_orbit(t, **init_data)
state2 = prop2.get_orbit(t, **init_data)

dstate = state - state2

fig = plt.figure(figsize=(15, 15))
ax = fig.add_subplot(211)
ax.plot(t / 3600.0, n.sqrt(n.sum(dstate[:3, :]**2, axis=0)) * 1e-3)
Ejemplo n.º 18
0
def Microsat_R_debris(mjd, num, radii_range, mass_range, propagator, propagator_options):

    tle_raw = Microsat_R_debris_raw_tle

    tle_raw = [line.strip() for line in tle_raw.split('\n')]
    if len(tle_raw) % 2 != 0:
        raise Exception('Not even number of lines [not TLE compatible]')
    TLEs = zip(tle_raw[0::2], tle_raw[1::2])

    M_earth = propagator_sgp4.SGP4.GM*1e9/consts.G

    pop = Population(
        name='Microsat R debris',
        extra_columns = ['A', 'm', 'd', 'C_D', 'C_R'],
        space_object_uses = [True, True, True, True, True],
        propagator = propagator,
        propagator_options = propagator_options,
    )

    pop.allocate(len(TLEs)*num)

    delete_inds = []
    cnt = 0
    for ind in range(num):
        for line_id, lines in enumerate(TLEs):
            line1, line2 = lines

            sat_id = tle.tle_id(line1)
            jd0 = tle.tle_jd(line1)
            mjd0 = dpt.jd_to_mjd(jd0)

            state_TEME = tle.TLE_propagation_TEME(line1, line2, dpt.mjd_to_jd(mjd))
            kep = dpt.cart2kep(state_TEME, m=0.0, M_cent=M_earth, radians=False)

            if np.any(np.isnan(kep)):
                delete_inds.append(cnt)
                continue

            pop.objs[cnt][1] = kep[0]*1e-3
            pop.objs[cnt][2] = kep[1]
            pop.objs[cnt][3] = kep[2]
            pop.objs[cnt][4] = kep[4]
            pop.objs[cnt][5] = kep[3]
            pop.objs[cnt][6] = dpt.true2mean(kep[5], kep[1], radians=False)
            
            pop.objs[cnt][0] = float(sat_id)
            pop.objs[cnt][7] = mjd

            rho = 1.1e4
            while rho > 1e4 or rho < 1e2:
                r = np.random.rand(1)*(radii_range[1] - radii_range[0]) + radii_range[0]
                A = np.pi*r**2
                m = np.random.rand(1)*(mass_range[1] - mass_range[0]) + mass_range[0]
                vol = 4.0/3.0*np.pi*r**3
                rho = m/vol

            pop.objs[cnt][8] = A
            pop.objs[cnt][9] = m
            pop.objs[cnt][10] = r*2.0
            pop.objs[cnt][11] = 2.3
            pop.objs[cnt][12] = 1.0

            cnt += 1
        
    pop.delete(delete_inds)

    return pop
Ejemplo n.º 19
0
    def test_PropagatorSGP4_cart_kep_inverse_cases(self):

        R_E = 6353.0e3
        mjd0 = dpt.jd_to_mjd(2457126.2729)
        a = R_E*2.0
        orb_init_list = []

        orb_range = np.array([a, 0.9, 180, 360, 360, 360], dtype=np.float)
        orb_offset = np.array([R_E*1.1, 0, 0.0, 0.0, 0.0, 0.0], dtype=np.float)
        test_n = 5000
        while len(orb_init_list) < test_n:
            orb = np.random.rand(6)
            orb = orb_offset + orb*orb_range
            if orb[0]*(1.0 - orb[1]) > R_E+200e3:
                orb_init_list.append(orb)

        orb_init_list.append(np.array([R_E*1.2, 0, 0.0, 0.0, 0.0, 0.0], dtype=np.float))
        orb_init_list.append(np.array([R_E*1.2, 0, 0.0, 0.0, 0.0, 270], dtype=np.float))
        orb_init_list.append(np.array([R_E*1.2, 1e-9, 0.0, 0.0, 0.0, 0.0], dtype=np.float))
        orb_init_list.append(np.array([R_E*1.2, 0.1, 0.0, 0.0, 0.0, 0.0], dtype=np.float))
        orb_init_list.append(np.array([R_E*1.2, 0.1, 75.0, 0.0, 0.0, 0.0], dtype=np.float))
        orb_init_list.append(np.array([R_E*1.2, 0.1, 0.0, 120.0, 0.0, 0.0], dtype=np.float))
        orb_init_list.append(np.array([R_E*1.2, 0.1, 0.0, 0.0, 35.0, 0.0], dtype=np.float))
        orb_init_list.append(np.array([R_E*1.2, 0.1, 75.0, 120.0, 0.0, 0.0], dtype=np.float))
        orb_init_list.append(np.array([R_E*1.2, 0.1, 75.0, 0.0, 35.0, 0.0], dtype=np.float))
        orb_init_list.append(np.array([R_E*1.2, 0.1, 75.0, 120.0, 35.0, 0.0], dtype=np.float))

        prop = propagator_sgp4.PropagatorSGP4(polar_motion=False)

        t = np.array([0], dtype=np.float)
        M_earth = propagator_sgp4.SGP4.GM*1e9/consts.G

        fail_inds = []
        errs = np.empty((len(orb_init_list),2), dtype=np.float)
        for ind, kep in enumerate(orb_init_list):

            state_TEME = dpt.kep2cart(kep, m=self.m, M_cent=M_earth, radians=False)

            ecefs_kep = self.prop.get_orbit(
                t=t, mjd0=mjd0,
                a=kep[0], e=kep[1], inc=kep[2],
                raan=kep[4], aop=kep[3], mu0=dpt.true2mean(kep[5],kep[1],radians=False),
                C_D=self.C_D, m=self.m, A=self.A,
            )
            p = ecefs_kep[:3]*1e-3
            p.shape=(3,1)
            v = ecefs_kep[3:]*1e-3
            v.shape=(3,1)
            kep_TEME = propagator_sgp4.ecef2teme(np.array([0.0]), p, v, mjd0=mjd0)*1e3
            kep_TEME.shape = (6,)

            ecefs_cart = self.prop.get_orbit_cart(
                t=t, mjd0=mjd0,
                x=kep_TEME[0], y=kep_TEME[1], z=kep_TEME[2], 
                vx=kep_TEME[3], vy=kep_TEME[4], vz=kep_TEME[5], 
                C_D=self.C_D, m=self.m, A=self.A,
            )
            p = ecefs_cart[:3]*1e-3
            p.shape=(3,1)
            v = ecefs_cart[3:]*1e-3
            v.shape=(3,1)
            cart_TEME = propagator_sgp4.ecef2teme(np.array([0.0]), p, v, mjd0=mjd0)*1e3
            cart_TEME.shape = (6,)

            state_diff1 = np.abs(kep_TEME - state_TEME)
            try:
                nt.assert_array_less(state_diff1[:3], np.full((3,), 1e-2, dtype=state_diff1.dtype))
                nt.assert_array_less(state_diff1[3:], np.full((3,), 1e-5, dtype=state_diff1.dtype))
            except AssertionError as err:
                if ind not in fail_inds:
                    fail_inds.append(ind)

            state_diff2 = np.abs(cart_TEME - state_TEME)

            try:
                nt.assert_array_less(state_diff2[:3], np.full((3,), 1e-2, dtype=state_diff2.dtype))
                nt.assert_array_less(state_diff2[3:], np.full((3,), 1e-5, dtype=state_diff2.dtype))
            except AssertionError as err:
                if ind not in fail_inds:
                    fail_inds.append(ind)

            state_diff = np.abs(cart_TEME - kep_TEME)

            try:
                nt.assert_array_less(state_diff[:3], np.full((3,), 1e-2, dtype=state_diff.dtype))
                nt.assert_array_less(state_diff[3:], np.full((3,), 1e-5, dtype=state_diff.dtype))
            except AssertionError as err:
                if ind not in fail_inds:
                    fail_inds.append(ind)

            er_r = np.linalg.norm(state_diff1[:3])
            er_v = np.linalg.norm(state_diff1[3:])
            errs[ind,0] = er_r
            errs[ind,1] = er_v

        if len(fail_inds) > 0:
            print('FAIL / TOTAL: {} / {}'.format(len(fail_inds), len(orb_init_list)))

        assert np.median(errs[:,0]) < 1e-2
        assert np.median(errs[:,1]) < 1e-4

        assert len(fail_inds) < float(test_n)/100.
Ejemplo n.º 20
0
def NESCv9_mini_moons(albedo, propagate_SNR = None, radar = None, truncate = None):
    from propagator_rebound import PropagatorRebound

    _opts = dict(
        in_frame = 'HeliocentricECLIPJ2000',
        out_frame = 'ITRF',
    )

    #fname = './data/NESCv9reintv1.TCO.withoutH.kep.des'
    fname = './data/NESCv9reintv1.TCO.withH.kep.des'

    data = np.genfromtxt(fname)

    if truncate is not None:
        _trunc = np.full((data.shape[0],), True, dtype=np.bool)
        _trunc[truncate] = False

        data = data[_trunc, :]
        print('Data truncated to: {}'.format(data.shape[0]))

    AU = 149597871.0 #km

    max_check = 365.0*3600.0*24.0

    '''
    1. synthetic orbit designation
    2. orbital element type (KEP for heliocentric Keplerian)
    3. semimajor axis (au)
    4. eccentricity
    5. inclination (deg)
    6. longitude of ascending node (deg)
    7. argument of perihelion (deg)
    8. mean anomaly (deg)
    9. H-magnitude (filler value)
    10. epoch for which the input orbit is valid (modified Julian date)
    11. index (1)
    12. number of parameters (6)
    13. MOID (filler value)
    14. Code with which created (OPENORB)
    '''

    pop = Population(
        name='NESCv9',
        extra_columns = ['d'],
        space_object_uses = [True],
        propagator = PropagatorRebound,
        propagator_options = _opts,
    )

    pop.allocate(data.shape[0])

    pop['oid'] = np.arange(len(pop))
    pop['a'] = data[:,2]*AU
    pop['e'] = data[:,3]
    pop['i'] = data[:,4]
    pop['raan'] = data[:,5]
    pop['aop'] = data[:,6]
    pop['mu0'] = data[:,7]
    pop['mjd0'] = data[:,9]
    pop['d'] = 10.0**(3.1236 - 0.5*np.log10(albedo) - 0.2*data[:,8])

    if propagate_SNR is not None:
        my_iter = list(range(comm.rank, len(pop), comm.size))

        ranges = np.empty((len(pop),), dtype=np.float64)
        for ind, _d in enumerate(pop['d']):
            if ind in my_iter:
                ranges[ind], _snr = _find_range_for_snr(radar, _d, AU*1e3 ,propagate_SNR)
                print('Object {} found range {:.3f} LD @ {:.2f} SNR'.format(ind, ranges[ind]/384400e3, _snr))

        t_at_dist = np.empty((len(pop),), dtype=np.float64)
        
        new_elements = np.empty((6,len(pop)), dtype=np.float64)
        prop_ok = np.full((len(pop),), True, dtype=np.bool)

        obj_gen = pop.object_generator()

        t_v = np.arange(0.0, max_check, 3600.0)
        for ind, obj in enumerate(obj_gen):
            if ind in my_iter:
                print('Checking object {}'.format(ind))
                states = obj.get_orbit(t_v)
                dists = np.linalg.norm(states, axis=0)
                _check = dists < ranges[ind]
                if np.any(_check):
                    t_at_dist[ind] = t_v[np.argmax(_check)]
                    print('|- Passed @ {:.2f} days'.format(t_at_dist[ind]/(24.0*3600.0)))
                else:
                    prop_ok[ind] = False
        
        if 'out_frame' in pop.propagator_options:
            out_f = pop.propagator_options['out_frame']
        else:
            out_f = 'ITRF'
        pop.propagator_options['out_frame'] = _opts['in_frame']

        obj_gen = pop.object_generator()

        for ind, obj in enumerate(obj_gen):
            if ind in my_iter and prop_ok[ind]:
                print('PID{}: propagating obj {} {:.2f} h'.format(comm.rank, ind, t_at_dist[ind]/3600.0))

                try:
                    state = obj.get_state(t_at_dist[ind])
                except:
                    prop_ok[ind] = False
                    continue

                kep = dpt.cart2kep(state, m=obj.m, M_cent=obj.M_cent, radians=False)

                if np.any(np.isnan(kep)):
                    prop_ok[ind] = False
                    continue

                new_elements[0,ind] = kep[0]*1e-3
                new_elements[1,ind] = kep[1]
                new_elements[2,ind] = kep[2]
                new_elements[3,ind] = kep[4]
                new_elements[4,ind] = kep[3]
                new_elements[5,ind] = dpt.true2mean(kep[5], kep[1], radians=False)

        for pid in range(comm.size):
            for ind in range(pid, len(pop), comm.size):
                new_elements[:,ind] = comm.bcast(new_elements[:,ind], root=pid)
                prop_ok[ind] = comm.bcast(prop_ok[ind], root=pid)
                t_at_dist[ind] = comm.bcast(t_at_dist[ind], root=pid)

        pop.objs['a'] = new_elements[0,:]
        pop.objs['e'] = new_elements[1,:]
        pop.objs['i'] = new_elements[2,:]
        pop.objs['raan'] = new_elements[3,:]
        pop.objs['aop'] = new_elements[4,:]
        pop.objs['mu0'] = new_elements[5,:]
        pop.objs['mjd0'] += t_at_dist/(3600.0*24.0)

        pop.objs = pop.objs[prop_ok]

        pop.propagator_options['out_frame'] = out_f


    return pop
Ejemplo n.º 21
0
    def test_PropagatorSGP4_cart_kep_inverse(self):

            prop = propagator_sgp4.PropagatorSGP4(polar_motion=False)

            t = np.array([0], dtype=np.float)

            reci = np.array([
                    -5339.76186573000,
                    5721.43584226500,
                    921.276953805000,
                ], dtype=np.float)

            veci = np.array([
                    -4.88969089550000,
                    -3.83304653050000,
                    3.18013811100000,
                ], dtype=np.float)

            state_TEME = np.concatenate((reci*1e3, veci*1e3), axis=0)

            M_earth = propagator_sgp4.SGP4.GM*1e9/consts.G

            kep = dpt.cart2kep(state_TEME, m=self.m, M_cent=M_earth, radians=False)
            kep[5] = dpt.true2mean(kep[5], kep[1], radians=False)

            ecefs_kep = prop.get_orbit(
                t=t, mjd0=self.mjd0,
                a=kep[0], e=kep[1], inc=kep[2],
                raan=kep[4], aop=kep[3], mu0=kep[5],
                C_D=self.C_D, m=self.m, A=self.A,
            )
            p = ecefs_kep[:3]*1e-3
            p.shape=(3,1)
            v = ecefs_kep[3:]*1e-3
            v.shape=(3,1)
            kep_TEME = propagator_sgp4.ecef2teme(np.array([0.0]), p, v, mjd0=self.mjd0)*1e3
            kep_TEME.shape = (6,)

            state_diff1 = np.abs(kep_TEME - state_TEME)

            nt.assert_array_less(state_diff1[:3], np.full((3,), 1e-2, dtype=state_diff1.dtype))
            nt.assert_array_less(state_diff1[3:], np.full((3,), 1e-5, dtype=state_diff1.dtype))

            ecefs_cart = prop.get_orbit_cart(
                t=t, mjd0=self.mjd0,
                x=-5339.76186573000e3, y=5721.43584226500e3, z=921.276953805000e3, 
                vx=-4.88969089550000e3, vy=-3.83304653050000e3, vz=3.18013811100000e3, 
                C_D=self.C_D, m=self.m, A=self.A,
            )
            p = ecefs_cart[:3]*1e-3
            p.shape=(3,1)
            v = ecefs_cart[3:]*1e-3
            v.shape=(3,1)
            cart_TEME = propagator_sgp4.ecef2teme(np.array([0.0]), p, v, mjd0=self.mjd0)*1e3
            cart_TEME.shape = (6,)

            state_diff2 = np.abs(cart_TEME - state_TEME)

            nt.assert_array_less(state_diff2[:3], np.full((3,), 1e-2, dtype=state_diff2.dtype))
            nt.assert_array_less(state_diff2[3:], np.full((3,), 1e-5, dtype=state_diff2.dtype))

            state_diff = np.abs(cart_TEME - kep_TEME)

            nt.assert_array_less(state_diff[:3], np.full((3,), 1e-2, dtype=state_diff.dtype))
            nt.assert_array_less(state_diff[3:], np.full((3,), 1e-5, dtype=state_diff.dtype))
Ejemplo n.º 22
0
def tle_snapshot(tle_file, sgp4_propagation=True, propagator = default_propagator, propagator_options = {}):
    '''Reads a TLE-snapshot file and converts the TLE's to orbits in a TEME frame and creates a population file. The BSTAR parameter is saved in column BSTAR (or :code:`_objs[:,12`). A snapshot generally contains several TLE's for the same object thus will this population also contain duplicate objects.
    
    *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 tle_file: 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)]`.
    :param bool sgp4_propagation: If :code:`False` then the population is specifically constructed to be propagated with :class:`propagator_orekit.PropagatorOrekit` and assumptions are made on mass, density and shape of objects. Otherwise the :class:`space_object.SpaceObject` is configured to use SGP4 propagation.

    :return: TLE snapshot as a population with numerical propagator
    :rtype: population.Population
    '''
    if isinstance(tle_file, str):
        tle_raw = [line.rstrip('\n') for line in open(tle_file)]
        if len(tle_raw) % 2 != 0:
            raise Exception('Not even number of lines [not TLE compatible]')

        TLEs = zip(tle_raw[0::2], tle_raw[1::2])
        pop_name = tle_file.split('/')[-1]
    else:
        TLEs = tle_file
        pop_name = 'TLE database'

    M_earth = propagator_sgp4.SGP4.GM*1e9/consts.G

    if sgp4_propagation:
        pop = Population(
            name=pop_name,
            extra_columns = ['A', 'm', 'd', 'C_D', 'C_R'] + ['line1', 'line2'],
            dtypes = ['float64']*5 + ['U70', 'U70'],
            space_object_uses = [True, True, True, True, True] + [True, True],
            propagator = propagator_sgp4.PropagatorTLE,
            propagator_options = {
                'out_frame': 'ITRF',
                'polar_motion': False,
            },
        )
    else:
        pop = Population(
            name=pop_name,
            extra_columns = ['A', 'm', 'd', 'C_D', 'C_R'],
            space_object_uses = [True, True, True, True, True],
            propagator = propagator,
            propagator_options = propagator_options,
        )

    pop.allocate(len(TLEs))

    for line_id, lines in enumerate(TLEs):
        line1, line2 = lines

        sat_id = tle.tle_id(line1)
        jd0 = tle.tle_jd(line1)
        mjd0 = dpt.jd_to_mjd(jd0)

        state_TEME, epoch = tle.TLE_to_TEME(line1,line2)
        kep = dpt.cart2kep(state_TEME, m=0.0, M_cent=M_earth, radians=False)
        pop.objs[line_id][1] = kep[0]*1e-3
        pop.objs[line_id][2] = kep[1]
        pop.objs[line_id][3] = kep[2]
        pop.objs[line_id][4] = kep[4]
        pop.objs[line_id][5] = kep[3]
        pop.objs[line_id][6] = dpt.true2mean(kep[5], kep[1], radians=False)
        
        pop.objs[line_id][0] = float(sat_id)
        pop.objs[line_id][7] = mjd0

    if sgp4_propagation:
        for line_id, lines in enumerate(TLEs):
            line1, line2 = lines
            pop.objs[line_id][13] = line1[:-1]
            pop.objs[line_id][14] = line2[:-1]
    
    for line_id, lines in enumerate(TLEs):
        line1, line2 = lines

        bstar = tle.tle_bstar(line1)/(propagator_sgp4.SGP4.R_EARTH*1000.0)
        B = bstar*2.0/propagator_sgp4.SGP4.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.objs[line_id][8] = A
        pop.objs[line_id][9] = m
        pop.objs[line_id][10] = r*2.0
        pop.objs[line_id][11] = C_D
        pop.objs[line_id][12] = 1.0

    return pop
Ejemplo n.º 23
0
def simulate_Microsat_R_debris_v2(num, max_dv, rho_range, mass_range, seed, propagator, propagator_options, mjd):


    mass = 740

    event_date = np.datetime64('2019-03-27T05:40')
    event_mjd = dpt.npdt2mjd(event_date)

    M_earth = propagator_sgp4.SGP4.GM*1e9/consts.G

    pop = Population(
        name='Simulated Microsat-R debris',
        extra_columns = ['A', 'm', 'd', 'C_D', 'C_R', 'dV', 'dx', 'dy', 'dz'],
        space_object_uses = [True, True, True, True, True, False, False, False, False],
        propagator = propagator,
        propagator_options = propagator_options,
    )

    pop.allocate(num)

    state_TEME, sat_id = _get_MicrosatR_state(event_mjd)

    #first has no pert

    states = np.repeat(state_TEME, num, axis=1)

    np.random.seed(seed)
    popts = copy.deepcopy(propagator_options)
    popts['out_frame'] = propagator_options['in_frame']

    prop = propagator(**popts)

    def mrho2d(m,rho):
        V = m/rho
        return 2.0*(V*3.0/(4.0*np.pi))**(1.0/3.0)

    prop_data = {}

    ind = 0
    trys = 0
    while ind < num:
        trys += 1
        print('try number {}'.format(trys))

        prop_data['C_D'] = 2.3
        prop_data['C_R'] = 1.0
        prop_data['mjd0'] = event_mjd

        rho_v = np.random.rand(1)*(rho_range[1] - rho_range[0]) + rho_range[0]
        m_v = np.random.rand(1)*(mass_range[1] - mass_range[0]) + mass_range[0]
        d_v = mrho2d(m_v, rho_v)

        prop_data['m'] = m_v[0]
        prop_data['d'] = d_v[0]
        prop_data['A'] = np.pi*d_v[0]**2/4.0

        pert_state = state_TEME[:,0].copy()

        dv = np.random.rand(1)*max_dv
        ddir = _rand_sph(1).T

        pert_state[3:] += ddir[:,0]*dv

        prop_data['x'], prop_data['y'], prop_data['z'] = pert_state[:3]
        prop_data['vx'], prop_data['vy'], prop_data['vz'] = pert_state[3:]
        prop_data['t'] = (mjd - event_mjd)*3600.0*24.0

        try:
            prop_pert_state = prop.get_orbit_cart(**prop_data)
        except Exception as e:
            #print(e)
            continue

        print('object added - {} of {}'.format(ind, num))
        kep = dpt.cart2kep(prop_pert_state[:,0], m=mass, M_cent=M_earth, radians=False)

        pop.objs[ind][1] = kep[0]*1e-3
        pop.objs[ind][2] = kep[1]
        pop.objs[ind][3] = kep[2]
        pop.objs[ind][4] = kep[4]
        pop.objs[ind][5] = kep[3]
        pop.objs[ind][6] = dpt.true2mean(kep[5], kep[1], radians=False)
                
        pop.objs[ind][0] = float(sat_id) + num
        pop.objs[ind][7] = mjd

        pop.objs[ind]['A'] = prop_data['A']
        pop.objs[ind]['d'] = prop_data['d']
        pop.objs[ind]['m'] = prop_data['m']
        pop.objs[ind]['C_D'] = prop_data['C_D']
        pop.objs[ind]['C_R'] = prop_data['C_R']

        pop.objs[ind]['dV'] = dv
        pop.objs[ind]['dx'] = ddir[0,0]
        pop.objs[ind]['dy'] = ddir[1,0]
        pop.objs[ind]['dz'] = ddir[2,0]

        ind += 1

    return pop
Ejemplo n.º 24
0
def simulate_Microsat_R_debris(num, max_dv, radii_range, mass_range, C_D_range, seed, propagator, propagator_options, mjd):

    tle_raw = '''1 43947U 19006A   19069.62495353  .00222140  22344-4  39735-3 0  9995
    2 43947  96.6263 343.1609 0026772 226.5664 224.4731 16.01032328  7176
    1 43947U 19006A   19069.68634861  .00217235  21442-4  38851-3 0  9995
    2 43947  96.6282 343.2231 0026267 227.5469 217.1086 16.01062873  7183
    1 43947U 19006A   19069.81093322  .00066734  37128-5  12017-3 0  9992
    2 43947  96.6282 343.3467 0026246 227.0726 215.1493 16.01048534  7204
    1 43947U 19006A   19070.54563657  .00111882  69857-5  20248-3 0  9991
    2 43947  96.6271 344.0664 0025783 228.7058 125.4384 16.00925959  7318
    1 43947U 19006A   19070.80923755  .00013653  19858-5  25403-4 0  9991
    2 43947  96.6268 344.3320 0024927 225.1848 207.3499 16.01142181  7364
    1 43947U 19006A   19071.12831853  .00154965  11740-4  27719-3 0  9998
    2 43947  96.6279 344.6467 0025572 226.6832 243.5148 16.01113233  7412
    1 43947U 19006A   19071.80921646  .00118874  76545-5  21379-3 0  9993
    2 43947  96.6279 345.3224 0025491 224.0468 208.0149 16.01043615  7523
    1 43947U 19006A   19072.44153689  .00037015  24665-5  66863-4 0  9999
    2 43947  96.6279 345.9498 0025442 221.6016 252.7257 16.01159223  7620
    1 43947U 19006A   19072.74405995  .00022228  21113-5  40609-4 0  9997
    2 43947  96.6279 346.2500 0025432 220.3955 196.4626 16.01147542  7675
    1 43947U 19006A   19073.12825718  .00008242  19370-5  15873-4 0  9996
    2 43947  96.6304 346.6133 0023002 223.0617 246.6563 16.01114545  7738
    1 43947U 19006A   19073.44154376  .00035052  24102-5  63784-4 0  9998
    2 43947  96.6300 346.9244 0022588 225.2511 249.1037 16.01188227  7782
    1 43947U 19006A   19073.80920446 -.00023017  21041-5 -40417-4 0  9994
    2 43947  96.6337 347.2908 0022039 223.4278 208.5467 16.01076766  7841
    1 43947U 19006A   19074.74408622  .00119327  76982-5  21614-3 0  9994
    2 43947  96.6289 348.2321 0022856 222.6623 194.1149 16.01049775  7992
    1 43947U 19006A   19075.01672454  .00167822  13470-4  30180-3 0  9994
    2 43947  96.6290 348.5015 0022778 221.4659 325.7020 16.01154108  8039
    1 43947U 19006A   19075.54702546  .00026769  22010-5  48973-4 0  9993
    2 43947  96.6290 349.0278 0022754 219.3583 142.5100 16.01177853  8128
    1 43947U 19006A   19075.74902949  .00160298  12418-4  29196-3 0  9995
    2 43947  96.6301 349.2308 0021693 223.2409 221.9908 16.00986874  8150
    1 43947U 19006A   19075.80608134  .00151204  11245-4  27527-3 0  9991
    2 43947  96.6283 349.2862 0021642 222.7701 191.0541 16.01000711  8166
    1 43947U 19006A   19075.80608134  .00152613  11422-4  27780-3 0  9994
    2 43947  96.6283 349.2862 0021642 222.7701 191.0553 16.01002279  8160
    1 43947U 19006A   19076.04950662  .00212767  20643-4  38419-3 0  9990
    2 43947  96.6283 349.5277 0021615 221.8443 154.0766 16.01125308  8205
    1 43947U 19006A   19076.38314227  .00228397  23614-4  40852-3 0  9999
    2 43947  96.6283 349.8588 0021611 220.6464 277.1313 16.01285801  8254
    1 43947U 19006A   19076.56965602  .00375665  62286-4  68387-3 0  9990
    2 43947  96.6317 350.0396 0020897 222.9971 269.0493 16.01007118  8281
    1 43947U 19006A   19076.62489356  .00301460  40170-4  54811-3 0  9991
    2 43947  96.6317 350.0945 0020879 222.7479 227.4454 16.01029701  8290
    1 43947U 19006A   19076.74888822  .00206456  19517-4  37455-3 0  9990
    2 43947  96.6317 350.2206 0020779 222.3519 222.0257 16.01081824  8311
    1 43947U 19006A   19076.80334391  .00189842  16753-4  34417-3 0  9997
    2 43947  96.6317 350.2747 0020760 222.1378 175.8977 16.01098177  8326
    1 43947U 19006A   19077.25548485  .00042586  26475-5  77957-4 0  9991
    2 43947  96.6337 350.7139 0018680 228.2848 254.2224 16.01199217  8396
    1 43947U 19006A   19077.49923692  .00048049  28483-5  87602-4 0  9993
    2 43947  96.6337 350.9559 0018675 227.3154 219.3457 16.01241589  8433
    1 43947U 19006A   19077.73867148  .00176479  14671-4  32436-3 0  9999
    2 43947  96.6324 351.1992 0019599 225.2817 160.3011 16.00913438  8475
    1 43947U 19006A   19078.62402633  .00193781  17362-4  35487-3 0  9996
    2 43947  96.6337 352.0814 0019337 224.7610 220.1468 16.00981700  8611
    1 43947U 19006A   19079.44446882  .00056887  32197-5  10424-3 0  9994
    2 43947  96.6318 352.8859 0017932 222.6020 267.9762 16.01149860  8742
    1 43947U 19006A   19079.56114259  .00331197  48376-4  60603-3 0  9996
    2 43947  96.6357 353.0133 0018767 223.2624 219.3325 16.01004143  8769
    1 43947U 19006A   19079.87121502  .00017670  20377-5  33169-4 0  9996
    2 43947  96.6348 353.3097 0018626 221.5456 207.0221 16.01103300  8819
    1 43947U 19006A   19080.12837572  .00018161  20446-5  34105-4 0  9991
    2 43947  96.6342 353.5628 0017856 223.7454 246.0274 16.01109643  8852
    1 43947U 19006A   19080.25184005  .00021666  21015-5  40443-4 0  9990
    2 43947  96.6342 353.6854 0017855 223.2528 237.6932 16.01123784  8871
    1 43947U 19006A   19080.56838169  .00007182  19289-5  14116-4 0  9996
    2 43947  96.6323 353.9969 0018497 223.3308 260.9364 16.01125965  8927
    1 43947U 19006A   19080.80934521 -.00010028  19397-5 -17132-4 0  9998
    2 43947  96.6323 354.2362 0018496 222.3649 209.7823 16.01086764  8962
    1 43947U 19006A   19081.01817130 -.00000602  19026-5  00000+0 0  9994
    2 43947  96.6305 354.4520 0018602 217.7557 337.0831 16.00999357  8992
    1 43947U 19006A   19081.19970958  .00192780  17239-4  35047-3 0  9995
    2 43947  96.6332 354.6387 0017808 222.1497 298.3751 16.01166044  9020
    1 43947U 19006A   19081.44288380  .00132357  90623-5  24030-3 0  9997
    2 43947  96.6332 354.8802 0017799 221.2143 260.0465 16.01211967  9068
    1 43947U 19006A   19081.68209472  .00185493  16056-4  34001-3 0  9993
    2 43947  96.6354 355.1161 0017576 220.8387 198.1644 16.01033820  9107
    1 43947U 19006A   19081.80977756  .00126608  84347-5  23219-3 0  9995
    2 43947  96.6356 355.2444 0017575 222.5408 211.8678 16.01049036  9124
    1 43947U 19006A   19082.19785193  .00009851  19489-5  19026-4 0  9997
    2 43947  96.6356 355.6299 0017571 221.0666 288.6619 16.01097025  9186
    1 43947U 19006A   19082.25710510  .00009887  19472-5  19026-4 0  9996
    2 43947  96.6318 355.6880 0017118 220.4674 270.5748 16.01171238  9192
    1 43947U 19006A   19082.38407701  .00138221  97199-5  25077-3 0  9994
    2 43947  96.6325 355.8124 0017241 219.6702 282.7837 16.01240682  9219
    1 43947U 19006A   19082.68646591  .00149753  11067-4  27555-3 0  9993
    2 43947  96.6363 356.1139 0016876 222.4115 221.6813 16.01004284  9261
    1 43947U 19006A   19082.81114447  .00088395  50732-5  16304-3 0  9995
    2 43947  96.6363 356.2377 0016873 221.9425 220.2429 16.01009980  9289
    1 43947U 19006A   19083.00642146  .00143972  10375-4  26369-3 0  9992
    2 43947  96.6358 356.4314 0016878 221.0757 265.8708 16.01087252  9317
    1 43947U 19006A   19083.49288397 -.03265362  32488-2 -61588-2 0  9990
    2 43947  96.6406 356.9162 0017256 219.6745 189.3161 16.00630469  9392
    1 43947U 19006A   19083.74911125  .00084825  48174-5  15749-3 0  9999
    2 43947  96.6345 357.1709 0015989 224.4362 220.2191 16.00930159  9436
    1 43947U 19006A   19083.81116759  .00103815  62739-5  19235-3 0  9995
    2 43947  96.6324 357.2279 0015947 223.4735 218.5865 16.00945210  9446
    1 43947U 19006A   19083.93495759  .00147725  10814-4  27243-3 0  9990
    2 43947  96.6324 357.3507 0015945 222.9977 212.0347 16.00998010  9463
    1 43947U 19006A   19084.04992207  .00154144  11623-4  28342-3 0  9996
    2 43947  96.6354 357.4673 0016254 222.4775 154.7117 16.01036332  9486
    1 43947U 19006A   19084.56994306 -.00389064  56746-4 -71643-3 0  9995
    2 43947  96.6360 357.9786 0015819 222.1151 270.2904 16.00942425  9569
    1 43947U 19006A   19084.68712708  .00107795  66250-5  19877-3 0  9992
    2 43947  96.6366 358.0976 0015957 221.7662 225.5779 16.01024149  9583
    1 43947U 19006A   19084.74556389  .00097765  57838-5  18034-3 0  9991
    2 43947  96.6363 358.1566 0015910 221.6645 202.2537 16.01028963  9598
    1 43947U 19006A   19084.98720666  .00152043  11367-4  27860-3 0  9992
    2 43947  96.6362 358.3958 0015832 220.6056 155.1371 16.01110841  9636
    1 43947U 19006A   19085.19976117  .00022830  21215-5  42802-4 0  9998
    2 43947  96.6349 358.6073 0016094 221.4560 298.5857 16.01085713  9665
    1 43947U 19006A   19085.49952644  .00052661  30351-5  96803-4 0  9996
    2 43947  96.6377 358.9036 0016197 221.8414 224.9544 16.01169686  9718
    1 43947U 19006A   19085.56842683  .00054526  31167-5  10000-3 0  9997
    2 43947  96.6377 358.9720 0016198 221.5803 262.1287 16.01202917  9722
    1 43947U 19006A   19085.80962006  .00050945  29637-5  93510-4 0  9994
    2 43947  96.6379 359.2115 0016283 220.5574 212.4511 16.01198803  9765'''

    mass = 740

    tle_raw = [line.strip() for line in tle_raw.split('\n')]
    if len(tle_raw) % 2 != 0:
        raise Exception('Not even number of lines [not TLE compatible]')
    TLEs = zip(tle_raw[0::2], tle_raw[1::2])

    event_date = np.datetime64('2019-03-27T05:40')
    event_mjd = dpt.npdt2mjd(event_date)

    M_earth = propagator_sgp4.SGP4.GM*1e9/consts.G

    pop = Population(
        name='Simulated Microsat R debris',
        extra_columns = ['A', 'm', 'd', 'C_D', 'C_R'],
        space_object_uses = [True, True, True, True, True],
        propagator = propagator,
        propagator_options = propagator_options,
    )

    pop.allocate(num)


    tle_mjds = np.empty((len(TLEs),), dtype=np.float64)
    for line_id, lines in enumerate(TLEs):
        line1, line2 = lines
        jd0 = tle.tle_jd(line1)
        mjd0 = dpt.jd_to_mjd(jd0)
        tle_mjds[line_id] = mjd0

    best_tle = np.argmin(np.abs(tle_mjds - event_mjd))


    line1, line2 = TLEs[best_tle]
    sat_id = tle.tle_id(line1)
    jd0 = tle.tle_jd(line1)
    mjd0 = dpt.jd_to_mjd(jd0)

    state_TEME = tle.TLE_propagation_TEME(line1, line2, dpt.mjd_to_jd(event_mjd))

    #first has no pert

    states = np.repeat(state_TEME, num, axis=1)

    np.random.seed(seed)

    kep = dpt.cart2kep(state_TEME, m=mass, M_cent=M_earth, radians=False)
    pop.objs[0][1] = kep[0]*1e-3
    pop.objs[0][2] = kep[1]
    pop.objs[0][3] = kep[2]
    pop.objs[0][4] = kep[4]
    pop.objs[0][5] = kep[3]
    pop.objs[0][6] = dpt.true2mean(kep[5], kep[1], radians=False)
        
    pop.objs[0][0] = float(sat_id)
    pop.objs[0][7] = mjd0

    pop.objs[0][8] = np.pi*1.0**2
    pop.objs[0][9] = mass
    pop.objs[0][10] = 2.0
    pop.objs[0][11] = 2.3
    pop.objs[0][12] = 1.0

    ind = 1
    while ind < num:
        C_D = np.random.rand(1)*(C_D_range[1] - C_D_range[0]) + C_D_range[0]
        rho = 11e3
        while rho > 10e3:
            r = np.random.rand(1)*(radii_range[1] - radii_range[0]) + radii_range[0]
            A = np.pi*r**2
            m = np.random.rand(1)*(mass_range[1] - mass_range[0]) + mass_range[0]
            vol = 4.0/3.0*np.pi*r**3
            rho = m/vol

        pert_state = states[:,ind].copy()

        dv = np.random.rand(1)*max_dv
        ddir = _rand_sph(1).T

        pert_state[:3] += ddir[:,0]*dv

        kep = dpt.cart2kep(pert_state, m=mass, M_cent=M_earth, radians=False)

        if kep[0]*(1.0 - kep[1]) > 6353.0e3+100e3:

            pop.objs[ind][1] = kep[0]*1e-3
            pop.objs[ind][2] = kep[1]
            pop.objs[ind][3] = kep[2]
            pop.objs[ind][4] = kep[4]
            pop.objs[ind][5] = kep[3]
            pop.objs[ind][6] = dpt.true2mean(kep[5], kep[1], radians=False)
                    
            pop.objs[ind][0] = float(sat_id) + num
            pop.objs[ind][7] = mjd0

            pop.objs[ind][8] = A
            pop.objs[ind][9] = m
            pop.objs[ind][10] = r*2.0
            pop.objs[ind][11] = C_D
            pop.objs[ind][12] = 1.0

            ind += 1

    if 'out_frame' in pop.propagator_options:
        out_f = pop.propagator_options['out_frame']
    else:
        out_f = 'ITRF'
    pop.propagator_options['out_frame'] = 'TEME'
    pop = propagate_population(pop, mjd)
    pop.propagator_options['out_frame'] = out_f

    return pop