def scintillation_parameters(self, plotbound=1.0, maxr=None, maxc=None, savefig=None, show=True, full_output=False, simple=False, eta=0.2, cmap=cm.binary, finitescintleerrors=True): if self.acf is None: self.acf2d() if self.dT is None: dT = 1 else: dT = self.dT if self.dF is None: dF = 1 else: dF = self.dF acfshape = np.shape(self.acf) centerrind = acfshape[0] // 2 centercind = acfshape[1] // 2 if simple: # Do 1D slices NF = len(self.F) Faxis = (np.arange(-(NF - 1), NF, dtype=np.float) * np.abs(dF) ) #why abs? NT = len(self.T) Taxis = (np.arange(-(NT - 1), NT, dtype=np.float) * np.abs(dT))[1:-1] #??? #try: pout, errs = ffit.gaussianfit(Taxis[NT // 2:3 * NT // 2], self.acf[centerrind, NT // 2:3 * NT // 2], baseline=True) f = interpolate.interp1d( Taxis, ffit.funcgaussian(pout, Taxis, baseline=True) - (pout[3] + pout[0] / np.e)) delta_t_d = optimize.brentq(f, 0, Taxis[-1]) #except: # delta_t_d = 0.0 # print "dtd",pout # plt.plot(Taxis,self.acf[centerrind,:]) # plt.plot(Taxis,f(Taxis)) # plt.show() #try: pout, errs = ffit.gaussianfit(Faxis[NF // 2:3 * NF // 2], self.acf[NF // 2:3 * NF // 2, centercind], baseline=True) f = interpolate.interp1d( Faxis, ffit.funcgaussian(pout, Faxis, baseline=True) - (pout[3] + pout[0] / 2)) delta_nu_d = optimize.brentq(f, 0, Faxis[-1]) #except: # delta_nu_d = 0 #print "dnud",pout,Faxis[-1],dF #print Faxis #raise SystemExit #plt.plot(Faxis,self.acf[:,centercind]) #plt.plot(Faxis,f(Faxis)) #plt.show() #following Glenn's code and Cordes 1986 (Space Velocities...) # Errors from finite scintle effect: bw = self.getBandwidth() T = self.getTspan() if delta_t_d == 0.0: N_d = (1 + eta * bw / delta_nu_d) elif delta_nu_d == 0.0: N_d = (1 + eta * T / delta_t_d) else: N_d = (1 + eta * bw / delta_nu_d) * (1 + eta * T / delta_t_d) fse_nu_d = delta_nu_d / (2 * np.log(2) * np.sqrt(N_d) ) #log because of FWHM? fse_t_d = delta_t_d / (2 * np.sqrt(N_d)) err_nu_d = fse_nu_d err_t_d = fse_t_d #need to add in fitting errors if full_output: return delta_t_d, err_t_d, delta_nu_d, err_nu_d return delta_t_d, delta_nu_d # Look for the central peak in the ACF MIN = np.min(self.acf) if MIN < 0: #The min value is approximately from a gaussian distribution MIN = np.abs(MIN) else: #center,hist = u.histogram(acf.flatten(),interval=0.001) #relies on 0.001 #MIN = center[np.argmax(hist)] MIN = u.RMS(self.acf.flatten()) if maxr is None: rslice = self.acf[centerrind:, centercind] maxr = np.where(rslice <= MIN)[0][0] if maxc is None: cslice = self.acf[centerrind, centercind:] maxc = np.where(cslice <= MIN)[0][0] plotacf = self.acf[int(centerrind - plotbound * maxr + 1):int(centerrind + plotbound * maxr), int(centercind - plotbound * maxc + 1):int(centercind + plotbound * maxc + 1)] params, pcov = ffit.fitgaussian2d( plotacf) #pcov already takes into account s_sq issue SHAPE = np.shape(plotacf) fit = ffit.gaussian2d(*params) amplitude, center_x, center_y, width_x, width_y, rotation, baseline = params paramnames = [ "amplitude", "center_x", "center_y", "width_x", "width_y", "rotation", "baseline" ] if pcov is not None: paramerrors = np.sqrt(np.diagonal(pcov)) else: paramerrors = np.zeros_like(params) if self.verbose: for i, param in enumerate(params): print("%s: %0.2e+/-%0.2e" % (paramnames[i], param, paramerrors[i])) #Solve for scintillation parameters numerically try: delta_t_d = (optimize.brentq( lambda y: fit(SHAPE[0] // 2, y) - baseline - amplitude / np.e, (SHAPE[1] - 1) // 2, SHAPE[1] * 2) - (SHAPE[1] - 1) // 2) * dT #FWHM test if self.verbose: print("delta_t_d %0.3f %s" % (delta_t_d, self.Tunit)) except ValueError: if self.verbose: print("ERROR in delta_t_d") delta_t_d = SHAPE[1] * dT if pcov is not None: err_t_d = paramerrors[3] * dT #assume no rotaton for now else: err_t_d = None try: delta_nu_d = (optimize.brentq( lambda x: fit(x, SHAPE[1] // 2) - baseline - amplitude / 2.0, (SHAPE[0] - 1) // 2, SHAPE[0]) - (SHAPE[0] - 1) // 2) * dF if self.verbose: print("delta_nu_d %0.3f %s" % (delta_nu_d, self.Funit)) except ValueError: if self.verbose: print("ERROR in delta_nu_d") delta_nu_d = SHAPE[0] * dF if pcov is not None: err_nu_d = paramerrors[4] * dF #assume no rotaton for now else: err_nu_d = None err_rot = paramerrors[5] #finite-scintle errors if finitescintleerrors: bw = self.getBandwidth() T = self.getTspan() if delta_t_d == 0.0: N_d = (1 + eta * bw / delta_nu_d) elif delta_nu_d == 0.0: N_d = (1 + eta * T / delta_t_d) else: N_d = (1 + eta * bw / delta_nu_d) * (1 + eta * T / delta_t_d) fse_nu_d = delta_nu_d / (2 * np.log(2) * np.sqrt(N_d) ) #log because of FWHM? fse_t_d = delta_t_d / (2 * np.sqrt(N_d)) fse_rot = rotation * np.sqrt((fse_nu_d / delta_nu_d)**2 + (fse_t_d / delta_t_d)**2) err_nu_d = np.sqrt(err_nu_d**2 + fse_nu_d**2) err_t_d = np.sqrt(err_t_d**2 + fse_t_d**2) err_rot = np.sqrt(err_rot**2 + fse_rot**2) if self.verbose: f = (dF / dT) * np.tan(rotation) df = (dF / dT) * np.cos(rotation)**2 * err_rot print("dnu/dt %0.3e+/-%0.3e %s/%s" % (f, df, self.Funit, self.Tunit)) #((dF/dT)*np.tan(rotation)) if show or savefig is not None: fig = plt.figure() ax = fig.add_subplot(211) u.imshow(self.data, cmap=cmap) ax = fig.add_subplot(212) u.imshow(plotacf, cmap=cmap) plt.colorbar() levels = (amplitude * np.array([1.0, 0.5, 1.0 / np.e])) + baseline levels = (amplitude * np.array([0.5])) + baseline #print(levels) ax.contour(fit(*np.indices(plotacf.shape)), levels, colors='k') #ax.set_xlim(len(xs)-20,len(xs)+20) #ax.set_ylim(len(ys)-10,len(ys)+10) if savefig is not None: plt.savefig(savefig) if show: plt.show() if full_output: return delta_t_d, err_t_d, delta_nu_d, err_nu_d, rotation, err_rot return delta_t_d, delta_nu_d, rotation
def spline_smoothing(self, sigma=None, lam=None, **kwargs): """ Cubic Spline Interplation sigma: phase bin error bars lam: (0,1], 1 = maximize fitting through control points (knots), 0 = minimize curvature of spline """ tdata = self.bins ydata = u.normalize(self.data, simple=True) N = len(ydata) noise = self.getOffpulseNoise() if lam is None or (lam > 1 or lam <= 0): lam = 1 - noise**2 mu = 2 * float(1 - lam) / (3 * lam) ### Define knot locations # Rotate the pulse so the peak is at the edges of the spline shift = -np.argmax(ydata) yshift = np.roll(ydata, shift) # Add periodic point tdata = np.concatenate((tdata, [tdata[-1] + np.diff(tdata)[0]])) yshift = np.concatenate((yshift, [yshift[0]])) knots = u.subdivide(tdata, yshift, noise, **kwargs) knots = np.array(np.sort(knots), dtype=np.int) knots = np.concatenate(([0], knots, [N])) #Add endpoints if sigma is None: setsigma = True #for passnum in range(2): while True: Nknots = len(knots) Narcs = Nknots - 1 t = np.array(tdata[knots], dtype=np.float) # Determine the knot y-values. y = np.zeros_like(t) y[0] = yshift[0] y[-1] = yshift[-1] for i in range(1, len(knots) - 1): knotL = knots[i - 1] knotR = knots[i + 1] dt = tdata[knotL:knotR] dy = yshift[knotL:knotR] p = np.polyfit( dt, dy, 3 ) #Fit a preliminary cubic over the data to place the point. f = np.poly1d(p) y[i] = f(tdata[knots[i]]) if setsigma: sigma = np.ones(len(y), dtype=np.float) Sigma = np.diag(sigma[:-1]) #matrix # Smoothing with Cubic Splines by D.S.G. Pollock 1999 h = t[1:] - t[:-1] r = 3.0 / h f = np.zeros_like(h) p = np.zeros_like(h) #q = np.zeros_like(h) p[0] = 2 * (h[0] + h[-1]) #q[0] = 3*(y[1] - y[0])/h[0] - 3*(y[-1] - y[-2])/h[-1] #note the indices f[0] = -(r[-1] + r[0]) for i in range(1, Narcs): p[i] = 2 * (h[i] + h[i - 1]) #q[i] = 3*(y[i+1] - y[i])/h[i] - 3*(y[i] - y[i-1])/h[i-1] f[i] = -(r[i - 1] + r[i]) # Build projection matrices R = np.zeros((Narcs, Narcs)) Qp = np.zeros((Narcs, Narcs)) for i in range(Narcs): #for j in range(Narcs): # if i == j: R[i, i] = p[i] Qp[i, i] = f[i] if i != Narcs - 1: R[i + 1, i] = h[i] R[i, i + 1] = h[i] Qp[i + 1, i] = r[i] Qp[i, i + 1] = r[i] R[0, -1] = h[-1] R[-1, 0] = h[-1] Qp[0, -1] = r[-1] Qp[-1, 0] = r[-1] Q = np.transpose(Qp) A = mu * np.dot(np.dot(Qp, Sigma), Q) + R b = np.linalg.solve(A, np.dot(Qp, y[:-1])) d = y[:-1] - mu * np.dot(np.dot(Sigma, Q), b) a = np.zeros(Narcs) c = np.zeros(Narcs) i = Narcs - 1 a[i] = (b[0] - b[i]) / (3 * h[i]) for i in range(Narcs - 1): a[i] = (b[i + 1] - b[i]) / (3 * h[i]) i = Narcs - 1 c[i] = (d[0] - d[i]) / h[i] - a[i] * h[i]**2 - b[i] * h[i] for i in range(Narcs - 1): c[i] = (d[i + 1] - d[i]) / h[i] - a[i] * h[i]**2 - b[i] * h[i] # Build polynomials S = [] for i in range(Narcs): S.append(np.poly1d([a[i], b[i], c[i], d[i]])) ytemp = np.zeros_like(yshift) for i in range(Narcs): ts = np.arange(t[i], t[i + 1]) hs = ts - t[i] yS = S[i](hs) ytemp[int(t[i]):int(t[i + 1])] = yS ytemp[-1] = ytemp[0] resids = yshift - ytemp #print resids,noise rms_resids = u.RMS(resids) #inds = np.where(np.abs(resids)>4*rms_resids)[0] inds = np.where( np.logical_and(yshift > 3 * noise, np.abs(resids) > 4 * rms_resids) )[0] #require the intensity to be "significant", and the residuals if len(inds) == 0: break #newinds = np.sort(np.abs(resids)) newinds = np.argsort(np.abs(resids)) #print np.argmax(np.abs(resids)) #print newinds #raise SystemExit #newind = np.argmax(np.abs(resids)) newind = newinds[-1] i = 1 addknot = True while newind in knots and np.any(np.abs(knots - newind) <= 4): if i == N: addknot = False break i += 1 newind = newinds[-i] ''' for newind in newinds: if newind in knots: continue elif np.all(np.abs(newind-knots)<=1): continue print newind break ''' if addknot: #print newind knots = np.sort(np.concatenate((knots, [newind]))) else: break resids = yshift - ytemp rms_resids = u.RMS(resids) tdata = tdata[:-1] #yshift = yshift[:-1] ytemp = ytemp[:-1] #yshift = np.roll(yshift,-shift) ytemp = np.roll(ytemp, -shift) ytemp /= np.max(ytemp) return ytemp
def scintillation_parameters(self, plotbound=1.0, maxr=None, maxc=None, savefig=None, show=True, full_output=False): if self.acf is None: self.acf2d() if self.dT is None: dT = 1 else: dT = self.dT if self.dF is None: dF = 1 else: dF = self.dF acfshape = np.shape(self.acf) centerrind = acfshape[0] // 2 centercind = acfshape[1] // 2 # Look for the central peak in the ACF MIN = np.min(self.acf) if MIN < 0: #The min value is approximately from a gaussian distribution MIN = np.abs(MIN) else: #center,hist = u.histogram(acf.flatten(),interval=0.001) #relies on 0.001 #MIN = center[np.argmax(hist)] MIN = u.RMS(self.acf.flatten()) if maxr is None: rslice = self.acf[centerrind:, centercind] maxr = np.where(rslice <= MIN)[0][0] if maxc is None: cslice = self.acf[centerrind, centercind:] maxc = np.where(cslice <= MIN)[0][0] plotacf = self.acf[centerrind - plotbound * maxr + 1:centerrind + plotbound * maxr, centercind - plotbound * maxc + 1:centercind + plotbound * maxc + 1] params, pcov = ffit.fitgaussian2d( plotacf) #pcov already takes into account s_sq issue SHAPE = np.shape(plotacf) fit = ffit.gaussian2d(*params) amplitude, center_x, center_y, width_x, width_y, rotation, baseline = params if self.verbose: paramnames = [ "amplitude", "center_x", "center_y", "width_x", "width_y", "rotation", "baseline" ] if pcov is not None: paramerrors = np.sqrt(np.diagonal(pcov)) else: paramerrors = np.zeros_like(params) for i, param in enumerate(params): print("%s: %0.2e+/-%0.2e" % (paramnames[i], param, paramerrors[i])) #Solve for scintillation parameters numerically try: delta_t_d = (optimize.brentq( lambda y: fit(SHAPE[0] // 2, y) - baseline - amplitude / np.e, (SHAPE[1] - 1) // 2, SHAPE[1] * 2) - (SHAPE[1] - 1) // 2) * dT #FWHM test if self.verbose: print("delta_t_d %0.3f minutes" % delta_t_d) except ValueError: if self.verbose: print("ERROR in delta_t_d") delta_t_d = SHAPE[1] * dT if pcov is not None: err_t_d = paramerrors[3] * dT #assume no rotaton for now else: err_t_d = None try: delta_nu_d = (optimize.brentq( lambda x: fit(x, SHAPE[1] // 2) - baseline - amplitude / 2.0, (SHAPE[0] - 1) // 2, SHAPE[0]) - (SHAPE[0] - 1) // 2) * dF if self.verbose: print("delta_nu_d %0.3f MHz" % delta_nu_d) except ValueError: if self.verbose: print("ERROR in delta_nu_d") delta_nu_d = SHAPE[0] * dF if pcov is not None: err_nu_d = paramerrors[4] * dF #assume no rotaton for now else: err_nu_d = None err_rot = paramerrors[5] if self.verbose: print("dnu/dt %0.3f MHz/min" % ((dF / dT) * np.tan(rotation))) #((dF/dT)*np.tan(rotation)) if show or savefig is not None: fig = plt.figure() ax = fig.add_subplot(211) u.imshow(self.data) ax = fig.add_subplot(212) u.imshow(plotacf) plt.colorbar() levels = (amplitude * np.array([1.0, 0.5, 1.0 / np.e])) + baseline levels = (amplitude * np.array([0.5])) + baseline print(levels) ax.contour(fit(*np.indices(plotacf.shape)), levels, colors='k') #ax.set_xlim(len(xs)-20,len(xs)+20) #ax.set_ylim(len(ys)-10,len(ys)+10) if savefig is not None: plt.savefig(savefig) if show: plt.show() if full_output: return delta_t_d, err_t_d, delta_nu_d, err_nu_d, rotation, err_rot return delta_t_d, delta_nu_d, rotation