Пример #1
0
def linearizedSol_bs(Obsdata, currImage, Prior, alpha=100, beta=100, reg="patch"):
# note what beta is
	
	# normalize the prior
	# TODO: SHOULD THIS BE DONE??
    zbl = np.max(np.abs(Obsdata.unpack(['vis'])['vis']))
    nprior = zbl * Prior.imvec / np.sum(Prior.imvec)
	
    if reg == "patch":
        linRegTerm, constRegTerm = spatchlingrad(currImage.imvec, nprior)

	# Get bispectra data    
    biarr = Obsdata.bispectra(mode="all", count="max")
    uv1 = np.hstack((biarr['u1'].reshape(-1,1), biarr['v1'].reshape(-1,1)))
    uv2 = np.hstack((biarr['u2'].reshape(-1,1), biarr['v2'].reshape(-1,1)))
    uv3 = np.hstack((biarr['u3'].reshape(-1,1), biarr['v3'].reshape(-1,1)))
    bispec = biarr['bispec']
    sigs = biarr['sigmab']
    
    # Compute the fourier matrices
    A3 = (vb.ftmatrix(currImage.psize, currImage.xdim, currImage.ydim, uv1, pulse=currImage.pulse),
          vb.ftmatrix(currImage.psize, currImage.xdim, currImage.ydim, uv2, pulse=currImage.pulse),
          vb.ftmatrix(currImage.psize, currImage.xdim, currImage.ydim, uv3, pulse=currImage.pulse)
         )
	
    Alin, blin = computeLinTerms_bi(currImage.imvec, A3, bispec, sigs, currImage.xdim*currImage.ydim, alpha=alpha, reg=reg)
    out = np.linalg.solve(Alin + beta*linRegTerm, blin + beta*constRegTerm); 
    
    return vb.Image(out.reshape((currImage.ydim, currImage.xdim)), currImage.psize, currImage.ra, currImage.dec, rf=currImage.rf, source=currImage.source, mjd=currImage.mjd, pulse=currImage.pulse)
Пример #2
0
def self_cal_scan(scan, im, method="both"):
    """Self-calibrate a scan"""

    # calculating image true visibs (beware no scattering here..)
    uv = np.hstack((scan["u"].reshape(-1, 1), scan["v"].reshape(-1, 1)))
    A = vb.ftmatrix(im.psize, im.xdim, im.ydim, uv, pulse=im.pulse)
    V = np.dot(A, im.imvec)

    sites = list(set(scan["t1"]).union(set(scan["t2"])))

    tkey = {b: a for a, b in enumerate(sites)}
    tidx1 = [tkey[row["t1"]] for row in scan]
    tidx2 = [tkey[row["t2"]] for row in scan]
    sigma_inv = 1.0 / scan["sigma"]

    def errfunc(gpar):
        g = gpar.astype(np.float64).view(dtype=np.complex128)  # all the forward site gains (complex)
        if method == "phase":
            g = g / np.abs(g)
        if method == "amp":
            g = np.abs(g)

        Verr = scan["vis"] - g[tidx1] * g[tidx2].conj() * V
        chisq = np.sum((Verr.real * sigma_inv) ** 2) + np.sum((Verr.imag * sigma_inv) ** 2)
        return chisq

    gpar_guess = np.ones(len(sites), dtype=np.complex128).view(dtype=np.float64)

    optdict = {"maxiter": 1000}  # minimizer params
    res = opt.minimize(errfunc, gpar_guess, method="Powell", options=optdict)
    g_fit = res.x.view(np.complex128)

    if method == "phase":
        g_fit = g_fit / np.abs(g_fit)
    if method == "amp":
        g_fit = np.abs(g_fit)

    gij_inv = (g_fit[tidx1] * g_fit[tidx2].conj()) ** (-1)

    print np.abs(gij_inv)

    scan["vis"] = gij_inv * scan["vis"]
    scan["qvis"] = gij_inv * scan["qvis"]
    scan["uvis"] = gij_inv * scan["uvis"]
    scan["sigma"] = np.abs(gij_inv) * scan["sigma"]

    return scan
