<s> """<STR_LIT>""" <EOL> __author__ = '<STR_LIT>' <EOL> import datetime <EOL> from datetime import timedelta as py_td <EOL> import ephem <EOL> import logging <EOL> import numpy <EOL> from services . common import gis , misc <EOL> logger = logging . getLogger ( '<STR_LIT>' ) <EOL> class OrbitalSimulator ( object ) : <EOL> """<STR_LIT>""" <EOL> _test_mode = False <EOL> _fail_test = False <EOL> def set_debug ( self , on = True , fail = False ) : <EOL> """<STR_LIT>""" <EOL> self . _test_mode = on <EOL> self . _fail_test = fail <EOL> def get_debug ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . _test_mode <EOL> _observer = None <EOL> _body = None <EOL> _tle = None <EOL> @ staticmethod <EOL> def normalize_string ( l0 , l1 , l2 ) : <EOL> """<STR_LIT>""" <EOL> if isinstance ( l0 , bytes ) : <EOL> l0 = str ( l0 , '<STR_LIT:ascii>' ) <EOL> if isinstance ( l1 , bytes ) : <EOL> l1 = str ( l1 , '<STR_LIT:ascii>' ) <EOL> if isinstance ( l2 , bytes ) : <EOL> l2 = str ( l2 , '<STR_LIT:ascii>' ) <EOL> return l0 , l1 , l2 <EOL> @ staticmethod <EOL> def check_tle_format ( l0 , l1 , l2 ) : <EOL> """<STR_LIT>""" <EOL> l0 , l1 , l2 = OrbitalSimulator . normalize_string ( l0 , l1 , l2 ) <EOL> ephem . readtle ( l0 , l1 , l2 ) <EOL> return True <EOL> @ staticmethod <EOL> def _create_test_operational_slots ( <EOL> start , end , minimum_duration = datetime . timedelta ( minutes = <NUM_LIT:5> ) <EOL> ) : <EOL> """<STR_LIT>""" <EOL> if start is None : <EOL> now = misc . get_now_utc ( ) <EOL> return [ ( now , now + minimum_duration ) ] <EOL> if end is None : <EOL> return [ ( start , start + minimum_duration ) ] <EOL> return [ ( start , end ) ] <EOL> @ staticmethod <EOL> def ephem_date_2_utc_datetime ( e_date ) : <EOL> """<STR_LIT>""" <EOL> return misc . localize_datetime_utc ( e_date . datetime ( ) ) <EOL> @ staticmethod <EOL> def datetime_2_ephem_string ( dt ) : <EOL> """<STR_LIT>""" <EOL> if dt is None : <EOL> dt = misc . get_today_utc ( ) <EOL> return dt . strftime ( "<STR_LIT>" ) <EOL> @ staticmethod <EOL> def dbtle_2_ephem_str ( spacecraft_tle ) : <EOL> """<STR_LIT>""" <EOL> return misc . unicode_2_string ( spacecraft_tle . identifier ) , misc . unicode_2_string ( spacecraft_tle . first_line ) , misc . unicode_2_string ( spacecraft_tle . second_line ) <EOL> def set_groundstation ( self , groundstation ) : <EOL> """<STR_LIT>""" <EOL> self . _observer = ephem . Observer ( ) <EOL> self . _observer . lat = gis . decimal_2_degrees ( groundstation . latitude ) <EOL> self . _observer . lon = gis . decimal_2_degrees ( groundstation . longitude ) <EOL> self . _observer . horizon = gis . decimal_2_degrees ( <EOL> groundstation . contact_elevation <EOL> ) <EOL> self . _observer . elevation = groundstation . altitude <EOL> def set_spacecraft ( self , spacecraft_tle ) : <EOL> """<STR_LIT>""" <EOL> self . _tle = spacecraft_tle <EOL> l0 , l1 , l2 = OrbitalSimulator . dbtle_2_ephem_str ( spacecraft_tle ) <EOL> self . _body = OrbitalSimulator . create_spacecraft ( l0 , l1 , l2 ) <EOL> @ staticmethod <EOL> def create_spacecraft ( l0 , l1 , l2 ) : <EOL> """<STR_LIT>""" <EOL> l0 , l1 , l2 = OrbitalSimulator . normalize_string ( l0 , l1 , l2 ) <EOL> return ephem . readtle ( l0 , l1 , l2 ) <EOL> @ staticmethod <EOL> def get_update_duration ( ) : <EOL> """<STR_LIT>""" <EOL> return datetime . timedelta ( days = <NUM_LIT:1> ) <EOL> @ staticmethod <EOL> def get_update_window ( ) : <EOL> """<STR_LIT>""" <EOL> s_window = OrbitalSimulator . get_simulation_window ( ) <EOL> return ( <EOL> s_window [ <NUM_LIT:1> ] , <EOL> s_window [ <NUM_LIT:1> ] + OrbitalSimulator . get_update_duration ( ) <EOL> ) <EOL> @ staticmethod <EOL> def get_window_duration ( ) : <EOL> """<STR_LIT>""" <EOL> return datetime . timedelta ( days = <NUM_LIT:3> ) <EOL> @ staticmethod <EOL> def get_simulation_window ( ) : <EOL> """<STR_LIT>""" <EOL> start = misc . get_now_utc ( ) <EOL> end = misc . get_next_midnight ( ) + OrbitalSimulator . get_window_duration ( ) - datetime . timedelta ( days = <NUM_LIT:1> ) <EOL> return start , end <EOL> def calculate_passes ( self , availability_slots ) : <EOL> """<STR_LIT>""" <EOL> pass_slots = [ ] <EOL> for a_slot_i in availability_slots : <EOL> pass_i = self . calculate_pass_slot ( a_slot_i [ <NUM_LIT:0> ] , a_slot_i [ <NUM_LIT:1> ] ) <EOL> pass_i_id = a_slot_i [ <NUM_LIT:2> ] <EOL> pass_slots . append ( ( pass_i , pass_i_id ) ) <EOL> return pass_slots <EOL> def calculate_pass_slot ( <EOL> self , start , end , minimum_slot_duration = datetime . timedelta ( minutes = <NUM_LIT:1> ) <EOL> ) : <EOL> """<STR_LIT>""" <EOL> if self . _test_mode : <EOL> if self . _fail_test : <EOL> raise Exception ( '<STR_LIT>' ) <EOL> return OrbitalSimulator . _create_test_operational_slots ( start , end ) <EOL> pass_slots = [ ] <EOL> self . _observer . date = OrbitalSimulator . datetime_2_ephem_string ( start ) <EOL> last_end = start <EOL> while last_end < end : <EOL> tr , azr , tt , altt , ts , azs = self . _observer . next_pass ( self . _body ) <EOL> self . _body . compute ( self . _observer ) <EOL> if not tr or not ts : <EOL> return pass_slots <EOL> dt_tr = misc . localize_datetime_utc ( tr . datetime ( ) ) <EOL> dt_ts = misc . localize_datetime_utc ( ts . datetime ( ) ) <EOL> if dt_tr > end : <EOL> break <EOL> if dt_ts > end : <EOL> slot_end = end <EOL> else : <EOL> slot_end = dt_ts <EOL> if ( slot_end - dt_tr ) > minimum_slot_duration : <EOL> pass_slots . append ( ( dt_tr , slot_end ) ) <EOL> self . _observer . date = ts + ephem . minute <EOL> last_end = misc . localize_datetime_utc ( <EOL> self . _observer . date . datetime ( ) <EOL> ) <EOL> return pass_slots <EOL> @ staticmethod <EOL> def arrays_2_groundtrack ( timestamps , latitudes , longitudes ) : <EOL> """<STR_LIT>""" <EOL> gt = [ ] <EOL> i = <NUM_LIT:0> <EOL> for ts_i in timestamps : <EOL> lat_i = latitudes [ i ] <EOL> lng_i = longitudes [ i ] <EOL> gt . append ( { <EOL> '<STR_LIT>' : ts_i , <EOL> '<STR_LIT>' : lat_i , <EOL> '<STR_LIT>' : lng_i <EOL> } ) <EOL> i += <NUM_LIT:1> <EOL> return gt <EOL> def calculate_groundtrack ( <EOL> self , spacecraft_tle , <EOL> interval = None , <EOL> timestep = py_td ( seconds = <NUM_LIT:20> ) <EOL> ) : <EOL> """<STR_LIT>""" <EOL> if not interval : <EOL> interval = OrbitalSimulator . get_simulation_window ( ) <EOL> if self . _test_mode : <EOL> if self . _fail_test : <EOL> raise Exception ( '<STR_LIT>' ) <EOL> self . set_spacecraft ( spacecraft_tle ) <EOL> groundtrack = [ ] <EOL> date_i = interval [ <NUM_LIT:0> ] <EOL> while date_i < interval [ <NUM_LIT:1> ] : <EOL> self . _body . compute ( date_i ) <EOL> lat_i = numpy . rad2deg ( self . _body . sublat ) <EOL> lng_i = numpy . rad2deg ( self . _body . sublong ) <EOL> groundtrack . append ( { <EOL> '<STR_LIT>' : date_i , <EOL> '<STR_LIT>' : lat_i , <EOL> '<STR_LIT>' : lng_i <EOL> } ) <EOL> date_i += timestep <EOL> return groundtrack <EOL> def __unicode__ ( self ) : <EOL> return '<STR_LIT>' + str ( self . _body ) + '<STR_LIT>' + self . _tle . identifier + '<STR_LIT>' + self . _tle . first_line + '<STR_LIT>' + self . _tle . second_line + '<STR_LIT>' + '<STR_LIT>' + str ( self . _observer . lat ) + '<STR_LIT:U+002CU+0020>' + str ( self . _observer . lon ) + '<STR_LIT:)>' + '<STR_LIT>' + str ( self . _observer . elevation ) + '<STR_LIT>' + str ( self . _observer . horizon ) + '<STR_LIT>' + str ( self . _observer . date ) <EOL> def __str__ ( self ) : <EOL> return self . __unicode__ ( ) </s>
