def power_parameters(fname, ant1, ant2): fcd, fs, ts, ptitle = load_wedge_sim(fname + ".pickle") print("Simulation file loaded.\n") num_f = len(fs) B = fs.max() - fs.min() etas = pol.f2etas(fs) #z_avg = pol.fq2z(np.average(fs) / 1e9) #k_para = pol.k_parallel(etas, z_avg) k_para = np.array([ pol.k_parallel(etas[i], pol.fq2z(fs[i] / 1e9)) \ for i in range(num_f) ]) #print(k_par) """ Power constants, section 1""" kB = 1.380649e-26 # this is in mK. # To use K, add 3 orders of magnitude. # 1 Jy = 1e-20 J / km^2 / s^2 square_Jy = (1e-20)**2 universal_p_coeff = square_Jy / (2 * kB)**2 / B """ """ baselength = sf.ant.baselength(ant1, ant2) power_pieces = { 'z': [], # dimensionless 'lambda': [], # m 'D': [], # m? 'DeltaD': [], 'kperp': [] } for nu in fs: #nu = np.average(fs) """ Power constants, section 2 """ z = pol.fq2z(nu / 1e9) power_pieces['z'].append(z) lambda_ = pol.C / nu power_pieces['lambda'].append(lambda_) D = pol.transverse_comoving_distance(z) power_pieces['D'].append(D) DeltaD = pol.comoving_depth(B, z) power_pieces['DeltaD'].append(DeltaD) k_perp = baselength * pol.k_perp(z) / lambda_ power_pieces['kperp'].append(k_perp) for key in power_pieces.keys(): power_pieces[key] = np.array(power_pieces[key]) power_pieces['fs'] = fs return power_pieces
def micro_wedge(h1, f1, b1, h2, f2, b2, h3, f3, b3): """ The axes do not line up with Nunhokee et al. Probably something wrong with your constants or usage thereof. """ center_f1 = np.average(f1) z1 = pol.fq2z(center_f1) lambda1 = pol.C / center_f1 k_par1 = pol.k_parallel(h1[:, 0], z1) k_orth1 = pol.k_perp(z1) / lambda1 * b1 center_f2 = np.average(f2) z2 = pol.fq2z(center_f2) lambda2 = pol.C / center_f2 k_par2 = pol.k_parallel(h2[:, 0], z2) k_orth2 = pol.k_perp(z2) / lambda2 * b2 center_f3 = np.average(f3) z3 = pol.fq2z(center_f3) lambda3 = pol.C / center_f3 k_par3 = pol.k_parallel(h3[:, 0], z3) k_orth3 = pol.k_perp(z3) / lambda3 * b3 y = np.concatenate((k_par1, k_par2, k_par3)) x = np.concatenate( (np.repeat(k_orth1, len(k_par1)), np.repeat(k_orth2, len(k_par2)), np.repeat(k_orth3, len(k_par3)))) colors = np.concatenate((h1[:, 2], h2[:, 2], h3[:, 2])) plt.title("Helix concatenation") #print("Minimum:", z.min()) #print("PTP:", z.ptp()) plt.scatter(x, y, marker='.', c=colors) plt.colorbar() plt.show()
def collect_wedge_points(fcd, fs, ts, rAnt1, rAnt2): """ out of context """ num_t = len(ts) num_f = len(fs) B = fs.max() - fs.min() visual = [] etas = pol.f2etas(fs) k_para = np.array([ pol.k_parallel(etas[i], pol.fq2z(fs[i] / 1e9)) \ for i in range(num_f) ]) max_counts = [0, 0, 0, 0] hmax_counts = [0, 0, 0, 0] for ant1 in fcd.keys(): for ant2 in fcd[ant1].keys(): if rAnt1 is not None and rAnt1 != ant1: continue if rAnt2 is not None and rAnt2 != ant2: continue baselength = sf.ant.baselength(ant1, ant2) for nu_idx in range(num_f): nua = np.average(fs) nu = fs[nu_idx] z = pol.fq2z(nu / 1e9) lambda_ = pol.C / nu k_perp = baselength * pol.k_perp(z) / lambda_ for t_idx in range(num_t - 1): this_instant = \ fcd[ant1][ant2][:, t_idx, nu_idx] # [I1, Q1, U1, V1] * [I2*, Q2*, U2*, V2*] this_test = np.array([ np.abs(S) for S in this_instant ]) for i in range(len(this_test)): if this_test[i] == this_test.max(): max_counts[i] += 1 next_instant = \ fcd[ant1][ant2][:, t_idx + 1, nu_idx] # [I1, Q1, U1, V1] * [I2*, Q2*, U2*, V2*] hadamard = np.multiply( this_instant, next_instant ) htest = np.array([ np.abs(S) for S in hadamard ]) for i in range(len(htest)): if htest[i] == htest.max(): hmax_counts[i] += 1 print(max_counts) print(hmax_counts)
def plot_3D(visual, fs, title, scaled=False): """ Primitive 3D plotter. For use with the return value of either static_wedge_vis or dynamic_wedge_vis Disable @scaled if you are using values such as logarithms """ x = visual[:, 0] y = visual[:, 1] z = visual[:, 2] colors = None if (scaled): scaled_z = (z - z.min()) / z.ptp() colors = plt.cm.viridis(scaled_z) else: colors = z print("Minimum:", z.min()) print("PTP:", z.ptp()) image = visual_to_image(visual) ### horizon-code center_f = np.average(fs) z = pol.fq2z(center_f / 1e9) lambda_ = pol.C / center_f k_starter = pol.k_perp(z) / lambda_ horizonx = np.unique(visual[:, 0]) horizonyp = [] horizonym = [] etas = pol.f2etas(fs) k_par = pol.k_parallel(etas, z) for i in range(len(horizonx)): k_orthogonal = horizonx[i] horizonyp.append(pol.horizon_limit(k_orthogonal, z)) horizonym.append(-pol.horizon_limit(k_orthogonal, z)) plt.scatter(horizonx, horizonyp, marker='.', c='w') plt.scatter(horizonx, horizonym, marker='.', c='w') ### end horizon-code # Interpolation choice doesn't really matter; # gaussian looks smooth print(image.shape, "shape") plt.imshow(image.T, extent=[x.min(), x.max(), y.min(), y.max()], interpolation='gaussian', aspect='auto') finalize_plot(title) plt.scatter(x, y, marker='.', c=colors) finalize_plot(title) return x, y, visual, image
def collect_wedge_points(fcd, fs, ts, Qi, sp=None, special_request=None): """ Read from the wedge data structure @sim_dict (specifically, one using the format established in load_wedge_sim) and generate 3D points appropriate for a wedge plot. i.e., return a list of triples: (k_perpendicular, k_parallel, power*) * currently, the implementation uses values that should be proportional to power. The final constants have not yet been considered. This function is distinct from static_wedge_vis in accepting multiple LST values from @sim_dict. @sp : Stokes parameter, if you want to look at just one at a time 0 : I 1 : Q 2 : U 3 : V @special_request: tuple of (baseline1, baseline2, to really complete the Nunhokee parallel, you would want to average over a range of k_orth values TODO: last updated 3/30 # we need the horizon line: white dots # Fix amplitudes? # Create separate plots for I, Q, U, V # Create slices after the fashion of Nunhokee fig 6 # make some notes for HERA team circulation """ num_t = len(ts) num_f = len(fs) B = fs.max() - fs.min() visual = [] #print(fs) etas = pol.f2etas(fs) #z_avg = pol.fq2z(np.average(fs) / 1e9) #k_para = pol.k_parallel(etas, z_avg) k_para = np.array([ pol.k_parallel(etas[i], pol.fq2z(fs[i] / 1e9)) \ for i in range(num_f) ]) #print(k_par) """ Power constants, section 1""" kB = 1.380649e-26 # this is in mK. # To use K, add 3 orders of magnitude. # 1 Jy = 1e-20 J / km^2 / s^2 square_Jy = (1e-20)**2 universal_p_coeff = square_Jy / (2 * kB)**2 / B """ """ for ant1 in fcd.keys(): for ant2 in fcd[ant1].keys(): if special_request is not None: if ant1 != special_request[0] or \ ant2 != special_request[1]: continue baselength = sf.ant.baselength(ant1, ant2) special = [[], [], [], []] for nu_idx in range(num_f): nua = np.average(fs) nu = fs[nu_idx] """ Power constants, section 2 """ # using these causes problems z = pol.fq2z(nu / 1e9) lambda_ = pol.C / nu # less accurate, but doesn't kill the graph # what gives? z_a = pol.fq2z(nua / 1e9) lambda_a = pol.C / nua D = pol.transverse_comoving_distance(z_a) DeltaD = pol.comoving_depth(B, z_a) # Finally, condense everything into a # power coefficient p_coeff = universal_p_coeff * \ lambda_a ** 4 * D ** 2 * DeltaD """ """ k_perp = baselength * pol.k_perp(z_a) / lambda_a powers_prop = [] # store power results by Stokes index: special_powers = [[], [], [], []] # store normalized Hadamard vectors: special_times = [] for t_idx in range(num_t - 1): this_instant = \ fcd[ant1][ant2][:, t_idx, nu_idx] next_instant = \ fcd[ant1][ant2][:, t_idx + 1, nu_idx] # [I1, Q1, U1, V1] * [I2*, Q2*, U2*, V2*] hadamard = np.multiply(this_instant, next_instant) p = np.dot(Qi, hadamard) # if no Stokes parameter is specified, # we take the absolute value of the # entire Stokes visibility vector if sp is None: sqBr = np.abs(p) else: sqBr = np.abs(p[sp]) powers_prop.append(sqBr) # we leave the normalized Hadamard # products for the cross-section # code to handle special_times.append(p) if special_request is not None: for vector in np.array(special_times): # si: Stokes index for si in range(len(vector)): # take the magnitude of each # normalized Hadamard index param = np.abs(vector[si]) # and count it as a power special_powers[si].append(param) avg = p_coeff * np.average(np.array(powers_prop)) #print("Using k_parallel", k_par[nu_idx]) wedge_datum = np.array([ k_perp, k_para[nu_idx], #float(avg) float(np.log10(avg)) ]) if special_request is not None: for si in range(len(special_powers)): special_powers[si] = np.array(special_powers[si]) special_powers = np.array(special_powers) #print("Using k_parallel", k_par[nu_idx]) # si: Stokes index for si in range(len(special_powers)): stokes_param = special_powers[si] avg = p_coeff * np.average(stokes_param) #!!! duplicate reference special[si].append( np.array([ k_para[nu_idx], #float(avg) float(np.log10(avg)) ])) visual.append(wedge_datum) # Figure 6-esque investigation if special_request is not None: if ant1 == special_request[0] and \ ant2 == special_request[1]: print("Exiting") return np.array(special) visual = np.array(visual) return np.array(visual)
def slicer(ant1, ant2, func_show, Qi=None, fs=np.arange(125e6, 175e6 + 0.001, 1e6), wedge_name="0Fw", ratio_mode=False, deltas=False): """ The second pair of arguments is admittedly disappointing, but I could not figure out how else to write a script like this. """ # sp doesn't matter since the use of the # special_request parameter branches differently special = func_show(wedge_name, Qi=Qi, special_request=(ant1, ant2)) b = ant.baselength(ant1, ant2) #print(special.shape) print("Baseline length [m]:", np.around(b, 4)) center_f = np.average(fs) z = pol.fq2z(center_f / 1e9) lambda_ = pol.C / center_f k_orth = pol.k_perp(z) * b / lambda_ print("Baseline has perpendicular k mode:", np.around(k_orth, 4), "[h / Mpc]") horizonp = pol.horizon_limit(k_orth, z) horizonn = -pol.horizon_limit(k_orth, z) magnitudes = [] # this loop only serves to re-organize the results for stokes_param in special: magnitudes.append([]) i = len(magnitudes) - 1 magnitudes[i].append( np.fft.fftshift(stokes_param[:, 0])) magnitudes[i].append( np.fft.fftshift(stokes_param[:, 1])) magnitudes[i] = np.array(magnitudes[i]) magnitudes = np.array(magnitudes) if ratio_mode: plt.plot( magnitudes[1, 0], 10 ** (magnitudes[1, 1] - magnitudes[0, 1]), label="Q / I" ) plt.plot( magnitudes[2, 0], 10 ** (magnitudes[2, 1] - magnitudes[0, 1]), label="U / I" ) plt.plot( magnitudes[3, 0], 10 ** (magnitudes[3, 1] - magnitudes[0, 1]), label="V / I" ) ### this is pretty bad ymin = 10 ** (magnitudes[1, 1] - magnitudes[0, 1]).min() ymin = min( ymin, 10 ** (magnitudes[2, 1] - magnitudes[0, 1]).min() ) ymin = min( ymin, 10 ** (magnitudes[2, 1] - magnitudes[0, 1]).min() ) ymin = min( ymin, 10 ** (magnitudes[3, 1] - magnitudes[0, 1]).min() ) ymax = magnitudes[0, 1].max() ymax = max( ymin, 10 ** (magnitudes[2, 1] - magnitudes[0, 1]).max() ) ymax = max( ymin, 10 ** (magnitudes[2, 1] - magnitudes[0, 1]).max() ) ymax = max( ymin, 10 ** (magnitudes[3, 1] - magnitudes[0, 1]).max() ) else: if deltas=False: plt.plot(magnitudes[0, 0], magnitudes[0, 1], label="I", color='k') plt.plot(magnitudes[1, 0], magnitudes[1, 1], label="Q", color='b') plt.plot(magnitudes[2, 0], magnitudes[2, 1], label="U", color='orange') plt.plot(magnitudes[3, 0], magnitudes[3, 1], label="V", color='g') else: # k^3 / 2 pi^2, but the problem is that