Пример #3
0
    def observe_same(self, obs, sgrscat=False, repeat=False):
        """Observe the movie on the same baselines as an existing observation object
           if sgrscat==True, the visibilites will be blurred by the Sgr A* scattering kernel
           Does NOT add noise
        """
        
        # Check for agreement in coordinates and frequency 
        if (self.ra!= obs.ra) or (self.dec != obs.dec):
            raise Exception("Image coordinates are not the same as observtion coordinates!")
	    if (self.rf != obs.rf):
	        raise Exception("Image frequency is not the same as observation frequency!")
        
        mjdstart = self.mjd
        mjdend = self.mjd + (len(self.frames)*self.framedur) / 86400.0 #!AC use astropy date conversion
        
        # Get data
        obslist = obs.tlist()
        
        # Observation MJDs in range?
        # !AC use astropy date conversion!!
        obsmjds = np.array([(np.floor(obs.mjd) + (obsdata[0]['time'])/24.0) for obsdata in obslist])

        if (not repeat) and ((obsmjds < mjdstart) + (obsmjds > mjdend)).any():
            raise Exception("Obs times outside of movie range of MJD %f - %f" % (mjdstart, mjdend))
                   
        # Observe nearest frame
        obsdata_out = []
        for i in xrange(len(obslist)):
            obsdata = obslist[i]
            
            # Frame number
            mjd = obsmjds[i]
            n = int(np.floor((mjd - mjdstart) * 86400.0 / self.framedur))
            
            if (n >= len(self.frames)):
                if repeat: n = np.mod(n, len(self.frames))
                else: raise Exception("Obs times outside of movie range of MJD %f - %f" % (mjdstart, mjdend))
                
            # Extract uv data & perform DFT
            uv = obsdata[['u','v']].view(('f8',2))
            mat = vb.ftmatrix(self.psize, self.xdim, self.ydim, uv, pulse=self.pulse)
            vis = np.dot(mat, self.frames[n])
        
            # If there are polarized images, observe them:
            qvis = np.zeros(len(vis))
            uvis = np.zeros(len(vis))
            if len(self.qframes):
                qvis = np.dot(mat, self.qframes[n])
                uvis = np.dot(mat, self.uframes[n])
        
            # Scatter the visibilities with the SgrA* kernel
            if sgrscat:
                for i in range(len(vis)):
                    ker = sgra_kernel_uv(self.rf, uv[i,0], uv[i,1])
                    vis[i]  *= ker
                    qvis[i] *= ker
                    uvis[i] *= ker
   
            # Put the visibilities back in the obsdata array
            obsdata['vis'] = vis
            obsdata['qvis'] = qvis
            obsdata['uvis'] = uvis
            
            if len(obsdata_out):
                obsdata_out = np.hstack((obsdata_out, obsdata))
            else:
                obsdata_out = obsdata
                
        # Return observation object
        obs_no_noise = vb.Obsdata(self.ra, self.dec, self.rf, obs.bw, obsdata_out, obs.tarr, source=self.source, mjd=self.mjd)
        return obs_no_noise
