def compute_b_jones(self): """ Computes the brightness matrix from the stokes parameters. Returns a (4,nsrc,ntime,nchan) matrix of complex scalars. """ nsrc, ntime, nchan = self.dim_local_size('nsrc', 'ntime', 'nchan') try: B = np.empty(shape=(nsrc, ntime, 4), dtype=self.ct) S = self.stokes # Create the brightness matrix from the stokes parameters # Dimension (nsrc, ntime, 4) B[:,:,0] = S[:,:,0] + S[:,:,1] # I+Q B[:,:,1] = S[:,:,2] + 1j*S[:,:,3] # U+Vi B[:,:,2] = S[:,:,2] - 1j*S[:,:,3] # U-Vi B[:,:,3] = S[:,:,0] - S[:,:,1] # I-Q # Multiply the scalar power term into the matrix B_power = ne.evaluate('B*((f/rf)**a)', { 'rf': self.ref_frequency[np.newaxis, np.newaxis, :, np.newaxis], 'B': B[:,:,np.newaxis,:], 'f': self.frequency[np.newaxis, np.newaxis, :, np.newaxis], 'a': self.alpha[:, :, np.newaxis, np.newaxis] }) assert B_power.shape == (nsrc, ntime, nchan, 4) return B_power except AttributeError as e: mbu.rethrow_attribute_exception(e)
def compute_b_sqrt_jones(self, b_jones=None): """ Computes the square root of the brightness matrix. Returns a (4,nsrc,ntime,nchan) matrix of complex scalars. """ nsrc, ntime, nchan = self.dim_local_size('nsrc', 'ntime', 'nchan') try: # See # http://en.wikipedia.org/wiki/Square_root_of_a_2_by_2_matrix # Note that this code handles a special case of the above # where we assume that both the trace and determinant # are real and positive. B = self.compute_b_jones() if b_jones is None else b_jones.copy() # trace = I+Q + I-Q = 2*I # det = (I+Q)*(I-Q) - (U+iV)*(U-iV) = I**2-Q**2-U**2-V**2 trace = (B[:,:,:,0]+B[:,:,:,3]).real det = (B[:,:,:,0]*B[:,:,:,3] - B[:,:,:,1]*B[:,:,:,2]).real assert trace.shape == (nsrc, ntime, nchan) assert det.shape == (nsrc, ntime, nchan) assert np.all(trace >= 0.0), \ 'Negative brightness matrix trace' assert np.all(det >= 0.0), \ 'Negative brightness matrix determinant' s = np.sqrt(det) t = np.sqrt(trace + 2*s) # We don't have a solution for matrices # where both s and t are zero. In the case # of brightness matrices, zero s and t # implies that the matrix itself is 0. # Avoid infs and nans from divide by zero mask = np.logical_and(s == 0.0, t == 0.0) t[mask] = 1.0 # Add s to the diagonal entries B[:,:,:,0] += s B[:,:,:,3] += s # Divide the entire matrix by t B /= t[:,:,:,np.newaxis] return B except AttributeError as e: mbu.rethrow_attribute_exception(e)
def compute_ekb_jones_per_bl(self, ekb_sqrt=None): """ Computes per baseline jones matrices based on the scalar EKB Square root terms Returns a (nsrc,ntime,nbl,nchan,4) matrix of complex scalars. """ nsrc, npsrc, ngsrc, nssrc, ntime, nbl, nchan = self.dim_local_size( 'nsrc', 'npsrc', 'ngsrc', 'nssrc', 'ntime', 'nbl', 'nchan') try: if ekb_sqrt is None: ekb_sqrt = self.compute_ekb_sqrt_jones_per_ant() ant0, ant1 = self.ap_idx(src=True, chan=True) ekb_sqrt_p = ekb_sqrt[ant0] ekb_sqrt_q = ekb_sqrt[ant1] assert ekb_sqrt_p.shape == (nsrc, ntime, nbl, nchan, 4) result = self.jones_multiply(ekb_sqrt_p, ekb_sqrt_q, hermitian=True).reshape(nsrc, ntime, nbl, nchan, 4) # Multiply in Gaussian Shape Terms if ngsrc > 0: src_beg = npsrc src_end = npsrc + ngsrc gauss_shape = self.compute_gaussian_shape() result[src_beg:src_end,:,:,:,:] *= gauss_shape[:,:,:,:,np.newaxis] # Multiply in Sersic Shape Terms if nssrc > 0: src_beg = npsrc + ngsrc src_end = npsrc + ngsrc + nssrc sersic_shape = self.compute_sersic_shape() result[src_beg:src_end,:,:,:,:] *= sersic_shape[:,:,:,:,np.newaxis] return result #return ebk_sqrt[1]*ebk_sqrt[0].conj() except AttributeError as e: mbu.rethrow_attribute_exception(e)