def test_eci_aer(useastropy): t = '2013-01-15T12:00:05' aer1 = pm.eci2aer(*eci0, 42, -100, 0, t, useastropy=useastropy) assert aer1 == approx([83.73050, -6.614478, 1.473510e6], rel=0.001) assert pm.aer2eci(*aer1, 42, -100, 0, t, useastropy=useastropy) == approx(eci0, rel=0.001) with pytest.raises(ValueError): pm.aer2eci(aer1[0], aer1[1], -1, 42, -100, 0, t, useastropy=useastropy)
def test_eci_aer(useastropy): pytest.importorskip("numpy") t = "2013-01-15T12:00:05" aer1 = pm.eci2aer(*eci0, 42, -100, 0, t, useastropy=useastropy) assert aer1 == approx([83.73050, -6.614478, 1.473510e6], rel=0.001) assert pm.aer2eci(*aer1, 42, -100, 0, t, useastropy=useastropy) == approx(eci0, rel=0.001) with pytest.raises(ValueError): pm.aer2eci(aer1[0], aer1[1], -1, 42, -100, 0, t, useastropy=useastropy)
def test_eci2aer(use_astropy): # test coords from Matlab eci2aer pytest.importorskip("numpy") if use_astropy: pytest.importorskip("astropy") t = datetime(1969, 7, 20, 21, 17, 40) eci = [-3.8454e8, -0.5099e8, -0.3255e8] lla = [28.4, -80.5, 2.7] aer = pm.eci2aer(*eci, *lla, t, use_astropy=use_astropy) rel = 0.0001 if use_astropy else 0.01 assert aer == approx([162.55, 55.12, 384013940.9], rel=rel)
def get_observer_azimuth_elevation(self, observer_latitude, observer_longitude, observer_altitude, date, north_offset=0.0): '''Returns the satellite directions (azimuth, elevation) for the given observer's positions''' assert(date.tzinfo == timezone.utc) eci_position = self.propagate(date)[0] aer_position = pm.eci2aer(eci_position, observer_latitude, observer_longitude, observer_altitude, date) az = (aer_position[0][0] - north_offset) % 360.0 el = aer_position[1][0] return az, el
def _is_satellite_in_frame(self, ra, dec, loc, fov, sat_pass, ts): ra_rng = (ra - fov, ra + fov) dec_rng = (dec - fov, dec + fov) lat, lon, alt = loc for i, t in enumerate(ts): dt = datetime.fromtimestamp(int(t.value)) x, y, z = sat_pass[i] az, el, rng = pm.eci2aer(sat_pass[i], lat, lon, alt, dt) ra_sat, dec_sat = pm.azel2radec(az, el, lat, lon, dt) if ra_rng[0] <= ra_sat <= ra_rng[1]: if dec_rng[0] <= dec_sat <= dec_rng[1]: return True return False
def test_eci(): tlla = (42, -82, 200) teci = (-3.977913815668146e6, -2.582332196263046e6, 4.250818828152067e6) t = datetime(2013, 1, 15, 12, 0, 5, tzinfo=UTC) lla = asarray(pm.eci2geodetic(teci, t)).squeeze() assert_allclose(lla, tlla, rtol=0.2) assert_allclose( pm.eci2ecef(teci, t).squeeze(), [649012.04640917, -4697980.55129606, 4250818.82815207]) assert_allclose( pm.ecef2eci([649012.04640917, -4697980.55129606, 4250818.82815207], t).squeeze(), teci) assert_allclose( asarray(pm.eci2aer(teci, 42, -100, 0, t)).squeeze(), [83.73050, -6.614478, 1.473510e6])
def get_observer_azimuth_elevation(self, observer_latitude, observer_longitude, observer_altitude, date=None): '''Returns the satellite directions (azimuth, elevation) for the given observer's positions''' if date is None: date = datetime.now(timezone.utc) eci_position = self.propagate(date)[0] aer_position = pm.eci2aer(eci_position, observer_latitude, observer_longitude, observer_altitude, date) az = aer_position[0][0] el = aer_position[1][0] return az, el
def test_eci_vallado(): t = '2013-01-15T12:00:05' lla = pm.eci2geodetic(eci0, t, useastropy=False) assert lla == approx(lla0, rel=0.2) eci1 = pm.eci2ecef(eci0, t, useastropy=False) assert eci1 == approx( [649012.04640917, -4697980.55129606, 4250818.82815207], rel=0.001) assert pm.ecef2eci(eci1, t, useastropy=False) == approx(eci0, rel=0.001) aer1 = pm.eci2aer(eci0, 42, -100, 0, t, useastropy=False) assert aer1 == approx([83.73050, -6.614478, 1.473510e6], rel=0.001) assert pm.aer2eci(*aer1, 42, -100, 0, t, useastropy=False) == approx(eci0, rel=0.001) with pytest.raises(ValueError): pm.aer2eci(aer1[0], aer1[1], -1, 42, -100, 0, t, useastropy=False)
def test_eci_astropy(): pytest.importorskip('astropy') t = '2013-01-15T12:00:05' lla = pm.eci2geodetic(eci0, t) assert lla == approx(lla0, rel=0.2) eci1 = pm.eci2ecef(eci0, t) assert eci1 == approx( [649012.04640917, -4697980.55129606, 4250818.82815207]) assert pm.ecef2eci(eci1, t) == approx(eci0) aer1 = pm.eci2aer(eci0, 42, -100, 0, t) assert aer1 == approx([83.73050, -6.614478, 1.473510e6]) assert pm.aer2eci(*aer1, 42, -100, 0, t) == approx(eci0) with pytest.raises(ValueError): pm.aer2eci(aer1[0], aer1[1], -1, 42, -100, 0, t)
def iridium_ncdf(fn,day,tlim,ellim, camlla): assert len(ellim) == 2,'must specify elevation limits' fn = Path(fn).expanduser() day = forceutc(day) #%% get all sats psuedo SV number with Dataset(str(fn),'r') as f: #psv_border = nonzero(diff(f['pseudo_sv_num'])!=0)[0] #didn't work because of consequtively reused psv #unique doesn't work because psv's can be recycled psv_border = (diff(f['time'])<0).nonzero()[0] + 1 #note unequal number of samples per satellite, +1 for how diff() is defined #%% iterate over psv, but remember different number of time samples for each sv. # since we are only interested in one satellite at a time, why not just iterate one by one, throwing away uninteresting results # qualified by crossing of FOV. #%% consider only satellites above az,el limits for this location #TODO assumes only one satellite meets elevation and time criteria lind = [0,0] #init for i in psv_border: lind = [lind[1],i] cind = arange(lind[0],lind[1]-1,dtype=int) # all times for this SV #now handle times for this SV t = array([day + timedelta(hours=h) for h in f['time'][cind].astype(float)]) if tlim: mask = (tlim[0] <= t) & (t <= tlim[1]) t = t[mask] cind = cind[mask] #now filter by az,el criteria az,el,r = eci2aer(f['pos_eci'][cind,:], camlla[0], camlla[1], camlla[2],t) if ellim and ((ellim[0] <= el) & (el <= ellim[1])).any(): # print(t) #print('sat psv {}'.format(f['pseudo_sv_num'][i])) eci = f['pos_eci'][cind,:] lat,lon,alt = eci2geodetic(eci,t) x,y,z = eci2ecef(eci,t) #print('ecef {} {} {}'.format(x,y,z)) ecef = DataFrame(index=t, columns=['x','y','z'], data=column_stack((x,y,z))) lla = DataFrame(index=t, columns=['lat','lon','alt'], data=column_stack((lat,lon,alt))) aer = DataFrame(index=t, columns=['az','el','srng'], data=column_stack((az,el,r))) return ecef,lla,aer,eci print('no FOV crossings for your time span were found.') return (None,None)
def see_satellite(satellite, obs_lat, obs_lon, obs_alt, start, end, count=None, annotate=True, title=''): positions_at = satellite.propagate_positions(start, end, count=count) azimuth = [] elevation = [] dates = [] for position_at in positions_at: eci, date = position_at aer = pm.eci2aer(eci, obs_lat, obs_lon, obs_alt, date) az = aer[0][0] el = aer[1][0] azimuth.append(az) elevation.append(el) dates.append(date) print('plotted points between [{}] and [{}].'.format(dates[0], dates[-1])) plot_az_el(azimuth, elevation) dates = [x[1] for x in positions_at] ax = plt.gca() plt.suptitle(title, size=20) df = pd.DataFrame({ 'Azimuth': azimuth, 'Elevation': elevation, 'Date': dates }) return df
def test_eci(self): if numpy is None or astropy is None: logging.warning('ECI not tested') return teci = (-3.977913815668146e6, -2.582332196263046e6, 4.250818828152067e6) t = datetime(2013, 1, 15, 12, 0, 5, tzinfo=UTC) lla = numpy.asarray(pm.eci2geodetic(teci, t)).squeeze() assert_allclose(lla, lla0, rtol=0.2) assert_allclose( pm.eci2ecef(teci, t).squeeze(), [649012.04640917, -4697980.55129606, 4250818.82815207]) assert_allclose( pm.ecef2eci([649012.04640917, -4697980.55129606, 4250818.82815207], t).squeeze(), teci) assert_allclose( numpy.asarray(pm.eci2aer(teci, 42, -100, 0, t)).squeeze(), [83.73050, -6.614478, 1.473510e6])