def main(): # ========================================================================== # Telescope element radii st_radius = 35.0 / 2.0 # Station-radius ss_radius = st_radius * 3.0 # Super-station radius # Core ring super-stations num_rings = 4 ring_counts = [1, 5, 11, 17] ring_radii = [0.0, 100.0, 190.0, 290.0] # metres num_super_stations_rings = numpy.array(ring_counts).sum() ring_start_angle = -360.0 * random(num_rings) + 360.0 ss_ring_petal_angle = -360.0 * random(num_super_stations_rings) + 360.0 # Core arms num_arms = 3 core_arm_count = 5 # Number of super-stations per core arm a = 300.0 b = 0.513 delta_theta = 37.0 arm_offsets = [35.0, 155.0, 275.0] num_super_stations_arms = num_arms * core_arm_count ss_arm_petal_angle = -360.0 * random(num_super_stations_arms) + 360.0 # Outer arms (same outer 3 * 12 = 36 stations as v4a) outer_arm_count = 12 # Number of super-stations per outer arm num_super_stations_outer = num_arms * outer_arm_count v4a_ss_enu_file = 'v7ska1lowN1v2rev3R.enu.94x4.fixed.txt' ss_petal_angle_outer = -360.0 * random(num_super_stations_outer) + 360.0 # Stations num_stations_per_ss = 6 out_dir = 'v4d_layout' if not os.path.isdir(out_dir): os.makedirs(out_dir) # ========================================================================== # == Super-stations # Generate core ring super-stations v4d_ss_x_rings = numpy.zeros(num_super_stations_rings) v4d_ss_y_rings = numpy.zeros(num_super_stations_rings) idx = 0 for i, hist in enumerate(ring_counts): angles = numpy.arange(hist) * (360.0 / hist) angles += ring_start_angle[i] x = ring_radii[i] * numpy.cos(numpy.radians(angles)) y = ring_radii[i] * numpy.sin(numpy.radians(angles)) v4d_ss_x_rings[idx:idx+hist] = x v4d_ss_y_rings[idx:idx+hist] = y idx += hist # Generate core spiral arm super-stations v4d_ss_x_arms = numpy.zeros(num_super_stations_arms) v4d_ss_y_arms = numpy.zeros(num_super_stations_arms) for i in range(num_arms): t = numpy.arange(1, core_arm_count + 1) * delta_theta t = numpy.radians(t) x = a * numpy.exp(b * t) * numpy.cos(t + numpy.radians(arm_offsets[i])) y = a * numpy.exp(b * t) * numpy.sin(t + numpy.radians(arm_offsets[i])) i0 = i * core_arm_count i1 = i0 + core_arm_count v4d_ss_x_arms[i0:i1] = x v4d_ss_y_arms[i0:i1] = y # Load super-station outer spiral arms from the v4a config v4a_ss_enu = numpy.loadtxt(v4a_ss_enu_file) v4a_ss_enu = v4a_ss_enu[:, 1:] v4a_ss_r = (v4a_ss_enu[:, 0]**2 + v4a_ss_enu[:, 1]**2)**0.5 sort_idx = numpy.argsort(v4a_ss_r) v4a_ss_enu = v4a_ss_enu[sort_idx[::-1], :] v4d_ss_x_outer = v4a_ss_enu[:num_super_stations_outer, 0] v4d_ss_y_outer = v4a_ss_enu[:num_super_stations_outer, 1] # == Stations # Generate core ring stations v4d_st_x_rings = numpy.zeros((num_super_stations_rings, num_stations_per_ss)) v4d_st_y_rings = numpy.zeros_like(v4d_st_x_rings) for i in range(num_super_stations_rings): angles = 360.0 / (num_stations_per_ss - 1) * \ numpy.arange(num_stations_per_ss - 1) x = (st_radius * 2.0) * numpy.cos(numpy.radians(angles)) y = (st_radius * 2.0) * numpy.sin(numpy.radians(angles)) x, y = rotate_coords(x, y, ss_ring_petal_angle[i]) v4d_st_x_rings[i, 1:] = x v4d_st_y_rings[i, 1:] = y v4d_st_x_rings[i, :] += v4d_ss_x_rings[i] v4d_st_y_rings[i, :] += v4d_ss_y_rings[i] v4d_st_x_rings = v4d_st_x_rings.flatten() v4d_st_y_rings = v4d_st_y_rings.flatten() # Generate core spiral arm stations v4d_st_x_arms = numpy.zeros((num_super_stations_arms, num_stations_per_ss)) v4d_st_y_arms = numpy.zeros_like(v4d_st_x_arms) for i in range(num_super_stations_arms): angles = 360.0 / (num_stations_per_ss - 1) * \ numpy.arange(num_stations_per_ss - 1) x = (st_radius * 2.0) * numpy.cos(numpy.radians(angles)) y = (st_radius * 2.0) * numpy.sin(numpy.radians(angles)) x, y = rotate_coords(x, y, ss_arm_petal_angle[i]) v4d_st_x_arms[i, 1:] = x v4d_st_y_arms[i, 1:] = y v4d_st_x_arms[i, :] += v4d_ss_x_arms[i] v4d_st_y_arms[i, :] += v4d_ss_y_arms[i] v4d_st_x_arms = v4d_st_x_arms.flatten() v4d_st_y_arms = v4d_st_y_arms.flatten() # Generate outer arm stations v4d_st_x_outer = numpy.zeros((num_super_stations_outer, num_stations_per_ss)) v4d_st_y_outer = numpy.zeros((num_super_stations_outer, num_stations_per_ss)) for i in range(num_super_stations_outer): angles = 360.0 / (num_stations_per_ss - 1) * \ numpy.arange(num_stations_per_ss - 1) x = (st_radius * 2.0) * numpy.cos(numpy.radians(angles)) y = (st_radius * 2.0) * numpy.sin(numpy.radians(angles)) x, y = rotate_coords(x, y, ss_petal_angle_outer[i]) v4d_st_x_outer[i, 1:] = x v4d_st_y_outer[i, 1:] = y v4d_st_x_outer[i, :] += v4d_ss_x_outer[i] v4d_st_y_outer[i, :] += v4d_ss_y_outer[i] v4d_st_x_outer = v4d_st_x_outer.flatten() v4d_st_y_outer = v4d_st_y_outer.flatten() # Concatenate coords. v4d_ss_x = numpy.hstack((v4d_ss_x_rings, v4d_ss_x_arms, v4d_ss_x_outer)) v4d_ss_y = numpy.hstack((v4d_ss_y_rings, v4d_ss_y_arms, v4d_ss_y_outer)) v4d_st_x = numpy.hstack((v4d_st_x_rings, v4d_st_x_arms, v4d_st_x_outer)) v4d_st_y = numpy.hstack((v4d_st_y_rings, v4d_st_y_arms, v4d_st_y_outer)) # === Generate layouts ============================== num_stations = v4d_st_x.shape[0] v4d_st_enu = numpy.zeros((num_stations, 3)) v4d_st_enu[:, 0] = v4d_st_x v4d_st_enu[:, 1] = v4d_st_y numpy.savetxt(join(out_dir, 'v4d_stations_enu.txt'), v4d_st_enu, fmt='% -16.12f % -16.12f % -16.12f') num_super_stations = v4d_ss_x.shape[0] v4d_ss_enu = numpy.zeros((num_super_stations, 3)) v4d_ss_enu[:, 0] = v4d_ss_x v4d_ss_enu[:, 1] = v4d_ss_y numpy.savetxt(join(out_dir, 'v4d_super_stations_enu.txt'), v4d_ss_enu, fmt='% -16.12f % -16.12f % -16.12f') # ==== Plotting =========================================================== fig = pyplot.figure(figsize=(8, 8)) ax = fig.add_subplot(111, aspect='equal') for i in range(num_super_stations_rings): circle = pyplot.Circle((v4d_ss_x_rings[i], v4d_ss_y_rings[i]), ss_radius, color='b', fill=True, alpha=0.5, linewidth=0.0) ax.add_artist(circle) arm_colors = ['y', 'g', 'r'] for i in range(num_super_stations_arms): q = int(i / core_arm_count) circle = pyplot.Circle((v4d_ss_x_arms[i], v4d_ss_y_arms[i]), ss_radius, color=arm_colors[q], fill=True, alpha=0.5, linewidth=0.0) ax.add_artist(circle) for q in range(num_arms): i0 = q * outer_arm_count i1 = i0 + outer_arm_count for i in range(i0, i1): circle = pyplot.Circle((v4d_ss_x_outer[i], v4d_ss_y_outer[i]), ss_radius, color='c', fill=True, alpha=0.5) ax.add_artist(circle) # Plot station positions for i in range(v4d_st_x.shape[0]): circle = pyplot.Circle((v4d_st_x[i], v4d_st_y[i]), st_radius, color='k', linewidth=1.0, fill=True, alpha=0.2) ax.add_artist(circle) # circle = pyplot.Circle((0.0, 0.0), 1700.0, color='r', linestyle='--', # linewidth=1.0, fill=False, alpha=0.5) # ax.add_artist(circle) ax.grid(which='both') ax.grid(which='minor', alpha=0.5) ax.grid(which='major', alpha=1.0) ax.set_ylabel('North [m]') ax.set_xlabel('East [m]') ax.set_xlim(-1500, 1500) ax.set_ylim(-1500, 1500) pyplot.savefig(join(out_dir, 'v4d_station_layout_zoom_1.5km.png')) ax.set_xlim(-3000, 3000) ax.set_ylim(-3000, 3000) pyplot.savefig(join(out_dir, 'v4d_station_layout_zoom_3.0km.png')) ax.set_xlim(-5000, 5000) ax.set_ylim(-5000, 5000) pyplot.savefig(join(out_dir, 'v4d_station_layout_zoom_5.0km.png')) ax.set_xlim(-50000, 50000) ax.set_ylim(-50000, 50000) pyplot.savefig(join(out_dir, 'v4d_station_layout_50.0km.png')) pyplot.close(fig) if uvwsim_found: # TODO-BM make this a function in layout_utils.py print('generating uv coords...') x = v4d_st_x y = v4d_st_y num_stations = x.shape[0] z = numpy.zeros_like(x) lon = radians(116.63128900) lat = radians(-26.69702400) alt = 0.0 ra = radians(68.698903779331502) dec = radians(-26.568851215532160) mjd_mid = 57443.4375000000 obs_length = 4.0 * 3600.0 # seconds num_times = int(obs_length / (3 * 60.0)) # print('num_times =', num_times) dt_s = obs_length / float(num_times) mjd_start = mjd_mid - (obs_length / 2.0) / (3600.0 * 24.0) mjd_start = mjd_mid obs_length = 0.0 dt_s = 0.0 num_times = 1 num_baselines = num_stations * (num_stations - 1) / 2 x, y, z = convert_enu_to_ecef(x, y, z, lon, lat, alt) uu, vv, ww = generate_baseline_uvw(x, y, z, ra, dec, num_times, num_baselines, mjd_start, dt_s) layout_utils.plot_hist(uu, vv, join(out_dir, 'v4d_hist.png'), 'v4d snapshot-uv') layout_utils.plot_uv_dist(uu, vv, st_radius, join(out_dir, 'v4d_snapshot_uv_zenith')) layout_utils.plot_uv_grid_image(uu, vv, 5.0, join(out_dir, 'uv_image'))
def main(): """ 1. Generate a large-ish core of stations using random generator. a. overlap some stations in the core to have a very dense station region 2. After core area start using arms but generate some randomness in the arms by placing antennas randomly near the outer stations keeping them along the spiral 3. Remove radius redundancy in the spiral arms """ # ========================================================================= # ====== Core seed = 1 num_tries = 10 num_core_stations = (1 + 5 + 11 + 17) * 6 + (3 * 6) core_radius_m = 480.0 inner_core_radius_m = 280.0 station_radius_m = 35.0 / 2.0 sll = -28 # ====== Core arms num_arms = 3 core_arm_count = 4 stations_per_arm_cluster = 6 arm_cluster_radius = 75.0 # a = 300.0 # b = 0.513 a = 300.0 b = 0.513 delta_theta = math.radians(37.0) arm_offsets = numpy.radians([35.0, 155.0, 270.0]) a2 = 500.0 b2 = 0.513 delta_theta2 = math.radians(12.0) arm_offsets2 = numpy.radians([35.0, 155.0, 270.0]) num_core_arm_stations = num_arms * core_arm_count * stations_per_arm_cluster # ====== Outer arms outer_arm_count = 12 stations_per_outer_cluster = 6 num_clusters_outer = outer_arm_count * num_arms v4a_ss_enu_file = 'v7ska1lowN1v2rev3R.enu.94x4.fixed.txt' outer_arm_cluster_radius = 80.0 # ===== uvw coordinate generation. lon = radians(116.63128900) lat = radians(-26.69702400) alt = 0.0 ra = radians(68.698903779331502) dec = radians(-26.568851215532160) mjd_mid = 57443.4375000000 # obs_length = 0.0 # mjd_start = mjd_mid # dt_s = 0.0 # num_times = 1 obs_length = 2.0 * 3600.0 # seconds num_times = int(obs_length / (3.0 * 60.0)) dt_s = obs_length / float(num_times) mjd_start = mjd_mid - ((obs_length / 2.0) / 3600.0 * 24.0) print('num times = %i' % num_times) out_dir = 'v5d-2h' # ========================================================================= if not os.path.isdir(out_dir): os.makedirs(out_dir) # Generate core stations x_core, y_core, weights, r_weights = \ generate_random_core(num_core_stations, core_radius_m, inner_core_radius_m, sll, station_radius_m, num_tries, seed) # Core arms x_arm, y_arm, cx_arm, cy_arm = \ generate_core_arms(num_arms, core_arm_count, stations_per_arm_cluster, arm_cluster_radius, station_radius_m, a, b, delta_theta, arm_offsets, num_tries) # Core arms x_arm_2, y_arm_2, cx_arm_2, cy_arm_2 = \ generate_core_arms_2(num_arms, core_arm_count, stations_per_arm_cluster, arm_cluster_radius, station_radius_m, a2, b2, delta_theta2, arm_offsets2, num_tries) # Outer stations. x_arm_outer, y_arm_outer, cx_outer, cy_outer = \ generate_outer_arms(v4a_ss_enu_file, num_clusters_outer, stations_per_outer_cluster, outer_arm_cluster_radius, station_radius_m, num_tries) # Plotting plot_layout(x_core, y_core, x_arm, y_arm, x_arm_2, y_arm_2, x_arm_outer, y_arm_outer, cx_arm, cy_arm, cx_arm_2, cy_arm_2, cx_outer, cy_outer, station_radius_m, inner_core_radius_m, core_radius_m, arm_cluster_radius, outer_arm_cluster_radius, out_dir) plot_core_thinning_profile(r_weights, weights, core_radius_m, inner_core_radius_m, out_dir) if uvwsim_found: x = numpy.hstack((x_core, x_arm_2, x_arm_outer)) y = numpy.hstack((y_core, y_arm_2, y_arm_outer)) print('total stations = %i' % x.shape[0]) num_stations = x.shape[0] z = numpy.zeros_like(x) num_baselines = num_stations * (num_stations - 1) / 2 x, y, z = convert_enu_to_ecef(x, y, z, lon, lat, alt) uu, vv, ww = generate_baseline_uvw(x, y, z, ra, dec, num_times, num_baselines, mjd_start, dt_s) plot_hist(uu, vv, join(out_dir, 'uv_hist_%.2fh.png' % (obs_length/3600.0)), 'v5d %.2f h' % (obs_length/3600.0)) plot_uv_dist(uu, vv, station_radius_m, join(out_dir, 'uv_%.2fh' % (obs_length/3600.0))) plot_uv_grid_image(uu, vv, 5.0, join(out_dir, 'uv_image')) # TODO-BM see ALMA memo for plots? # TODO-BM Plot of azimuthal variation # TODO-BM movie of uv coverage histogram improvement with time? # TODO-BM convolve uv response with station beam?! print('making image...') imager = Imager('single') fov = 1.0 im_size = 2048 freq = 150.0e6 wavelength = 299792458.0 / freq uu /= wavelength vv /= wavelength ww /= wavelength amp = numpy.ones(uu.shape, dtype='c16') weight = numpy.ones(uu.shape, dtype='f8') image = imager.make_image(uu, vv, ww, amp, weight, fov, im_size) fig = pyplot.figure(figsize=(8, 8)) ax = fig.add_subplot(111, aspect='equal') ax.imshow(image, interpolation='nearest') pyplot.show() cell = math.degrees(imager.fov_to_cellsize(math.radians(fov), im_size)) save_fits_image_2(join(out_dir, 'psf.fits'), image, cell, math.degrees(ra), math.degrees(dec), freq)