tqdm.write("χν^2: {}".format( fitobj.rchi2_min)) tqdm.write("Cov:\n{}".format(fitobj.covar)) tqdm.write("\n") sv.save_a_vector(pulseID, fitobj) ###################################### ## PLOT OF CHISQUARE DISTRIBUTION ## ###################################### ϕ = np.linspace(-np.pi, np.pi, Ns) θ = np.linspace(0, np.pi, Ns) level = np.logspace(np.log10(χ2.min()), np.log10(χ2.max()), 30) cmap = gen_olaf_cmap() norm = colors.LogNorm(χ2.min(), χ2.max()) #plot without marginalization #fig = figure(figsize=(20,10)) #frame = fig.add_subplot(111, aspect='equal') #cont = frame.contour(ϕθ[0], ϕθ[1], χ2, level, cmap=cmap, norm=norm) #frame.clabel(cont, level, fontsize=8, colors='k') #frame.plot(*fitobj.params, marker="*", color="k") #frame.set_xlabel(r"$ϕ$", fontsize=16) #frame.set_ylabel(r"$θ$", fontsize=16) #show() ϕ_lims = [-np.pi, np.pi] θ_lims = [np.pi, 0]
def polPlot2D(station_loc, pulses_PE, source_info, ell_scale=2**50, ϕ_shift=False, cmap=None, cmode='time', errors=False, save=False, fig=None, frame=None): if fig is None: fig = figure(figsize=(20,10),dpi=108) #Az : [-90,90] and Z : [0:90] => 2:1 ratio ensures we fill canvas properly frame = fig.add_subplot(111, aspect='equal') #equal aspect ensures correct direction of polarization ellipse! #setting up colormap if cmap is None: cmap = gen_olaf_cmap() T = np.array([]) if cmode == 'time': for pulseID in pulses_PE.keys(): T = np.append(T, source_info[pulseID]['XYZT'][3]) elif cmode == 'dop': for pulseID in pulses_PE.keys(): T = np.append(T, pulses_PE[pulseID][1]) vmin = np.min(T) vmax = np.max(T) T = 1/(vmax-vmin)*(T-vmin) #normalize T for i, pulseID in enumerate(pulses_PE.keys()): loc = source_info[pulseID]['XYZT'][:3] - station_loc Az = np.arctan2(loc[1], loc[0]) Z = np.arctan2(np.dot(loc[:2], loc[:2])**0.5, loc[2]) Az = np.rad2deg(Az); Z = np.rad2deg(Z) #ensures clusterings at +90 and -90 degrees are brought to zero (reducing x scale) if ϕ_shift: if Az<0: Az += 180 elif Az>0: Az -= 180 #compute ellipse parameters width = 2*pulses_PE[pulseID][0]*np.cos(pulses_PE[pulseID][3]) height = 2*pulses_PE[pulseID][0]*np.sin(pulses_PE[pulseID][3]) width *= ell_scale; height *= ell_scale angle = pulses_PE[pulseID][2] #alternative: #width = 2*pulses_PE[pulseID][0]*pulses_PE[pulseID][1]*np.cos(pulses_PE[pulseID][3]) #height = 2*pulses_PE[pulseID][0]*pulses_PE[pulseID][1]*np.sin(pulses_PE[pulseID][3]) #width *= ell_scale; height *= ell_scale #angle = pulses_PE[pulseID][2] if errors: #compute ellipse parameter errors width_err = 2*np.sqrt((np.cos(pulses_PE[pulseID][3])*pulses_PE[pulseID][4])**2 + (pulses_PE[pulseID][0]*np.sin(pulses_PE[pulseID][3])*pulses_PE[pulseID][7])**2) height_err = 2*np.sqrt((np.sin(pulses_PE[pulseID][3])*pulses_PE[pulseID][4])**2 + (pulses_PE[pulseID][0]*np.cos(pulses_PE[pulseID][3])*pulses_PE[pulseID][7])**2) width_err *= ell_scale; height_err *= ell_scale angle_err = pulses_PE[pulseID][6] #alternative: #width_err = 2*np.sqrt((pulses_PE[pulseID][1]*np.cos(pulses_PE[pulseID][3])*pulses_PE[pulseID][4])**2 + (pulses_PE[pulseID][0]*pulses_PE[pulseID][1]*np.sin(pulses_PE[pulseID][3])*pulses_PE[pulseID][7])**2 + (pulses_PE[pulseID][0]*np.cos(pulses_PE[pulseID][3])*pulses_PE[pulseID][5])**2) #height_err = 2*np.sqrt((pulses_PE[pulseID][1]*np.sin(pulses_PE[pulseID][3])*pulses_PE[pulseID][4])**2 + (pulses_PE[pulseID][0]*pulses_PE[pulseID][1]*np.cos(pulses_PE[pulseID][3])*pulses_PE[pulseID][7])**2 + (pulses_PE[pulseID][0]*np.sin(pulses_PE[pulseID][3])*pulses_PE[pulseID][5])**2) #width_err *= ell_scale; height_err *= ell_scale #angle_err = pulses_PE[pulseID][6] #compute error in position covXYZ = source_info[pulseID]['covXYZ'] rsq = np.dot(loc[:2],loc[:2]) #dϕ/dx part_Az_x = -loc[1]/rsq #dϕ/dy part_Az_y = loc[0]/rsq ρsq = np.dot(loc,loc) #dθ_z/dx part_Z_x = 1/ρsq*loc[0]*loc[2]/np.sqrt(rsq) #dθ_z/dy part_Z_y = 1/ρsq*loc[1]*loc[2]/np.sqrt(rsq) #dθ_z/dz part_Z_z = -np.sqrt(rsq)/ρsq pos_cov = np.array([[0,0],[0,0]]) pos_cov[0][0] = (part_Az_x*covXYZ[0][0])**2 + (part_Az_y*covXYZ[1][1])**2 + part_Az_x*part_Az_y*covXYZ[0][1] + part_Az_x*part_Az_y*covXYZ[1][0] pos_cov[0][1] = part_Az_x*part_Z_x*covXYZ[0][0] + part_Az_y*part_Z_y*covXYZ[1][1] + part_Az_x*part_Z_y*covXYZ[0][1] + part_Az_x*part_Z_y*covXYZ[1][0] + part_Az_y*part_Z_x*covXYZ[0][1] + part_Az_y*part_Z_x*covXYZ[1][0] + part_Az_x*part_Z_z*covXYZ[0][2] + part_Az_x*part_Z_z*covXYZ[2][0] + part_Az_y*part_Z_z*covXYZ[0][2] + part_Az_y*part_Z_z*covXYZ[2][0] pos_cov[1][0] = pos_cov[0][1] pos_cov[1][1] = (part_Z_x*covXYZ[0][0])**2 + (part_Z_y*covXYZ[1][1])**2 + (part_Z_z*covXYZ[2][2])**2 + part_Z_x*part_Z_y*covXYZ[0][1] + part_Z_x*part_Z_y*covXYZ[1][0] + part_Z_x*part_Z_z*covXYZ[0][2] + part_Z_x*part_Z_z*covXYZ[2][0] + part_Z_y*part_Z_z*covXYZ[1][2] + part_Z_y*part_Z_z*covXYZ[2][1] #compute ellipse parametrization r, r_err = Ellipse((Az,Z), width, height,angle, pos_cov=pos_cov, width_err=width_err, height_err=height_err, angle_err=angle_err) #plot the ellipses with errorbars frame.errorbar(r[0], r[1], xerr=r_err[0], yerr=r_err[1], color=cmap(T[i]), linewidth=0.75, alpha=0.5, capsize=2, capthick=0.25, elinewidth=0.5, ecolor='k') #plot the pulses frame.errorbar(Az, Z, xerr=pos_cov[0][0], yerr=pos_cov[1][1], markersize=1, marker='s', color=cmap(T[i]), alpha=0.75, capsize=2, capthick=0.25, elinewidth=0.5, ecolor='k') else: #compute ellipse parametrization x, y = Ellipse((Az,Z),width,height,angle) #plot the ellipses frame.plot(x, y, color=cmap(T[i]), linewidth=0.75, alpha=0.75) #plot the pulses frame.scatter(Az, Z, s=4, marker='s', edgecolor='k', linewidths=0.4, color=cmap(T[i]), alpha=0.75) #flip zenithal axis such that overhead it actually up! ylimits = frame.get_ylim() frame.set_ylim((ylimits[1],ylimits[0])) #flip azimuthal axis such that left and right is actually left and right from the station's perspective xlimits = frame.get_xlim() frame.set_xlim((xlimits[1],xlimits[0])) #setting up colorbar divider = make_axes_locatable(frame) cax = divider.append_axes("right", size="3%", pad=0.03) if cmode == 'time': norm = mpl.colors.Normalize(vmin=vmin*1000, vmax=vmax*1000) #set time in ms cbar = fig.colorbar(mpl.cm.ScalarMappable(norm=norm, cmap=cmap), cax=cax) cbar.set_label(label=r"$t\ [ms]$",fontsize=16) elif cmode == 'dop': norm = mpl.colors.Normalize(vmin=vmin, vmax=vmax) cbar = fig.colorbar(mpl.cm.ScalarMappable(norm=norm, cmap=cmap), cax=cax) cbar.set_label(label=r"$\delta$",fontsize=16) #set axis labels frame.set_xlabel(r"$\phi\ [^\circ]$", fontsize=16) frame.set_ylabel(r"$\theta_z\ [^\circ]$", fontsize=16) frame.grid() if save: return fig show()
def plot_chisq_variation(x, y, yerr, dof, rchi2, c, cmode='ε', Zlimit=None, dop=None, save=False): #'cmode' : possible modes are 'ε' and 'dop' (degree of polarization) #'x' should be a tuple containing station names and zenith angles (in degrees) for each station, i.e. (station_names, zenith_angles) #'y' should contain chi-square values and absolute deviations from the model (in radians) for each station, i.e. (chi-square, abs_dev) #'yerr' should contain the errors in the data fitted to the model (τ_err) in radians #'dof' should contain the degrees of freedom of the fitted data #'rchi2' should contain the reduced chi-square value corresponding to the fit #'c' should contain a data array defining the colors for each scatter point according to 'cmode' #'Zlimit' is the zenithal limit for which the fit of the acceleration direction was made station_names = x[0] Z = x[1] χ2 = y[0] absdev = np.rad2deg(y[1]) absdev_err = np.rad2deg(yerr) fig = figure(figsize=(20, 10)) gs = fig.add_gridspec(2, 1, height_ratios=(1, 1), hspace=0.05) errorbar_setup = dict(fmt='.k', markersize=0.5, marker='s', capsize=2, capthick=1.5, elinewidth=1.5, ecolor='k', zorder=1) cmap = gen_olaf_cmap() if cmode == 'ε': c = np.rad2deg(c) norm = colors.Normalize(np.min(c), np.max(c)) scatter_setup = dict(s=150, marker='*', c=c, cmap=cmap, norm=norm, edgecolor='k', linewidths=0.4, zorder=2) frame2 = fig.add_subplot(gs[1]) frame1 = fig.add_subplot(gs[0], sharex=frame2) frame1.scatter(station_names, χ2, **scatter_setup) frame1.axhline(y=rchi2, linestyle='dashed', linewidth=1, color='r') ytrans1 = frame1.get_yaxis_transform() frame1.annotate(r"$\chi^2_{\nu}$", [1.01, rchi2], xycoords=ytrans1, fontsize=16) setp(frame1.get_xticklabels(), visible=False) frame1.set_ylabel(r"$\chi^2$", fontsize=16) frame1.grid() RMS = compute_RMS(absdev, dof, Z, Zlimit=Zlimit, dop=dop) frame2.scatter(station_names, absdev, **scatter_setup) frame2.errorbar(station_names, absdev, yerr=absdev_err, **errorbar_setup) frame2.axhline(y=RMS, linestyle='dashed', linewidth=1, color='r') ytrans2 = frame2.get_yaxis_transform() frame2.annotate(r"RMS", [1.01, RMS], xycoords=ytrans2, fontsize=16) xticklabels = [ "{}\n".format(s) + r"${:.1f}^{{\circ}}$".format(z) for s, z in zip(station_names, Z) ] frame2.set_xticklabels(xticklabels, rotation=45) frame2.set_xlabel( "station\n" + r"$\theta_z$", fontsize=16 ) #r"stations (ordered lowest $\rightarrow$ highest zenith angle)" frame2.set_ylabel( r"$\left|\tau_i - \tau\left(\vec{p}\right)\right|\ [^{\circ}]$", fontsize=16) frame2.set_ylim((0, None)) frame2.grid() cbar = fig.colorbar(cm.ScalarMappable(cmap=cmap, norm=norm), orientation='vertical', ax=[frame1, frame2]) if cmode == 'ε': cbar.set_label(label=r"$\epsilon\ [^{\circ}]$", fontsize=16) elif cmode == 'dop': cbar.set_label(label=r"$\delta$", fontsize=16) if save: return fig else: show()
def plot_PE_scatter(pulses_PE, station, Z, save=False): cmap = gen_olaf_cmap() errorbar_setup = dict(fmt='.k', markersize=0.5, marker='s', capsize=2, capthick=0.25, elinewidth=0.5, ecolor='k', zorder=1) scatter_setup = dict(s=10, marker='s', cmap=cmap, edgecolor='k', linewidths=0.4, zorder=2) fig = figure(figsize=(20, 20)) gs = fig.add_gridspec(2, 2, wspace=0.25, hspace=0.15) fig.suptitle(r"{} ($\overline{{\theta}}_z = {:.2f}^{{\circ}}$)".format( station, Z), fontsize=32, position=(0.5, 0.95)) frame1 = fig.add_subplot(gs[0]) norm1 = colors.Normalize(min(pulses_PE['ε']), max(pulses_PE['ε'])) frame1.scatter(pulses_PE['δ'], pulses_PE['τ'], c=pulses_PE['ε'], norm=norm1, **scatter_setup) frame1.errorbar(pulses_PE['δ'], pulses_PE['τ'], xerr=pulses_PE["σ_δ"], yerr=pulses_PE["σ_τ"], **errorbar_setup) frame1.set_xlabel(r"$δ$", fontsize=16) frame1.set_ylabel(r"$τ\ [^{\circ}]$", fontsize=16) divider1 = make_axes_locatable(frame1) cax1 = divider1.append_axes("right", size="2%", pad=0.03) cbar1 = fig.colorbar(cm.ScalarMappable(cmap=cmap, norm=norm1), cax=cax1) cbar1.set_label(label=r"$ε\ [^{\circ}]$", fontsize=16) frame1.set_xlim((0, 1)) frame1.set_ylim(-90, 90) frame1.grid() frame2 = fig.add_subplot(gs[1]) norm2 = colors.Normalize(min(pulses_PE['τ']), max(pulses_PE['τ'])) frame2.scatter(pulses_PE['δ'], pulses_PE['ε'], c=pulses_PE['τ'], norm=norm2, **scatter_setup) frame2.errorbar(pulses_PE['δ'], pulses_PE['ε'], xerr=pulses_PE["σ_δ"], yerr=pulses_PE["σ_ε"], **errorbar_setup) frame2.set_xlabel(r"$δ$", fontsize=16) frame2.set_ylabel(r"$ε\ [^{\circ}]$", fontsize=16) divider2 = make_axes_locatable(frame2) cax2 = divider2.append_axes("right", size="2%", pad=0.03) cbar2 = fig.colorbar(cm.ScalarMappable(cmap=cmap, norm=norm2), cax=cax2) cbar2.set_label(label=r"$τ\ [^{\circ}]$", fontsize=16) frame2.set_xlim((0, 1)) frame2.set_ylim(-45, 45) frame2.grid() frame3 = fig.add_subplot(gs[2]) norm3 = colors.Normalize(min(pulses_PE['δ']), max(pulses_PE['δ'])) frame3.scatter(pulses_PE['τ'], pulses_PE['ε'], c=pulses_PE['δ'], norm=norm3, **scatter_setup) frame3.errorbar(pulses_PE['τ'], pulses_PE['ε'], xerr=pulses_PE["σ_τ"], yerr=pulses_PE["σ_ε"], **errorbar_setup) frame3.set_xlabel(r"$τ\ [^{\circ}]$", fontsize=16) frame3.set_ylabel(r"$ε\ [^{\circ}]$", fontsize=16) divider3 = make_axes_locatable(frame3) cax3 = divider3.append_axes("right", size="2%", pad=0.03) cbar3 = fig.colorbar(cm.ScalarMappable(cmap=cmap, norm=norm3), cax=cax3) cbar3.set_label(label=r"$δ$", fontsize=16) frame3.set_xlim(-90, 90) frame3.set_ylim(-45, 45) frame3.grid() if save: return fig, (frame1, frame2, frame3) else: show()