def test_horizontal_to_equatorial(self): #el_t = angle.from_dms(90.) #az_t = angle.from_dms(0.0) #ra, decl = Dunedin.horizontal_to_equatorial(self.utc_date, el_t, az_t) #st = Dunedin.LST(self.utc_date) #self.assertAlmostEqual(st.to_degrees(), ra.to_degrees(), 5) import ephem dnd = ephem.Observer() dnd.lon = str(Dunedin.lon.to_degrees()) dnd.lat = str(Dunedin.lat.to_degrees()) dnd.elevation = Dunedin.alt dnd.pressure = 0.0 dnd.date = self.utc_date for az in np.arange(0, 360, 10): for el in np.arange(-90, 90, 5): az_i = angle.from_dms(az) el_i = angle.from_dms(el) ra, dec = Dunedin.horizontal_to_equatorial(self.utc_date, el_i, az_i) el_f, az_f = Dunedin.equatorial_to_horizontal(self.utc_date, ra, dec) #print(Dunedin) #print('INIT: el az:', el_i, az_i) #print('RA, DEC', ra, dec) #print('FINAL: el az:', el_f, az_f) self.assertTrue((el_i - el_f) < angle.from_dms(0.01)) if (abs(el) != 90): self.assertTrue((az_i - az_f) < angle.from_dms(0.01))
def test_horizontal_to_equatorial(self): # el_t = angle.from_dms(90.) # az_t = angle.from_dms(0.0) # ra, decl = Dunedin.horizontal_to_equatorial(self.utc_date, el_t, az_t) # st = Dunedin.LST(self.utc_date) # self.assertAlmostEqual(st.to_degrees(), ra.to_degrees(), 5) import ephem dnd = ephem.Observer() dnd.lon = str(Dunedin.lon.to_degrees()) dnd.lat = str(Dunedin.lat.to_degrees()) dnd.elevation = Dunedin.alt dnd.pressure = 0.0 dnd.date = self.utc_date for az in np.arange(0, 360, 10): for el in np.arange(-90, 90, 5): az_i = angle.from_dms(az) el_i = angle.from_dms(el) ra, dec = Dunedin.horizontal_to_equatorial( self.utc_date, el_i, az_i) el_f, az_f = Dunedin.equatorial_to_horizontal( self.utc_date, ra, dec) # print(Dunedin) # print('INIT: el az:', el_i, az_i) # print('RA, DEC', ra, dec) # print('FINAL: el az:', el_f, az_f) self.assertTrue((el_i - el_f) < angle.from_dms(0.01)) if abs(el) != 90: self.assertTrue((az_i - az_f) < angle.from_dms(0.01))
def setUp(self): # rad = radio.Max2769B(noise_level=0.) utc_date = datetime.datetime.utcnow() self.config = settings.from_file(TEST_CONFIG) self.config.load_antenna_positions( cal_ant_positions_file=TEST_ANTENNA_POSITIONS) rad = radio.Max2769B( noise_level=[0.0 for _ in range(self.config.get_num_antenna())]) sources = [ simulation_source.SimulationSource( r=1e9, amplitude=1.0, azimuth=angle.from_dms(2.0), elevation=angle.from_dms(50.0), sample_duration=rad.sample_duration, ) ] ant_models = [ antenna_model.GpsPatchAntenna() for i in range(self.config.get_num_antenna()) ] ants = [ antennas.Antenna(self.config.get_loc(), pos) for pos in self.config.get_antenna_positions() ] self.timebase = np.arange(0, rad.sample_duration, 1.0 / rad.sampling_rate) ant_sigs = antennas.antennas_signal(ants, ant_models, sources, self.timebase) self.obs = rad.get_full_obs(ant_sigs, utc_date, self.config, self.timebase)
def antennas_simp_vis(antennas, ant_models, sources, utc_date, config, noise_lvl): """ Return visibility object without generating timeseries or filtering.""" from tart.imaging import visibility vis = [] baselines = [] # noise = np.random.uniform(0.,np.sqrt(noise_lvl),config.num_antennas) * np.exp(2.0j*np.pi*np.random.uniform(-1.,1.,config.num_antennas)) if noise_lvl.__gt__(0.).all(): noise = np.random.normal(0., noise_lvl) * np.exp(2.0j*np.pi*np.random.uniform(-1., 1., config.num_antennas)) else: noise = np.zeros(config.num_antennas) for i in range(0, config.num_antennas): for j in range(i+1, config.num_antennas): vi = noise[i]+noise[j] # print vi for src in sources: gain0 = ant_models[i].get_gain(src.elevation, src.azimuth) gain1 = ant_models[j].get_gain(src.elevation, src.azimuth) if gain0 <= 0. or gain1 <= 0.: vi += 0.0j else: dt = get_geo_delay_horizontal(antennas[i], antennas[j], src.elevation, src.azimuth) vi += gain0*gain1*1.*np.exp(1.0j*dt*constants.L1_OMEGA) * src.amplitude if np.abs(vi) >= 1.: # otherwise in case we have a signal that is almost 1. noise could cause an overflow vi = 1.*vi/np.abs(vi) vis.append(vi) baselines.append([i, j]) obs = observation.Observation(utc_date, config, data=np.zeros(1)) vis_o = visibility.Visibility(obs, angle.from_dms(90.), angle.from_dms(0.)) vis_o.set_visibilities(vis, baselines) return vis_o
def gen_n_photons(self, config, utc_date, radio, n=10): """ Generate a total of n photons. Sources with more jansky will contribute more photons""" cumulativ_src_flux = self.get_cum_src_flux(utc_date) int_src_flux = cumulativ_src_flux[-1] rel_noise_flux = 0.0 tot_flux = int_src_flux * (1.0 + rel_noise_flux) src_identifier = np.random.uniform(0.0, tot_flux, n) hi, _ = np.histogram(src_identifier, bins=cumulativ_src_flux) ret = [] for src_num, count in enumerate(hi): src = self.known_objects[src_num] # Assume the sky is flat. # this will also cause problems at problems at boundaries of dec. dx, dy = np.random.multivariate_normal( [0.0, 0.0], np.identity(2) * np.power(src.width, 2.0), count ).T ra, declination = src.radec(utc_date) for j in range(count): el, az = location.get_loc(config).equatorial_to_horizontal( utc_date, ra + angle.from_dms(dx[j]), declination + angle.from_dms(dy[j]), ) ret.append( simulation_source.SimulationSource( amplitude=1.0 / n, azimuth=az, elevation=el, sample_duration=radio.n_samples / radio.ref_freq, ) ) return ret
def from_state_vector(state): """Generate skymodel from state vector""" sun_str, sat_str, gps, thesun, known_cosmic, location, state_vector = state psky = Skymodel( 0, location=location, sun_str=sun_str, sat_str=sat_str, gps=gps, known_cosmic=known_cosmic, ) psky.n_sources = len(state_vector) / 4 psky.source_list = [] for i in range(psky.n_sources): ra = angle.from_dms(state_vector[i + (0 * psky.n_sources)]) dec = angle.from_dms(state_vector[i + (1 * psky.n_sources)]) gs = radio_source.CosmicSource( ra, dec, jy=state_vector[i + (2 * psky.n_sources)], width=state_vector[i + (3 * psky.n_sources)], ) psky.source_list.append(gs) return psky
def test_horizontal_to_equatorial_astropy(self): from astropy import coordinates as coord from astropy import units as u from astropy import time from astropy.time import Time utc_date = datetime.datetime.utcnow() loc = Dunedin obstime = time.Time(utc_date, scale="utc") eloc = coord.EarthLocation( lat=loc.latitude_deg() * u.deg, lon=loc.longitude_deg() * u.deg, height=loc.alt * u.m, ) altaz_frame = coord.AltAz(obstime=obstime, location=eloc) for el, az in zip(np.linspace(0, 90, 10), np.linspace(0, 259, 10)): elaz = coord.SkyCoord(alt=el * u.deg, az=az * u.deg, frame=altaz_frame) radec = elaz.transform_to(coord.ICRS) ra, dec = loc.horizontal_to_equatorial(utc_date, angle.from_dms(el), angle.from_dms(az)) self.assertAlmostEqual( radec.ra.degree, ra.to_degrees(), -1) # TODO better agreement should be possible. self.assertAlmostEqual( radec.dec.degree, dec.to_degrees(), 1) # TODO better agreement should be possible.
def setUp(self): self.utc_date = datetime.datetime.utcnow() self.config = settings.from_file(TEST_CONFIG) self.config.load_antenna_positions( cal_ant_positions_file=TEST_ANTENNA_POSITIONS) self.rad = radio.Max2769B( noise_level=[0.0 for _ in range(self.config.get_num_antenna())]) self.sources = [ simulation_source.SimulationSource( r=1e9, amplitude=1.0, azimuth=angle.from_dms(2.0), elevation=angle.from_dms(50.0), sample_duration=self.rad.sample_duration, ) ] self.ants = [ antennas.Antenna(self.config.get_loc(), pos) for pos in self.config.get_antenna_positions() ] self.ant_models = [ antenna_model.GpsPatchAntenna() for i in range(self.config.get_num_antenna()) ] self.cor = correlator.Correlator() self.timebase = np.arange(0, self.rad.sample_duration, 1.0 / self.rad.sampling_rate) ant_sigs_full = antennas.antennas_signal(self.ants, self.ant_models, self.sources, self.timebase) obs = self.rad.get_full_obs(ant_sigs_full, self.utc_date, self.config, self.timebase) vis = self.cor.correlate(obs) self.full_vis = np.array(vis.v) ant_sigs_simp = antennas.antennas_simplified_signal( self.ants, self.ant_models, self.sources, self.rad.baseband_timebase, self.rad.int_freq, ) obs = self.rad.get_simplified_obs(ant_sigs_simp, self.utc_date, config=self.config) vis2 = self.cor.correlate(obs) self.sim_vis = np.array(vis2.v) plt.figure(figsize=(4, 4)) plt.scatter(self.full_vis.real, self.full_vis.imag, label="full") plt.scatter(self.sim_vis.real, self.sim_vis.imag, color="red", label="simpl") plt.legend() plt.show()
def gen_photons_per_src(self, utc_date, radio, config, n_samp=1): """ Generate n_samp photons per source""" sources = [] # for src in self.known_objects: if self.l1_catalog: for src in get_L1_srcs(utc_date): if src["el"] > self.l1_elevation_threshold: l = len(self.l1_allowed) if (l == 0) or (src["name"] in self.l1_allowed["names"]): if l != 0: s_str = self.l1_allowed["strength_log10"][ self.l1_allowed["names"].index(src["name"]) ] # print(s_str, type(s_str)) amplitude = np.power(10, s_str) else: amplitude = 1.0 print(src["name"], src["az"], src["el"]) sources.append( simulation_source.SimulationSource( r=src["r"], amplitude=amplitude, azimuth=angle.from_dms(src["az"]), elevation=angle.from_dms(src["el"]), sample_duration=radio.n_samples / radio.ref_freq, ) ) # print('here') for src in self.known_objects: print("extra", src) # for src in self.get_src_objects(location.get_loc(config), utc_date): ra, declination = src.radec(utc_date) dx, dy = np.random.multivariate_normal( [0.0, 0.0], np.identity(2) * np.power(src.width, 2.0), n_samp ).T for j in range(n_samp): el, az = location.get_loc(config).equatorial_to_horizontal( utc_date, ra + angle.from_dms(dx[j]), declination + angle.from_dms(dy[j]), ) sources.append( simulation_source.SimulationSource( r=src.r, amplitude=src.jansky(utc_date) / self.get_int_src_flux(utc_date) * 1.0 / n_samp, azimuth=az, elevation=el, sample_duration=radio.n_samples / radio.ref_freq, ) ) print(len(sources)) return sources
def test_uvw_90(self): a0 = Antenna(location.Dunedin, [0.0, 0.0, 0.0]) a1 = Antenna(location.Dunedin, [0.0, 1.0, 0.0]) el = angle.from_dms(0.0) az = angle.from_dms(0.0) utc_time = utc.now() ra, dec = location.Dunedin.horizontal_to_equatorial(utc_time, el, az) u, v, w = get_UVW(a0, a1, utc_time, ra, dec) self.assertAlmostEqual(u, 0.0) self.assertAlmostEqual(v, 0.0) self.assertAlmostEqual(w, -1.0)
def test_horizontal_to_ecef(self): theta = 90.0 # Straight Up phi = 0.0 x,y,z = Dunedin.horizontal_to_ecef(0.0, angle.from_dms(theta), angle.from_dms(phi)) ecef = Dunedin.get_ecef() self.assertAlmostEqual(x, ecef[0]) self.assertAlmostEqual(y, ecef[1]) self.assertAlmostEqual(z, ecef[2])
def solar_longitude(self, utc_date): jd = tart_util.JulianDay(utc_date) D = jd - 2451545.0 # Mean anomaly of the Sun: g = 357.529 + 0.98560028 * D # Mean longitude of the Sun: q = 280.459 + 0.98564736 * D g = angle.from_dms(g) # Geocentric apparent ecliptic longitude of the Sun (adjusted for aberration): L = q + 1.915 * g.sin() + 0.020 * math.sin(g.to_rad() * 2) L = angle.from_dms(angle.wrap_360(L)) return L
def test_horizontal_to_ecef(self): theta = 90.0 # Straight Up phi = 0.0 x, y, z = Dunedin.horizontal_to_ecef(0.0, angle.from_dms(theta), angle.from_dms(phi)) ecef = Dunedin.get_ecef() self.assertAlmostEqual(x, ecef[0]) self.assertAlmostEqual(y, ecef[1]) self.assertAlmostEqual(z, ecef[2])
def solar_longitude(self, utc_date): jd = tart_util.JulianDay(utc_date) D = jd - 2451545.0 #Mean anomaly of the Sun: g = 357.529 + 0.98560028*D #Mean longitude of the Sun: q = 280.459 + 0.98564736*D g = angle.from_dms(g) #Geocentric apparent ecliptic longitude of the Sun (adjusted for aberration): L = q + 1.915*g.sin() + 0.020*math.sin(g.to_rad()*2) L = angle.from_dms(angle.wrap_360(L)) return L
def __init__(self, cal_vis_list, fixed_zenith=True): self.cal_vis_list = cal_vis_list self.fixed_zenith = fixed_zenith if self.fixed_zenith: self.phase_center = None else: vt = self.cal_vis_list[0] ra, dec = location.get_loc( vt.get_config()).horizontal_to_equatorial( vt.get_timestamp(), angle.from_dms(90), angle.from_dms(0)) self.phase_center = radio_source.CosmicSource(ra, dec, 1e10) self.grid_file = "grid.idx" self.grid_idx = None
def test_uvw(self): a0 = Antenna(location.Dunedin, [0.0, 0.0, 0.0]) a1 = Antenna(location.Dunedin, [0.0, 1.0, 0.0]) el = angle.from_dms(90.0) for az_deg in range(0, 360, 10): az = angle.from_dms(az_deg) utc_time = utc.now() ra, dec = location.Dunedin.horizontal_to_equatorial( utc_time, el, az) u, v, w = get_UVW(a0, a1, utc_time, ra, dec) self.assertAlmostEqual(u, 0.0) self.assertAlmostEqual(v, -1.0) self.assertAlmostEqual(w, 0.0)
def from_state_vector(state): '''Generate skymodel from state vector''' sun_str, sat_str, gps, thesun, known_cosmic, location, state_vector = state psky = Skymodel(0, location=location, sun_str=sun_str, \ sat_str=sat_str, gps=gps, known_cosmic=known_cosmic) psky.n_sources = len(state_vector)/4 psky.source_list = [] for i in range(psky.n_sources): ra = angle.from_dms(state_vector[i+(0*psky.n_sources)]) dec = angle.from_dms(state_vector[i+(1*psky.n_sources)]) gs = radio_source.CosmicSource(ra, dec, jy=state_vector[i+(2*psky.n_sources)], width=state_vector[i+(3*psky.n_sources)]) psky.source_list.append(gs) return psky
def gen_photons_per_src(self, utc_date, radio, config, n_samp=1): ''' Generate n_samp photons per source''' sources = [] #for src in self.known_objects: for src in self.get_src_objects(config.get_loc(), utc_date): ra, declination = src.radec(utc_date) dx, dy = np.random.multivariate_normal([0., 0.], np.identity(2)*np.power(src.width, 2.), n_samp).T for j in range(n_samp): el, az = config.get_loc().equatorial_to_horizontal(utc_date, \ ra + angle.from_dms(dx[j]), declination + angle.from_dms(dy[j])) sources.append(simulation_source.SimulationSource(\ amplitude = src.jansky(utc_date)/self.get_int_src_flux(utc_date)*1./n_samp, \ azimuth = az, elevation = el, sample_duration = radio.sample_duration)) return sources
def jansky(self, utc_date): x, y, z = self.sv_position(utc_date, self.sv) x0,y0,z0 = self.location.get_ecef() r0 = np.array([x0,y0,z0]) - np.array([x,y,z]) rs = - np.array([x,y,z]) # Calculate the off nadir angle (angle between rs # and r0). This maxes out around 14 degrees # An Improved Single Antenna Attitude System Based on GPS Signal Strength # C. Wang1, R. A. Walker 2 and M. P. Moody3 # Cooperative Research Centre for Satellite Systems # Queensland University of Technology, Brisbane, QLD, 4000, Australia angle_off_nadir = vector.angle_between(r0, rs) - angle.from_dms(10.0) # Maximum at 10 degrees # Transmit power EIRP = 27.0 * angle_off_nadir.cos() # dbW # Now estimate the flux, based on the distance r (in meters) r, el, az = self.location.ecef_to_horizontal(x, y, z) free_space_loss_db = 10.0 * np.log10(4.0*np.pi*r**2) # Received power (over whole band) rx_power_dbW = EIRP - free_space_loss_db # Received power (per Hz) bandwidth = 2.0e6 rx_power_dbWHz = rx_power_dbW - 10.0*np.log10(bandwidth) # Convert to Jansky rx_jansky = 10.0**(rx_power_dbWHz / 10.0 + 26.0) return rx_jansky
def jansky(self, utc_date): x, y, z = self.sv_position(utc_date) x0, y0, z0 = self.location.get_ecef() r0 = np.array([x0, y0, z0]) - np.array([x, y, z]) rs = -np.array([x, y, z]) # Calculate the off nadir angle (angle between rs # and r0). This maxes out around 14 degrees # An Improved Single Antenna Attitude System Based on GPS Signal Strength # C. Wang1, R. A. Walker 2 and M. P. Moody3 # Cooperative Research Centre for Satellite Systems # Queensland University of Technology, Brisbane, QLD, 4000, Australia angle_off_nadir = vector.angle_between(r0, rs) - angle.from_dms( 10.0) # Maximum at 10 degrees # Transmit power EIRP = 27.0 * angle_off_nadir.cos() # dbW # Now estimate the flux, based on the distance r (in meters) r, el, az = self.location.ecef_to_horizontal(x, y, z) free_space_loss_db = 10.0 * np.log10(4.0 * np.pi * r**2) # Received power (over whole band) rx_power_dbW = EIRP - free_space_loss_db # Received power (per Hz) bandwidth = 2.0e6 rx_power_dbWHz = rx_power_dbW - 10.0 * np.log10(bandwidth) # Convert to Jansky rx_jansky = 10.0**(rx_power_dbWHz / 10.0 + 26.0) return rx_jansky
def __init__(self, n_sources, location, sun_str=2.e5, sat_str=5.01e6, gps=True, thesun=False, known_cosmic=True): self.n_sources = n_sources self.source_list = [] self.known_objects = [] self.gps_ants = [] self.location = location self.sun_str=sun_str self.sat_str=sat_str self.gps = gps self.thesun = thesun self.known_cosmic= known_cosmic self.el_threshold = 0 if self.thesun: self.add_src(sun.Sun(jy=sun_str)) if self.gps: for i in range(32): sv = gps_satellite.GpsSatellite(i+1, location=self.location,jy=sat_str) self.add_src(sv) if self.known_cosmic: for src in radio_source.BrightSources: self.add_src(src) for _ in range(self.n_sources): ra = angle.from_dms(np.random.uniform(0., 360.)) dec = angle.asin(np.random.uniform(-1., 1)) cs = radio_source.CosmicSource(ra, dec) self.add_src(cs)
def setUp(self): self.config = settings.Settings('test_telescope_config.json') self.utc_date = datetime.datetime.utcnow() self.sources = [simulation_source.SimulationSource(amplitude = 1.0, azimuth = angle.from_dms(2.0), elevation = angle.from_dms(50.0), sample_duration = self.sample_duration)] self.ants = [antennas.Antenna(self.config.get_loc(), pos) for pos in self.config.ant_positions] self.rad = radio.Max2769B(noise_level=[0. for _ in self.config.ant_positions]) self.ant_models = [antenna_model.GpsPatchAntenna() for i in range(self.config.num_antennas)] self.cor = correlator.Correlator() ant_sigs_full = antennas.antennas_signal(self.ants, self.ant_models, self.sources, self.rad.timebase) obs = self.rad.get_full_obs(ant_sigs_full, self.utc_date, config = self.config) vis = self.cor.correlate(obs) self.full_vis = np.array(vis.v) ant_sigs_simp = antennas.antennas_simplified_signal(self.ants, self.ant_models, self.sources, self.rad.baseband_timebase, self.rad.int_freq) obs = self.rad.get_simplified_obs(ant_sigs_simp, self.utc_date, config = self.config) vis2 = self.cor.correlate(obs) self.sim_vis = np.array(vis2.v) plt.figure(figsize=(4,4)) plt.scatter(self.full_vis.real,self.full_vis.imag, label='full') plt.scatter(self.sim_vis.real,self.sim_vis.imag, color='red', label='simpl') plt.legend() plt.show()
def rotate_location(array_orientation, localcoord): array_orientation = angle.from_dms(array_orientation) c = array_orientation.cos() s = array_orientation.sin() e = localcoord[0]*c - localcoord[1]*s n = localcoord[0]*s + localcoord[1]*c u = localcoord[2] return [e, n, u]
def test_horizontal_to_ecef_vs_astropy(self): loc = Dunedin n_tests = 50 el_arr = np.random.rand(n_tests)*np.pi/2 az_arr = np.random.rand(n_tests)*np.pi*2 r_arr = np.random.rand(n_tests)*1e8 utc_date = utc.now() for r, el, az in zip(r_arr, el_arr, az_arr): x,y,z = self.astropy_horizontal_to_ECEF(r, el, az, loc, utc_date) xi, yi, zi = Dunedin.horizontal_to_ecef(r, angle.from_dms(el), angle.from_dms(az)) self.assertAlmostEqual(x/xi, 1.0, 3) self.assertAlmostEqual(y/yi, 1.0, 3) self.assertAlmostEqual(z/zi, 1.0, 3)
def rotate_location(array_orientation, localcoord): array_orientation = angle.from_dms(array_orientation) _e, _n, _u = localcoord c = array_orientation.cos() s = array_orientation.sin() e = _e*c - _n*s n = _e*s + _n*c u = _u return [e, n, u]
def setUp(self): self.config = settings.Settings('test_telescope_config.json') # noiselvls = 0.1.*np.ones(config.num_antennas) noiselvls = 0. * np.ones(self.config.num_antennas) self.rad = Max2769B(noise_level = noiselvls) self.sources = [simulation_source.SimulationSource(amplitude = 1.0, azimuth = angle.from_dms(0.), elevation = angle.from_dms(90.), sample_duration = self.rad.sample_duration)] self.ants = [antennas.Antenna(self.config.get_loc(), pos) for pos in self.config.ant_positions] self.ant_models = [antenna_model.GpsPatchAntenna() for i in range(self.config.num_antennas)] self.utc_date = datetime.datetime.utcnow()
def test_horizontal_to_ecef_vs_astropy(self): loc = Dunedin n_tests = 50 el_arr = np.random.rand(n_tests) * np.pi / 2 az_arr = np.random.rand(n_tests) * np.pi * 2 r_arr = np.random.rand(n_tests) * 1e8 utc_date = utc.now() for r, el, az in zip(r_arr, el_arr, az_arr): x, y, z = self.astropy_horizontal_to_ECEF(r, el, az, loc, utc_date) xi, yi, zi = Dunedin.horizontal_to_ecef(r, angle.from_dms(el), angle.from_dms(az)) self.assertAlmostEqual(x / xi, 1.0, 3) self.assertAlmostEqual(y / yi, 1.0, 3) self.assertAlmostEqual(z / zi, 1.0, 3)
def gen_beam(self, utc_date_init, utc_date_obs, config, radio, az_deg = 20., el_deg = 80.): ''' Generate point source with constant at RA and DEC according to given az and el at time utc_date_init''' sources = [] ra, dec = location.get_loc(config).horizontal_to_equatorial(utc_date_init, angle.from_dms(el_deg), angle.from_dms(az_deg)) src = radio_source.CosmicSource(ra, dec) el, az = src.to_horizontal(location.get_loc(config), utc_date_obs) sources.append(simulation_source.SimulationSource(amplitude = 1., azimuth = az, elevation = el, \ sample_duration = radio.n_samples/radio.ref_freq)) return sources
def rotate_location(array_orientation, localcoord): array_orientation = angle.from_dms(array_orientation) _e, _n, _u = localcoord c = array_orientation.cos() s = array_orientation.sin() e = _e * c - _n * s n = _e * s + _n * c u = _u return [e, n, u]
def solar_longitude_to_RA(self, L, utc_date): # require L to be an angle object!!! jd = tart_util.JulianDay(utc_date) D = jd - 2451545.0 # where jd is the Julian date of interest. Then compute #Mean anomaly of the Sun: g = angle.from_dms(357.529 + 0.98560028*D) #g = angle.to_rad(g) #Mean longitude of the Sun: q = 280.459 + 0.98564736*D R = 1.00014 - 0.01671*g.cos() - 0.00014*math.cos(g.to_rad()*2) # The distance of the Sun from the Earth, R, in astronomical units (AU) e = angle.from_dms(23.439 - 0.00000036*D) # mean obliquity of the ecliptic, in degrees: #L = angle.to_rad() #e = angle.to_rad(e) tan_RA = e.cos() * L.sin() / L.cos() sin_d = e.sin() * L.sin() #RA = math.atan(tan_RA) RA = angle.atan2(e.cos()*L.sin(), L.cos()) RA = RA.to_ra() delta = angle.asin(sin_d) return RA, delta
def __init__(self, cal_vis_list): self.cal_vis_list = cal_vis_list # vt = self.vis_list[int(len(self.vis_list)/2)] vt = self.cal_vis_list[0] # print vt.config ra, dec = vt.get_config().get_loc().horizontal_to_equatorial(vt.get_timestamp(), angle.from_dms(90.), angle.from_dms(90.)) # ra, dec = vt.config.get_loc().horizontal_to_equatorial(vt.timestamp, angle.from_dms(90.), angle.from_dms(0.)) # dec = angle.from_dms(-90.00) # print 'phasecenter:', ra, dec self.phase_center = radio_source.CosmicSource(ra, dec)
def gen_beam( self, utc_date_init, utc_date_obs, config, radio, az_deg=20.0, el_deg=80.0 ): """ Generate point source with constant at RA and DEC according to given az and el at time utc_date_init""" sources = [] ra, dec = location.get_loc(config).horizontal_to_equatorial( utc_date_init, angle.from_dms(el_deg), angle.from_dms(az_deg) ) src = radio_source.CosmicSource(ra, dec) el, az = src.to_horizontal(location.get_loc(config), utc_date_obs) sources.append( simulation_source.SimulationSource( amplitude=1.0, azimuth=az, elevation=el, sample_duration=radio.n_samples / radio.ref_freq, ) ) return sources
def setUp(self): # rad = radio.Max2769B(noise_level=0.) utc_date = datetime.datetime.utcnow() self.settings = settings.Settings('test_telescope_config.json') rad = radio.Max2769B(noise_level=[0. for _ in self.settings.ant_positions]) sources = [simulation_source.SimulationSource(amplitude = 1.0, azimuth = angle.from_dms(2.0), elevation = angle.from_dms(50.0), sample_duration = rad.sample_duration)] ant_models = [antenna_model.GpsPatchAntenna() for i in range(self.settings.num_antennas)] ants = [antennas.Antenna(self.settings.get_loc(), pos) for pos in self.settings.ant_positions] ant_sigs = antennas.antennas_signal(ants, ant_models, sources, rad.timebase) self.obs = rad.get_full_obs(ant_sigs, utc_date, config = self.settings)
def __init__(self, cal_vis_list, phase_center): # FIXME # self.phase_center_elevation = phase_center_elevation # self.phase_center_azimuth = phase_center_azimuth vt = cal_vis_list[0] c = vt.get_config() ant_p = np.asarray(c.get_antenna_positions()) self.config = c self.v_array = cal_vis_list self.n_baselines = len(vt.get_baselines()) self.loc = c.get_loc() # Assume the array isn't moving if phase_center is None: ra, dec = location.get_loc(vt.get_config()).horizontal_to_equatorial( vt.get_timestamp(), angle.from_dms(90), angle.from_dms(0) ) self.phase_center = radio_source.CosmicSource(ra, dec, 1e10) else: self.phase_center = phase_center
def correlate_roll(self, obs, debug=False): vis = visibility.Visibility(obs, angle.from_dms(90.), angle.from_dms(0.)) v = [] baselines = [] data = [] num_ant = obs.config.num_antennas data = obs.data # use obs.data[i] instead of get_antenna to keep mem usage low means = obs.get_means() for i in range(0, num_ant): for j in range(i+1, num_ant): progress = len(baselines) if (progress%10==0): print progress v_real = van_vleck_correction( -means[i]*means[j] + corr_b(data[i], data[j]) ) v_imag = van_vleck_correction( -means[i]*means[j] + corr_b(data[i], fast_roll_1(data[j]))) #v_imag = van_vleck_correction(np.dot(data[i],np.roll(data[j],1))*1./len(data[i])/2.) v_com = v_real-1.j*v_imag v.append(v_com) baselines.append([i,j]) vis.set_visibilities(v, baselines) return vis
def test_horizontal_to_eci_vs_astropy(self): utc_date = datetime.datetime.utcnow() loc = Dunedin n_tests = 50 el_arr = np.random.rand(n_tests)*np.pi/2 az_arr = np.random.rand(n_tests)*np.pi*2 r_arr = np.random.rand(n_tests)*1e8 #utc_date = utc.now() for r, el, az in zip(r_arr, el_arr, az_arr): x,y,z = self.astropy_horizontal_to_ECI(r, el, az, loc, utc_date) xi, yi, zi = Dunedin.horizontal_to_eci(r, angle.from_dms(el), angle.from_dms(az), utc_date) delta = np.sqrt((x-xi)**2 + (y-yi)**2 + (z-zi)**2) # TODO these are failing self.assertAlmostEqual(delta/r, 0.0, 3) self.assertAlmostEqual(x/xi, 1.0, 3) self.assertAlmostEqual(y/yi, 1.0, 3) self.assertAlmostEqual(z/zi, 1.0, 3)
def gen_n_photons(self, config, utc_date, radio, n=10): ''' Generate a total of n photons. Sources with more jansky will contribute more photons''' cumulativ_src_flux = self.get_cum_src_flux(utc_date) int_src_flux = cumulativ_src_flux[-1] rel_noise_flux = 0.0 tot_flux = int_src_flux * (1. + rel_noise_flux) src_identifier = np.random.uniform(0., tot_flux, n) hi, _ = np.histogram(src_identifier, bins=cumulativ_src_flux) ret = [] for src_num, count in enumerate(hi): src = self.known_objects[src_num] # Assume the sky is flat. # this will also cause problems at problems at boundaries of dec. dx, dy = np.random.multivariate_normal([0., 0.], np.identity(2)*np.power(src.width, 2.), count).T ra, declination = src.radec(utc_date) for j in range(count): el, az = location.get_loc(config).equatorial_to_horizontal(utc_date, ra\ + angle.from_dms(dx[j]), declination + angle.from_dms(dy[j])) ret.append(simulation_source.SimulationSource(amplitude = 1./n, \ azimuth = az, elevation = el, sample_duration = radio.n_samples/radio.ref_freq)) return ret
def test_horizontal_to_equatorial_astropy(self): from astropy import coordinates as coord from astropy import units as u from astropy import time from astropy.time import Time utc_date = datetime.datetime.utcnow() loc = Dunedin obstime = time.Time(utc_date, scale='utc') eloc = coord.EarthLocation(lat=loc.latitude_deg()*u.deg, lon=loc.longitude_deg()*u.deg, height=loc.alt*u.m) altaz_frame = coord.AltAz(obstime=obstime, location=eloc) for el, az in zip(np.linspace(0, 90, 10), np.linspace(0,259,10)): elaz = coord.SkyCoord(alt = el*u.deg, az = az*u.deg, frame=altaz_frame) radec = elaz.transform_to(coord.ICRS) ra, dec = loc.horizontal_to_equatorial(utc_date, angle.from_dms(el), angle.from_dms(az)) self.assertAlmostEqual(radec.ra.degree, ra.to_degrees(), -1) # TODO better agreement should be possible. self.assertAlmostEqual(radec.dec.degree, dec.to_degrees(), 1) # TODO better agreement should be possible.
def equatorial_to_horizontal(self, utc_date, ra, dec): # [Peter Duffett-Smith, Jonathan_Zwart] Practical Astronomy with calculator and spreadsheet lha = self.LHA(utc_date,ra) lat = self.lat el = angle.asin(dec.sin()*lat.sin() + dec.cos()*lat.cos()*lha.cos()) az = angle.atan2((-lha.sin())*dec.cos(), (dec.sin()-lat.sin()*el.sin())/lat.cos()) if az.to_degrees() < 0.: az = angle.from_dms(360. + az.to_degrees()) return el, az
def test_horizontal_to_eci_vs_astropy(self): utc_date = datetime.datetime.utcnow() loc = Dunedin n_tests = 50 el_arr = np.random.rand(n_tests) * np.pi / 2 az_arr = np.random.rand(n_tests) * np.pi * 2 r_arr = np.random.rand(n_tests) * 1e8 # utc_date = utc.now() for r, el, az in zip(r_arr, el_arr, az_arr): x, y, z = self.astropy_horizontal_to_ECI(r, el, az, loc, utc_date) xi, yi, zi = Dunedin.horizontal_to_eci(r, angle.from_dms(el), angle.from_dms(az), utc_date) delta = np.sqrt((x - xi)**2 + (y - yi)**2 + (z - zi)**2) # TODO these are failing self.assertAlmostEqual(delta / r, 0.0, 3) self.assertAlmostEqual(x / xi, 1.0, 3) self.assertAlmostEqual(y / yi, 1.0, 3) self.assertAlmostEqual(z / zi, 1.0, 3)
def test_antennas(self): """Test the construction of antenna signals""" ref_freq = 16.368e6 freq_mult = 256 sample_duration = 1e-5 antenna_locations = [[-10.0, 0.0, 0.0], [10.0, 0.0, 0.0]] antennas = [Antenna(location.Dunedin, i) for i in antenna_locations] src = [ SimulationSource( r=1e9, amplitude=1.0, azimuth=angle.from_dms(0.0), elevation=angle.from_dms(20.0), sample_duration=sample_duration, ), SimulationSource( r=1e9, amplitude=0.5, azimuth=angle.from_dms(0.0), elevation=angle.from_dms(20.0), sample_duration=sample_duration, ), ] radio_sampling_rate = ref_freq * freq_mult tb = np.arange(0, sample_duration, 1.0 / radio_sampling_rate) ant_models = [antenna_model.GpsPatchAntenna() for _ in range(2)] ant = antennas_signal(antennas, ant_models, src, tb) self.assertEqual(ant.shape, (len(antenna_locations), len(tb))) mu0 = ant[0, :].mean() self.assertLess(mu0, 0.01) self.assertGreater(mu0, -0.01) mu1 = ant[1, :].mean() self.assertLess(mu1, 0.01) self.assertGreater(mu1, -0.01)
def solar_longitude_to_RA(self, L, utc_date): # require L to be an angle object!!! jd = tart_util.JulianDay(utc_date) D = jd - 2451545.0 # where jd is the Julian date of interest. Then compute # Mean anomaly of the Sun: g = angle.from_dms(357.529 + 0.98560028 * D) # g = angle.to_rad(g) # Mean longitude of the Sun: q = 280.459 + 0.98564736 * D R = ( 1.00014 - 0.01671 * g.cos() - 0.00014 * math.cos(g.to_rad() * 2) ) # The distance of the Sun from the Earth, R, in astronomical units (AU) e = angle.from_dms( 23.439 - 0.00000036 * D) # mean obliquity of the ecliptic, in degrees: # L = angle.to_rad() # e = angle.to_rad(e) tan_RA = e.cos() * L.sin() / L.cos() sin_d = e.sin() * L.sin() # RA = math.atan(tan_RA) RA = angle.atan2(e.cos() * L.sin(), L.cos()) RA = RA.to_ra() delta = angle.asin(sin_d) return RA, delta
def gen_photons_per_src(self, utc_date, radio, config, n_samp=1): ''' Generate n_samp photons per source''' sources = [] #for src in self.known_objects: if self.l1_catalog: for src in get_L1_srcs(utc_date): if (src['el']>self.l1_elevation_threshold): l = len(self.l1_allowed) if (l==0) or (src['name'] in self.l1_allowed['names']): if (l!=0): s_str = self.l1_allowed['strength_log10'][self.l1_allowed['names'].index(src['name'])] #print(s_str, type(s_str)) amplitude = np.power(10,s_str) else: amplitude = 1. print(src['name'], src['az'], src['el']) sources.append(simulation_source.SimulationSource(\ r = src['r'], amplitude = amplitude, \ azimuth = angle.from_dms(src['az']), elevation = angle.from_dms(src['el']), sample_duration = radio.n_samples/radio.ref_freq)) #print('here') for src in self.known_objects: print('extra',src) #for src in self.get_src_objects(location.get_loc(config), utc_date): ra, declination = src.radec(utc_date) dx, dy = np.random.multivariate_normal([0., 0.], np.identity(2)*np.power(src.width, 2.), n_samp).T for j in range(n_samp): el, az = location.get_loc(config).equatorial_to_horizontal(utc_date, \ ra + angle.from_dms(dx[j]), declination + angle.from_dms(dy[j])) sources.append(simulation_source.SimulationSource(\ r = src.r, amplitude = src.jansky(utc_date)/self.get_int_src_flux(utc_date)*1./n_samp, \ azimuth = az, elevation = el, sample_duration = radio.n_samples/radio.ref_freq)) print(len(sources)) return sources
def setUp(self): self.config = settings.from_file("./tart/test/test_telescope_config.json") self.config.load_antenna_positions( cal_ant_positions_file="./tart/test/test_calibrated_antenna_positions.json" ) # noiselvls = 0.1.*np.ones(config.get_num_antenna()) num_ant = self.config.get_num_antenna() noiselvls = 0.0 * np.ones(num_ant) self.rad = Max2769B(noise_level=noiselvls) self.sources = [ simulation_source.SimulationSource( r=1e9, amplitude=1.0, azimuth=angle.from_dms(0.0), elevation=angle.from_dms(90.0), sample_duration=self.rad.sample_duration, ) ] self.ants = [ antennas.Antenna(self.config.get_loc(), pos) for pos in self.config.get_antenna_positions() ] self.ant_models = [antenna_model.GpsPatchAntenna() for i in range(num_ant)] self.utc_date = datetime.datetime.utcnow()
def setUp(self): # rad = radio.Max2769B(noise_level=0.) utc_date = datetime.datetime.utcnow() self.config = settings.from_file(TEST_CONFIG) self.config.load_antenna_positions(cal_ant_positions_file=TEST_ANTENNA_POSITIONS) rad = radio.Max2769B(noise_level=[0. for _ in range(self.config.get_num_antenna())]) sources = [simulation_source.SimulationSource(r=1e9, amplitude = 1.0, azimuth = angle.from_dms(2.0), elevation = angle.from_dms(50.0), sample_duration = rad.sample_duration)] ant_models = [antenna_model.GpsPatchAntenna() for i in range(self.config.get_num_antenna())] ants = [antennas.Antenna(self.config.get_loc(), pos) for pos in self.config.get_antenna_positions()] self.timebase = np.arange(0, rad.sample_duration, 1.0/rad.sampling_rate) ant_sigs = antennas.antennas_signal(ants, ant_models, sources, self.timebase) self.obs = rad.get_full_obs(ant_sigs, utc_date, self.config, self.timebase)
def equatorial_to_horizontal(self, utc_date, ra, dec): """ Convert RA/Decl to Elevation Azimuth this location """ # [Peter Duffett-Smith, Jonathan_Zwart] Practical Astronomy with calculator and spreadsheet lha = self.LHA(utc_date, ra) lat = self.lat el = angle.asin(dec.sin() * lat.sin() + dec.cos() * lat.cos() * lha.cos()) az = angle.atan2((-lha.sin()) * dec.cos(), (dec.sin() - lat.sin() * el.sin()) / lat.cos()) if az.to_degrees() < 0.0: az = angle.from_dms(360.0 + az.to_degrees()) return el, az
def test_full_rotation(self): v = self.v_array[0] v_before = np.array(v.v) # Copy the visibilities el1 = v.phase_el az1 = v.phase_az ra, decl = v.config.get_loc().horizontal_to_equatorial(v.timestamp, el1, az1) # Pick a baseline # Calculate the angle to offset the RA, DEC to produce a full rotation # v.rotate(skyloc.Skyloc(ra + angle.from_dms(0.05), decl)) v_after = np.array(v.v) self.assertAlmostEqual(v.phase_el.to_degrees(), el1.to_degrees(), 0) for x, y in zip(v_before, v_after): self.assertAlmostEqual(np.angle(x), np.angle(y), 1) self.assertAlmostEqual(np.abs(x), np.abs(y), 2)
def test_full_rotation(self): v = self.v_array[0] v_before = np.array(v.v) # Copy the visibilities el1 = v.phase_el az1 = v.phase_az ra, decl = v.config.get_loc().horizontal_to_equatorial(v.timestamp, el1, az1) # Pick a baseline # Calculate the angle to offset the RA, DEC to produce a full rotation # v.rotate(skyloc.Skyloc(ra + angle.from_dms(0.05), decl)) v_after = np.array(v.v) self.assertAlmostEqual(v.phase_el.to_degrees(), el1.to_degrees(), 0) for x,y in zip(v_before, v_after): self.assertAlmostEqual(np.angle(x),np.angle(y),1) self.assertAlmostEqual(np.abs(x),np.abs(y),2)
def ecef_to_horizontal(self, x_in, y_in, z_in): ex,ey,ez = self.get_ecef() # My position in ECEF rx,ry,rz = [x_in - ex, y_in - ey, z_in - ez] enu = np.array(self.ecef_to_enu(rx,ry,rz)) r = np.sqrt(enu.dot(enu)) rho = enu / r el = angle.asin(rho[2]) n = rho[1] #n e = rho[0] #e az = angle.atan2(e, n) if az.to_degrees() < 0.: az = angle.from_dms(360. + az.to_degrees()) return [r, el, az]
def ecef_to_horizontal(self, x_in, y_in, z_in): ex, ey, ez = self.get_ecef() # My position in ECEF rx, ry, rz = [x_in - ex, y_in - ey, z_in - ez] enu = np.array(self.ecef_to_enu(rx, ry, rz)) r = np.sqrt(enu.dot(enu)) rho = enu / r el = angle.asin(rho[2]) n = rho[1] # n e = rho[0] # e az = angle.atan2(e, n) if az.to_degrees() < 0.0: az = angle.from_dms(360.0 + az.to_degrees()) return [r, el, az]
def setUp(self): self.crab = SimulationSource( r=1e9, amplitude=1.0, azimuth=angle.from_dms(0.0), elevation=angle.from_dms(45.0), sample_duration=1e-3, ) # 0.1 ms sample duration self.s2 = SimulationSource( r=1e9, amplitude=1.0, azimuth=angle.from_dms(0.0), elevation=angle.from_dms(90.0), sample_duration=1e-3, ) # 0.1 ms sample duration self.s3 = SimulationSource( r=1e9, amplitude=1.0, azimuth=angle.from_dms(0.0), elevation=angle.from_dms(0.0), sample_duration=1e-3, ) # 0.1 ms sample duration
def get_src(el, az): return HorizontalSource(r=1e9, azimuth=angle.from_dms(az), elevation=angle.from_dms(el))
def __init__(self, location, utc_time, el, az, jy=1000.0, width=0.001): RadioSource.__init__(self, jy, width) a_az = angle.from_dms(az) a_el = angle.from_dms(el) self.skyloc = skyloc.Skyloc.from_horizontal(location, utc_time, a_el,a_az)
''' A cosmic radio source at fixed equatorial coordinates. ''' def __init__(self, ra, dec, jy=1000.0, width=0.001): RadioSource.__init__(self, jy, width) self.skyloc = skyloc.Skyloc(ra, dec) def __repr__(self): return 'COSMIC'+str(self.skyloc) def radec(self, utc_date): # Get the RA and Declination return self.skyloc.ra, self.skyloc.dec C3_461 = CosmicSource(angle.from_hours(23,23,24), angle.from_dms(58,48,54), 2477.0) # SNR-Cassiopeia A CTA_59 = CosmicSource(angle.from_hours(13,22,28), angle.from_dms(-42,46,0), 2010.0) # Cent A NGC5128 CTB_42 = CosmicSource(angle.from_hours(17,42,9), angle.from_dms(-28,50,0), 1800.0) # Sag A Galactic Nucleus C3_405 = CosmicSource(angle.from_hours(19,59,28), angle.from_dms(40,44,2), 1495.0) # D Galaxy - Cygnus A C3_144 = CosmicSource(angle.from_hours(5,34,32), angle.from_dms(22,0,52), 875.0) # SNR Crab Nebula '''Convenient list of bright sources''' BrightSources = [C3_461, CTA_59, CTB_42, C3_405, C3_144] # Use data from the NED database of objects http://ned.ipac.caltech.edu/ #class NEDRadioSources: #def __init__ if __name__ == '__main__': date = datetime.datetime.utcnow()
def get_loc(Settings): return Location( angle.from_dms(Settings.get_lat()), angle.from_dms(Settings.get_lon()), Settings.get_alt(), )
def get_loc(self): return location.Location(angle.from_dms(self.Dict['lat']), angle.from_dms(self.Dict['lon']), self.Dict['alt'])
from tart.simulation import antennas from tart.simulation import spectrum from tart.imaging import antenna_model from tart.util import angle from tart.simulation.radio import * config = settings.Settings("../test/test_telescope_config.json") num_ant = config.get_num_antenna() noiselvls = 0.1 * np.ones(num_ant) rad = Max2769B(n_samples=2**14, noise_level=noiselvls) sources = [ simulation_source.SimulationSource( amplitude=1.0, azimuth=angle.from_dms(0.0), elevation=angle.from_dms(90.0), sample_duration=rad.sample_duration, ) ] ants = [ antennas.Antenna(config.get_loc(), pos) for pos in config.ant_positions ] ant_models = [antenna_model.GpsPatchAntenna() for i in range(num_ant)] utc_date = datetime.datetime.utcnow() plt.figure() ant_sigs = antennas.antennas_signal(ants, ant_models, sources, rad.timebase) rad_sig_full = rad.sampled_signal(ant_sigs[0, :], 0, rad.sample_duration) obs_full = rad.get_full_obs(ant_sigs, utc_date, config)
def __init__(self, location, utc_time, r, el, az, jy=1000.0, width=0.001): RadioSource.__init__(self, r, jy, width) a_az = angle.from_dms(az) a_el = angle.from_dms(el) self.skyloc = skyloc.Skyloc.from_horizontal(location, utc_time, a_el, a_az)
def setUp(self): self.utc_date = datetime.datetime.utcnow() self.config = settings.from_file(TEST_CONFIG) self.config.load_antenna_positions(cal_ant_positions_file=TEST_ANTENNA_POSITIONS) self.rad = radio.Max2769B(noise_level=[0. for _ in range(self.config.get_num_antenna())]) self.sources = [simulation_source.SimulationSource(r=1e9,amplitude = 1.0, azimuth = angle.from_dms(2.0), elevation = angle.from_dms(50.0), sample_duration = self.rad.sample_duration)] self.ants = [antennas.Antenna(self.config.get_loc(), pos) for pos in self.config.get_antenna_positions()] self.ant_models = [antenna_model.GpsPatchAntenna() for i in range(self.config.get_num_antenna())] self.cor = correlator.Correlator() self.timebase = np.arange(0, self.rad.sample_duration, 1.0/self.rad.sampling_rate) ant_sigs_full = antennas.antennas_signal(self.ants, self.ant_models, self.sources, self.timebase) obs = self.rad.get_full_obs(ant_sigs_full, self.utc_date, self.config, self.timebase) vis = self.cor.correlate(obs) self.full_vis = np.array(vis.v) ant_sigs_simp = antennas.antennas_simplified_signal(self.ants, self.ant_models, self.sources, self.rad.baseband_timebase, self.rad.int_freq) obs = self.rad.get_simplified_obs(ant_sigs_simp, self.utc_date, config = self.config) vis2 = self.cor.correlate(obs) self.sim_vis = np.array(vis2.v) plt.figure(figsize=(4,4)) plt.scatter(self.full_vis.real,self.full_vis.imag, label='full') plt.scatter(self.sim_vis.real,self.sim_vis.imag, color='red', label='simpl') plt.legend() plt.show()
def __init__(self, config, timestamp): self.phase_el = angle.from_dms(90.) self.phase_az = angle.from_dms(0.) self.config = config self.timestamp = timestamp