def rot_sweep_data(interface, freq, step, a_range, pol_in): """ Returns the I, Q, U and V over a rotation of 2pi. """ I=np.array([]) Q=np.array([]) U=np.array([]) V=np.array([]) a_range=unitize_a(a_range) f = unitize_f(freq) interface.build(f) radstep = unitize_a(step) angle_range = np.arange(0, a_range, radstep) for angle in angle_range: # Rotating the input polarization rather than rebuilding the interface # at each rotation gives a factor of 2 improvement in performance. rot_pol = pol_in.rot(angle) pol_out = (interface*rot_pol).rot(-angle) I = np.append(I, pol_out.I) Q = np.append(Q, pol_out.Q) U = np.append(U, pol_out.U) V = np.append(V, pol_out.V) return (I, Q, U, V)
def rot_sweep_data(interface, freq, step, a_range, pol_in): """ Returns the I, Q, U and V over a rotation of 2pi. """ I = np.array([]) Q = np.array([]) U = np.array([]) V = np.array([]) a_range = unitize_a(a_range) f = unitize_f(freq) interface.build(f) radstep = unitize_a(step) angle_range = np.arange(0, a_range, radstep) for angle in angle_range: # Rotating the input polarization rather than rebuilding the interface # at each rotation gives a factor of 2 improvement in performance. rot_pol = pol_in.rot(angle) pol_out = (interface * rot_pol).rot(-angle) I = np.append(I, pol_out.I) Q = np.append(Q, pol_out.Q) U = np.append(U, pol_out.U) V = np.append(V, pol_out.V) return (I, Q, U, V)
def contrived_ahwp_mod(f_range, n1, n2, d): a_range = np.arange(0, pi / 2, unitize_a("1deg")) d = unitize_d(d) center_angle = unitize_a("58deg") mods = [] for f in f_range: mueller = mueller_wp((n2 - n1) * 2 * pi * f * d / c) I = np.array([]) Q = np.array([]) for a in a_range: s = StokesVector(1, 1, 0, 0) v = mueller.dot(np.array([s.rot(a).vect]).reshape([4, 1])).reshape([ 4, ]) s = StokesVector(*v) v = mueller.dot( np.array([s.rot(center_angle).vect]).reshape([4, 1])).reshape([ 4, ]) s = StokesVector(*v) v = mueller.dot( np.array([s.rot(-center_angle).vect]).reshape([4, 1])).reshape([ 4, ]) s = StokesVector(*v).rot(-a) Q = np.append(Q, s.Q) mods.append((max(1 + Q) - min(1 + Q)) / 2) return mods
def rot_sweep(interface, freq, pol_in, step='1 deg'): """ Plots the output Q and U vs rotation angle given an input polarization vector. The output is normalized by the input intensity. The interface must be built before calling this sweep. """ I, Q, U, V = rot_sweep_data(interface, freq, step=step, pol_in=pol_in) sin_to_fit = lambda x, phase: np.sin(phase + 4*x) radstep = unitize_a(step) angle_range = np.arange(0, 2*pi, radstep) phase_fit = curve_fit(sin_to_fit, angle_range, Q) sin_fit = np.sin(4*angle_range+phase_fit[0]) diff = np.sum((Q-sin_fit)**2)*radstep/(2*pi) print "Power difference: {}".format(diff) print "Minimum transmission: {}".format(min(I)) plt.plot(angle_range, Q, label="Q") plt.plot(angle_range, U, label="U") plt.plot(angle_range, I, label="I") plt.plot(angle_range, V, label="V") plt.plot(angle_range, sin_fit, label="Fit") plt.xlabel("Angle (radians)") plt.ylabel("Normalized Transmission") plt.ylim(ymax=1) plt.legend() plt.show()
def contrived_ahwp_cross(f_range, n1, n2, d, angle): d = unitize_d(d) center_angle = unitize_a("58deg") out_angles = [] for f in f_range: mueller = mueller_wp((n2 - n1) * 2 * pi * f * d / c) p = [] s = StokesVector(1, 1, 0, 0) v = mueller.dot(np.array([s.rot(angle).vect]).reshape([4, 1])).reshape([ 4, ]) s = StokesVector(*v) v = mueller.dot(np.array([s.rot(center_angle).vect ]).reshape([4, 1])).reshape([ 4, ]) s = StokesVector(*v) v = mueller.dot(np.array([s.rot(-center_angle).vect ]).reshape([4, 1])).reshape([ 4, ]) s = StokesVector(*v) a = s.rot(-angle).pol_angle a = (a + pi) % (pi) out_angles.append(a) return out_angles
def cross_pol(interface, fvals, astep="1deg"): """ Calculates and plots the cross polarization vs angle for a number of freqs. """ f_vals = map(unitize_f, fvals) divisor, frq_range = frange(min(f_vals), max(f_vals)) radstep = unitize_a(astep) angle_range = np.arange(0, pi / 2, radstep) deg_range = map(deg, angle_range) data = mpexec(rot_sweep_data, "freq", f_vals, interface=interface, a_range=pi / 2, step=astep, pol_in=StokesVector(1, 1, 0, 0), globals=globals()) for i, f in enumerate(f_vals): I, Q, U, V = data[i] plt.plot(deg_range, U, label="{}{}".format(int(f / divisor), frq_range)) plt.xlabel("Angle (degrees)") plt.ylabel("Cross Polarization") plt.ylim(ymin=-1, ymax=1) plt.legend() plt.show()
def rot_sweep(interface, freq, pol_in, step='1 deg'): """ Plots the output Q and U vs rotation angle given an input polarization vector. The output is normalized by the input intensity. The interface must be built before calling this sweep. """ I, Q, U, V = rot_sweep_data(interface, freq, step=step, pol_in=pol_in) sin_to_fit = lambda x, phase: np.sin(phase + 4 * x) radstep = unitize_a(step) angle_range = np.arange(0, 2 * pi, radstep) phase_fit = curve_fit(sin_to_fit, angle_range, Q) sin_fit = np.sin(4 * angle_range + phase_fit[0]) diff = np.sum((Q - sin_fit)**2) * radstep / (2 * pi) print "Power difference: {}".format(diff) print "Minimum transmission: {}".format(min(I)) plt.plot(angle_range, Q, label="Q") plt.plot(angle_range, U, label="U") plt.plot(angle_range, I, label="I") plt.plot(angle_range, V, label="V") plt.plot(angle_range, sin_fit, label="Fit") plt.xlabel("Angle (radians)") plt.ylabel("Normalized Transmission") plt.ylim(ymax=1) plt.legend() plt.show()
def phase_vs_freq(interface, fstart, fstop, fstep="1GHz"): """ Plot polarization rotation phase vs frequency for a given interface. """ sin_to_fit = lambda x, a, phase: a*np.sin(phase + 4*x) pol_in = StokesVector(1,1,0,0) fstart = unitize_f(fstart) fstop = unitize_f(fstop) fstep = unitize_f(fstep) f_range = np.arange(fstart, fstop, fstep) divisor, frq_range = frange(fstart, fstop) radstep = unitize_a("1deg") angle_range = np.arange(0, pi/2, radstep) data = np.array(mpexec(rot_sweep_data, "freq", f_range, interface=interface, step="1deg", a_range=pi/2, pol_in=pol_in, globals=globals())) pol = [] phase = [] print "starting fit" for i, f in enumerate(f_range): # Get Q vs angle, indexed by frequency pol.append(data[i,1]) phase_fit = curve_fit(sin_to_fit, angle_range, pol[i]) phase.append(phase_fit[0][1]) min_phase = min(phase) phase -= min_phase dphase = map(deg, phase) plt.plot(f_range/divisor, dphase) plt.xlabel("Frequency ({})".format(frq_range)) plt.ylabel("Phase angle (deg)") plt.show()
def __init__(self, eps=1, thickness=-1, eps2=-1, angle=0): if eps2 == -1: eps2 = eps self.eps2 = eps2 self.angle = unitize_a(angle) if (thickness==-1): # If no thickness is specified, choose a sane default self.thickness = c/(4*CENTRAL_FREQ*sqrt(eps)) else: self.thickness = unitize_d(thickness) self.eps = eps
def contrived_ahwp_mod(f_range,n1,n2,d): a_range = np.arange(0, pi/2, unitize_a("1deg")) d=unitize_d(d) center_angle = unitize_a("58deg") mods = [] for f in f_range: mueller = mueller_wp((n2-n1)*2*pi*f*d/c) I = np.array([]) Q = np.array([]) for a in a_range: s = StokesVector(1,1,0,0) v = mueller.dot(np.array([s.rot(a).vect]).reshape([4,1])).reshape([4,]) s = StokesVector(*v) v = mueller.dot(np.array([s.rot(center_angle).vect]).reshape([4,1])).reshape([4,]) s = StokesVector(*v) v = mueller.dot(np.array([s.rot(-center_angle).vect]).reshape([4,1])).reshape([4,]) s = StokesVector(*v).rot(-a) Q = np.append(Q,s.Q) mods.append((max(1+Q)-min(1+Q))/2) return mods
def rot(self, angle): """Return rotated copy of self.""" rad = unitize_a(angle) x_to_rot_x = self.v_x.amp*cos(rad) x_to_rot_y = -self.v_x.amp*sin(rad) y_to_rot_x = self.v_y.amp*sin(rad) y_to_rot_y = self.v_y.amp*cos(rad) new_x = PolarizationVector(x_to_rot_x, self.v_x.phase) + \ PolarizationVector(y_to_rot_x, self.v_y.phase) new_y = PolarizationVector(x_to_rot_y, self.v_x.phase) + \ PolarizationVector(y_to_rot_y, self.v_y.phase) return PolarizationTwoVector(new_x, new_y)
def contrived_cross_sweep(fstart, fstop, fstep, n1, n2, d): d = unitize_d(d) fstart = unitize_f(fstart) fstop = unitize_f(fstop) fstep = unitize_f(fstep) divisor, frq_range = frange(fstart, fstop) arange = np.arange(0, pi / 2, unitize_a("15deg")) f_range = np.arange(fstart, fstop, fstep) for angle in arange: angles = contrived_ahwp_cross(f_range, n1, n2, d, angle) label = "AHWP Angle: {0:.2f}".format(angle) plt.plot(f_range, angles, label=label) plt.xlabel("Frequency (" + frq_range + ")") plt.ylabel("Polarization Angle") plt.ylim(ymin=0, ymax=pi) plt.legend() plt.show()
def contrived_cross_sweep(fstart, fstop, fstep, n1, n2, d): d = unitize_d(d) fstart = unitize_f(fstart) fstop = unitize_f(fstop) fstep = unitize_f(fstep) divisor, frq_range = frange(fstart,fstop) arange = np.arange(0, pi/2, unitize_a("15deg")) f_range = np.arange(fstart, fstop, fstep) for angle in arange: angles = contrived_ahwp_cross(f_range, n1, n2, d, angle) label = "AHWP Angle: {0:.2f}".format(angle) plt.plot(f_range, angles, label=label) plt.xlabel("Frequency ("+frq_range+")") plt.ylabel("Polarization Angle") plt.ylim(ymin=0, ymax=pi) plt.legend() plt.show()
def contrived_ahwp_cross(f_range, n1, n2, d, angle): d=unitize_d(d) center_angle = unitize_a("58deg") out_angles = [] for f in f_range: mueller = mueller_wp((n2-n1)*2*pi*f*d/c) p = [] s = StokesVector(1,1,0,0) v = mueller.dot(np.array([s.rot(angle).vect]).reshape([4,1])).reshape([4,]) s = StokesVector(*v) v = mueller.dot(np.array([s.rot(center_angle).vect]).reshape([4,1])).reshape([4,]) s = StokesVector(*v) v = mueller.dot(np.array([s.rot(-center_angle).vect]).reshape([4,1])).reshape([4,]) s = StokesVector(*v) a = s.rot(-angle).pol_angle a = (a+pi)%(pi) out_angles.append(a) return out_angles
def phase_vs_freq(interface, fstart, fstop, fstep="1GHz"): """ Plot polarization rotation phase vs frequency for a given interface. """ sin_to_fit = lambda x, a, phase: a * np.sin(phase + 4 * x) pol_in = StokesVector(1, 1, 0, 0) fstart = unitize_f(fstart) fstop = unitize_f(fstop) fstep = unitize_f(fstep) f_range = np.arange(fstart, fstop, fstep) divisor, frq_range = frange(fstart, fstop) radstep = unitize_a("1deg") angle_range = np.arange(0, pi / 2, radstep) data = np.array( mpexec(rot_sweep_data, "freq", f_range, interface=interface, step="1deg", a_range=pi / 2, pol_in=pol_in, globals=globals())) pol = [] phase = [] print "starting fit" for i, f in enumerate(f_range): # Get Q vs angle, indexed by frequency pol.append(data[i, 1]) phase_fit = curve_fit(sin_to_fit, angle_range, pol[i]) phase.append(phase_fit[0][1]) min_phase = min(phase) phase -= min_phase dphase = map(deg, phase) plt.plot(f_range / divisor, dphase) plt.xlabel("Frequency ({})".format(frq_range)) plt.ylabel("Phase angle (deg)") plt.show()
def cross_pol(interface, fvals, astep="1deg"): """ Calculates and plots the cross polarization vs angle for a number of freqs. """ f_vals = map(unitize_f,fvals) divisor, frq_range = frange(min(f_vals), max(f_vals)) radstep = unitize_a(astep) angle_range = np.arange(0, pi/2, radstep) deg_range = map(deg, angle_range) data = mpexec(rot_sweep_data, "freq", f_vals, interface=interface, a_range=pi/2, step=astep, pol_in=StokesVector(1,1,0,0), globals=globals()) for i, f in enumerate(f_vals): I,Q,U,V = data[i] plt.plot(deg_range, U, label="{}{}".format(int(f/divisor), frq_range)) plt.xlabel("Angle (degrees)") plt.ylabel("Cross Polarization") plt.ylim(ymin=-1,ymax=1) plt.legend() plt.show()
def __call__(self, angle): """ Return a copy of self, but rotated by the given angle. """ theta = unitize_a(angle) return Layer(self.eps, self.thickness, self.eps2, self.angle+theta)