Пример #4
0
def maxen_dynamic_bs(Obsdata_List, Prior_List, Flux_List, maxit=100, alpha=100, gamma=500, delta=500, beta=5, beta_blur=5, entropy="simple", stop=1e-10, ipynb=False, refresh_interval = 1000):
    """Run maximum entropy with the bispectrum
       Uses I = exp(I') change of variables.
       Obsdata is an Obsdata object, and Prior is an Image object.
       Returns Image object.
       The lagrange multiplier alpha is not a free parameter
    """
    print "Dynamic Imaging with the bispectrum. . ."
        
    gauss = np.array([[np.exp(-1.0*i**2/(2*beta_blur**2) - 1.0*j**2/(2.*beta_blur**2))
		                  for i in np.linspace((Prior_List[0].xdim-1)/2., -(Prior_List[0].xdim-1)/2., num=Prior_List[0].xdim)]  
		                  for j in np.linspace((Prior_List[0].ydim-1)/2., -(Prior_List[0].ydim-1)/2., num=Prior_List[0].ydim)]) #linespace makes thing symmetric
    gauss = gauss[0:Prior_List[0].ydim, 0:Prior_List[0].xdim]
    gauss = gauss / np.sum(gauss) # normalize to 1

    N_frame = len(Obsdata_List)
    N_pixel = Prior_List[0].xdim #pixel dimension

    # Catch problem if uvrange < largest baseline
    uvrange = 1./Prior_List[0].psize
    maxbl = np.max(Obsdata_List[0].unpack(['uvdist'])['uvdist'])
    if uvrange < maxbl:
        raise Exception("pixel spacing is larger than smallest spatial wavelength!")    
    
    logprior_List = [Prior_List[i].imvec for i in range(N_frame)]
    nprior_List = [Prior_List[i].imvec for i in range(N_frame)]
    A_List = [Prior_List[i].imvec for i in range(N_frame)]
    bi_List = [None,] * N_frame
    sigma_List = [None,] * N_frame
    for i in range(N_frame):
	# Normalize prior image to total flux        
        nprior_List[i] = Flux_List[i] * Prior_List[i].imvec / np.sum(Prior_List[i].imvec)
        logprior_List[i] = np.log(nprior_List[i])    
	# Data
	biarr = Obsdata_List[i].bispectra(mode="all", count="min")
	bi_List[i] = biarr['bispec']
	sigma_List[i] = biarr['sigmab']	
	# Compute the Fourier matrix
	uv1 = np.hstack((biarr['u1'].reshape(-1,1), biarr['v1'].reshape(-1,1)))
	uv2 = np.hstack((biarr['u2'].reshape(-1,1), biarr['v2'].reshape(-1,1)))
	uv3 = np.hstack((biarr['u3'].reshape(-1,1), biarr['v3'].reshape(-1,1)))
	A3 = (
	      vb.ftmatrix(Prior_List[i].psize, Prior_List[i].xdim, Prior_List[i].ydim, uv1),
	      vb.ftmatrix(Prior_List[i].psize, Prior_List[i].xdim, Prior_List[i].ydim, uv2),
	      vb.ftmatrix(Prior_List[i].psize, Prior_List[i].xdim, Prior_List[i].ydim, uv3)
	     )
	A_List[i] = A3
    

    # Define the objective function and gradient
    def objfunc(logim):
        Frames = np.exp(logim.reshape((-1, N_pixel, N_pixel)))     
        if entropy == "simple":
            s = np.sum(-mx.ssimple(Frames[i].ravel(), nprior_List[i]) for i in range(N_frame))
        elif entropy == "l1":
            s = np.sum(-mx.sl1(Frames[i].ravel(), nprior_List[i]) for i in range(N_frame))
        elif entropy == "gs":
            s = np.sum(-mx.sgs(Frames[i].ravel(), nprior_List[i]) for i in range(N_frame))
        elif entropy == "tv":
            s = np.sum(-mx.stv(Frames[i].ravel(), Prior_List[0].xdim, Prior_List[0].ydim) for i in range(N_frame))

        chisq_total = np.sum(mx.chisq_bi(Frames[i].ravel(), A_List[i], bi_List[i], sigma_List[i]) for i in range(N_frame))/N_frame  
        s_dynamic = dynamic_regularizer(Frames, gauss)
	t = np.sum( [ gamma * (np.sum(Frames[i].ravel()) - Flux_List[i])**2 for i in range(N_frame)] )/N_frame  
        return s + beta * s_dynamic + alpha * (chisq_total - 1.) + t
        
    def objgrad(logim):
	Frames = np.exp(logim.reshape((-1, N_pixel, N_pixel)))
        if entropy == "simple":
            s = np.concatenate([-mx.ssimplegrad(Frames[i].ravel(), nprior_List[i])*Frames[i].ravel() for i in range(N_frame)])
        elif entropy == "l1":
            s = np.concatenate([-mx.sl1grad(Frames[i].ravel(), nprior_List[i])*Frames[i].ravel() for i in range(N_frame)])
        elif entropy == "gs":
            s = np.concatenate([-mx.sgsgrad(Frames[i].ravel(), nprior_List[i])*Frames[i].ravel() for i in range(N_frame)])
        elif entropy == "tv":
            s = np.concatenate([-mx.stvgrad(Frames[i].ravel(), Prior_List[0].xdim, Prior_List[0].ydim)*Frames[i].ravel() for i in range(N_frame)])
            
	chisq_total_grad = np.concatenate([mx.chisqgrad_bi(Frames[i].ravel(), A_List[i], bi_List[i], sigma_List[i])*Frames[i].ravel()/N_frame for i in range(N_frame)])  

	s_dynamic_grad = dynamic_regularizer_gradient(Frames, gauss)

	t = np.concatenate( [ 2.0 * gamma * (np.sum(Frames[i].ravel()) - Flux_List[i]) * Frames[i].ravel()/N_frame   for i in range(N_frame)] )

        return (s + beta * s_dynamic_grad + alpha * chisq_total_grad + t) 

    def objgrad_numeric(x):  #This calculates the gradient numerically
	#dx = 10.0**-8
	J0 = objfunc(x)
	Jgrad = np.copy(x)
	for i in range(len(x)):
	    xp = np.copy(x)
	    dx = xp[i]*10.0**-8#+10.0**-8
	    xp[i] = xp[i] + dx
	    J1 = objfunc(xp)
	    Jgrad[i] = (J1-J0)/dx
	return Jgrad

    # Plotting function for each iteration
    global nit
    nit = 0
    def plotcur(logim_step):
        global nit
        nit += 1
	if nit%10 == 0:        
		print "iteration %d" % nit
		Frames = np.exp(logim_step.reshape((-1, N_pixel, N_pixel)))
		chi2 = np.sum(mx.chisq_bi(Frames[i].ravel(), A_List[i], bi_List[i], sigma_List[i]) for i in range(N_frame))/N_frame
		s = np.sum(-mx.ssimple(Frames[i].ravel(), nprior_List[i]) for i in range(N_frame))
		s_dynamic = dynamic_regularizer(Frames, gauss)
		print "chi2: %f" % chi2
		print "s: %f" % s
		print "s_dynamic: %f" % s_dynamic
		#plot_i(Frames[0], Prior_List[0], nit, chi2, ipynb=ipynb)
		if nit%refresh_interval == 0:
			plot_i_dynamic(Frames[::5], Prior_List[0], nit, chi2, s, s_dynamic, ipynb=ipynb)        

		if 1==0:
		    numeric_gradient = objgrad_numeric(logim_step)
		    analytic_gradient = objgrad(logim_step)
		    print "Numeric Gradient:"
		    print numeric_gradient 
		    print "Analytic Gradient:"
		    print analytic_gradient
		    print "Max Fractional Difference in gradients:"
		    print max(abs((numeric_gradient - analytic_gradient)/numeric_gradient))
   
    # Plot the prior
    #print(logprior_List.flatten().shape)
    logprior = np.hstack(logprior_List).flatten()
    plotcur(logprior)
        
    # Minimize
    optdict = {'maxiter':maxit, 'ftol':stop, 'maxcor':NHIST} # minimizer params
    tstart = time.time()
    res = opt.minimize(objfunc, logprior, method='L-BFGS-B', jac=objgrad,
                       options=optdict, callback=plotcur)
    tstop = time.time()
    #out = np.exp(res.x)
    Frames = np.exp(res.x.reshape((-1, N_pixel, N_pixel)))

    # Print stats
    print "time: %f s" % (tstop - tstart)
    print "J: %f" % res.fun
    #print "Chi^2: %f" % mx.chisq(out, A, vis, sigma)
    print res.message
    
    #Return Frames
    outim = [vb.Image(Frames[i].reshape(Prior_List[0].ydim, Prior_List[0].xdim), Prior_List[0].psize, Prior_List[0].ra, Prior_List[0].dec, rf=Prior_List[0].rf, source=Prior_List[0].source, mjd=Prior_List[0].mjd) for i in range(N_frame)]

    return outim