def compute_redundantinfo(self, tol=1e-6): '''Use provided antenna locations (in arrayinfoPath) to derive redundancy equations''' reds = self.compute_reds(tol=tol) reds = self.filter_reds(reds, bls=self.totalVisibilityId.keys(), ex_ants=list(self.badAntenna), ex_ubls=[tuple(p) for p in self.badUBLpair]) info = RedundantInfo() info.init_from_reds(reds, self.antennaLocation) return info
def compute_redundantinfo(self, arrayinfoPath=None, tol=1e-6): # XXX remove this legacy interface? '''Legacy version of compute_redundantinfo if you need subsetbls for data ordering.''' self.antennaLocationTolerance = tol if arrayinfoPath is not None: self.read_arrayinfo(arrayinfoPath) info = RedundantInfo() # exclude bad antennas info['subsetant'] = subsetant = np.array([i for i in xrange(self.antennaLocation.shape[0]) if i not in self.badAntenna], dtype=np.int32) info['nAntenna'] = nAntenna = len(subsetant) # XXX maybe have C api automatically infer this info['antloc'] = antloc = np.array([self.antennaLocation[i] for i in subsetant], dtype=np.float32) ublall = self.compute_UBL(tol) #delete the bad ubl's badUBL = {} def dis(a1,a2): return np.linalg.norm(a1-a2) for a1,a2 in self.badUBLpair: bl = self.antennaLocation[a1] - self.antennaLocation[a2] for i,ubl in enumerate(ublall): if dis(bl,ubl) < tol or dis(bl,-ubl) < tol: badUBL[i] = None ubl2goodubl = {} def f(i,u): ubl2goodubl[i] = len(ubl2goodubl) return u info['ubl'] = ubl = np.array([f(i,u) for i,u in enumerate(ublall) if not badUBL.has_key(i)], dtype=np.float32) for k in badUBL: ubl2goodubl[k] = -1 nUBL = ubl.shape[0] # XXX maybe have C api automatically infer this badubl = [ublall[i] for i in badUBL] #find nBaseline (include auto bls) and subsetbl #bl2d: from 1d bl index to a pair of antenna numbers bl2d = [] # XXX cleaner way to do this? for i,ai in enumerate(antloc): for j,aj in enumerate(antloc[:i+1]): blij = ai - aj flag = False for bl in badubl: if dis(blij,bl) < tol or dis(blij,-bl) < tol: flag = True break if not flag: bl2d.append((i,j)) # exclude pairs that are not in totalVisibilityId tmp = [] for p in bl2d: bl = (subsetant[p[0]],subsetant[p[1]]) if self.totalVisibilityId_dic.has_key(bl): tmp.append(p) elif self.totalVisibilityId_dic.has_key(bl[::-1]): tmp.append(p[::-1]) bl2d = np.array(tmp, dtype=np.int32) crossindex = np.array([i for i,p in enumerate(bl2d) if p[0] != p[1]], dtype=np.int32) nBaseline = len(bl2d) bl2d = bl2d[crossindex] # make bl2d only hold crosscorrelations info['nBaseline'] = len(bl2d) # XXX maybe have C api infer this # from a pair of good antenna index to bl index info['subsetbl'] = np.array([self.get_baseline([subsetant[bl[0]],subsetant[bl[1]]]) for bl in bl2d], dtype=np.int32) #bltoubl: cross bl number to ubl index def findublindex(p1,p2): a1,a2 = subsetant[p1],subsetant[p2] if (a1,a2) in self.totalVisibilityUBL: return ubl2goodubl[self.totalVisibilityUBL[(a1,a2)]] info['bltoubl'] = bltoubl = np.array([findublindex(*p) for p in bl2d if p[0] != p[1]], dtype=np.int32) #reversed: cross only bl if reversed -1, otherwise 1 crosspair = [p for p in bl2d if p[0] != p[1]] reverse = [] for k,cpk in enumerate(crosspair): bl = antloc[cpk[0]] - antloc[cpk[1]] if dis(bl,ubl[bltoubl[k]]) < tol: reverse.append(-1) elif dis(bl,-ubl[bltoubl[k]]) < tol: reverse.append(1) else : raise ValueError('bltoubl[%d] points to wrong ubl index' % (k)) reverse = np.array(reverse, dtype=np.int32) info._reversed = reverse # XXX store this to remember what we did bl2d0 = np.where(reverse == 1, bl2d[:,0], bl2d[:,1]) bl2d1 = np.where(reverse == 1, bl2d[:,1], bl2d[:,0]) bl2d[:,0],bl2d[:,1] = bl2d0,bl2d1 crosspair = [p for p in bl2d if p[0] != p[1]] # recompute crosspair for reversed indices info.bl2d = bl2d #ublcount: for each ubl, the number of good cross bls corresponding to it cnt = {} for bl in bltoubl: cnt[bl] = cnt.get(bl,0) + 1 info['ublcount'] = np.array([cnt[i] for i in range(nUBL)], dtype=np.int32) #ublindex: //for each ubl, the set of corresponding indices of baselines in bl2d cnt = {} for i,(a1,a2) in enumerate(crosspair): cnt[bltoubl[i]] = cnt.get(bltoubl[i],[]) + [[a1,a2,i]] ublindex = np.concatenate([np.array(cnt[i],dtype=np.int32) for i in range(nUBL)]) newind = np.arange(nBaseline)[crossindex] = np.arange(crossindex.size, dtype=np.int32) info.ublindex = newind[ublindex[:,2]] #bl1dmatrix: a symmetric matrix where col/row numbers index ants and entries are bl index (no auto corr) bl1dmatrix = (2**31-1) * np.ones((nAntenna,nAntenna),dtype=np.int32) # XXX don't like 2**31-1. whence this number? for i,cp in enumerate(crosspair): bl1dmatrix[cp[1],cp[0]], bl1dmatrix[cp[0],cp[1]] = i,i info['bl1dmatrix'] = bl1dmatrix #degenM: a = np.array([np.append(ai,1) for ai in antloc], dtype=np.float32) d = np.array([np.append(ubli,0) for ubli in ubl], dtype=np.float32) m1 = -a.dot(la.pinv(a.T.dot(a))).dot(a.T) m2 = d.dot(la.pinv(a.T.dot(a))).dot(a.T) info['degenM'] = np.append(m1,m2,axis=0) #A: A matrix for logcal amplitude A = np.zeros((len(crosspair),nAntenna+nUBL)) for i,cp in enumerate(crosspair): A[i,cp[0]], A[i,cp[1]], A[i,nAntenna+bltoubl[i]] = 1,1,1 info['At'] = sps.csr_matrix(A).T #B: B matrix for logcal phase B = np.zeros((len(crosspair),nAntenna+nUBL)) #for i,cp in enumerate(crosspair): B[i,cp[0]], B[i,cp[1]], B[i,nAntenna+bltoubl[i]] = -reverse[i],reverse[i],1 for i,cp in enumerate(crosspair): B[i,cp[0]], B[i,cp[1]], B[i,nAntenna+bltoubl[i]] = -1,1,1 info['Bt'] = sps.csr_matrix(B).T info.update() return info