def xyregrid(img, mask, X, Y, nx=None, ny=None): ''' regrid with (nx,ny) points. This can also be used on QPHI coordinates any 2D rectangular grid. ''' pixellist = np.where(mask.ravel() == 1) data = img.ravel()[pixellist] x = X.ravel()[pixellist] y = Y.ravel()[pixellist] xlist = linplist(np.min(X), np.max(X), nx) ylist = linplist(np.min(Y), np.max(Y), ny) xid, yid, pselect = partition2D(xlist, ylist, x, y) bid = (yid * nx + xid) xy = partition_avg(data[pselect], bid) x_new = partition_avg(x[pselect], bid) y_new = partition_avg(y[pselect], bid) mask_new = partition_avg(pselect * 0 + 1, bid) xytot = np.zeros((ny, nx)) X_new = np.zeros((ny, nx)) Y_new = np.zeros((ny, nx)) MASK_new = np.zeros((ny, nx)) maxid = np.max(bid) xytot.ravel()[:maxid + 1] = xy X_new.ravel()[:maxid + 1] = x_new Y_new.ravel()[:maxid + 1] = y_new MASK_new.ravel()[:maxid + 1] = mask_new return xytot, MASK_new, X_new, Y_new
def xy2qphi(img, mask, X, Y, noqs=None, nophis=None): ''' Transform image from coordinates x,y to q,phi. Uses a binning scheme. ''' if (mask is None): pxlst = np.arange(img.shape[0] * img.shape[1]) else: pxlst = np.where(mask.ravel() == 1)[0] # make q coordinate system QS, PHIS = mkpolar(X=X, Y=Y) qs, phis = QS.ravel()[pxlst], PHIS.ravel()[pxlst] data = img.ravel()[pxlst] if (noqs is None): noqs = (np.max(qs) - np.min(qs)) if (nophis is None): nophis = 12 # make the lists for selection nophis = int(nophis) noqs = int(noqs) qlist_m1 = linplist(np.min(qs), np.max(qs), noqs) philist_m1 = linplist(np.min(phis), np.max(phis), nophis) # partition the grid (digitize) qid, pid, pselect = partition2D(qlist_m1, philist_m1, qs, phis) bid = (qid * nophis + pid).astype(int) # average the partitions sq = partition_avg(data[pselect], bid) q_new = partition_avg(qs[pselect], bid) phi_new = partition_avg(phis[pselect], bid) mask_new = partition_avg(pselect * 0 + 1, bid) sqtot = np.zeros((noqs, nophis)) Q_new = np.zeros((noqs, nophis)) PHI_new = np.zeros((noqs, nophis)) MASK_new = np.zeros((noqs, nophis)) maxid = np.max(bid) sqtot.ravel()[:maxid + 1] = sq Q_new.ravel()[:maxid + 1] = q_new PHI_new.ravel()[:maxid + 1] = phi_new MASK_new.ravel()[:maxid + 1] = mask_new return sqtot, MASK_new, Q_new, PHI_new
def qphi2xy(img, mask, Q, PHI, noxs=None, noys=None): ''' Transform image from coordinates x,y to q,phi. Uses a binning scheme. ''' if (mask is None): pxlst = np.arange(img.shape[0] * img.shape[1]) else: pxlst = np.where(mask.ravel() == 1)[0] X, Y = mkcartesian(Q=Q, PHI=PHI) x, y = X.ravel()[pxlst], Y.ravel()[pxlst] data = img.ravel()[pxlst] if (noxs is None): noxs = 400 if (noys is None): noys = 400 noxs = int(noxs) noys = int(noys) xlist_m1 = linplist(np.min(x), np.max(x), noxs) ylist_m1 = linplist(np.min(y), np.max(y), noys) xid, yid, pselect = partition2D(xlist_m1, ylist_m1, x, y) bid = (yid * noxs + xid).astype(int) xy = partition_avg(data[pselect], bid) x_new = partition_avg(x[pselect], bid) y_new = partition_avg(y[pselect], bid) mask_new = partition_avg(pselect * 0 + 1, bid) xytot = np.zeros((noys, noxs)) X_new = np.zeros((noys, noxs)) Y_new = np.zeros((noys, noxs)) MASK_new = np.zeros((noys, noxs)) maxid = np.max(bid) xytot.ravel()[:maxid + 1] = xy X_new.ravel()[:maxid + 1] = x_new Y_new.ravel()[:maxid + 1] = y_new MASK_new.ravel()[:maxid + 1] = mask_new return xytot, MASK_new, X_new, Y_new
def circavg(img, x0=None, y0=None, mask=None, SIMG=None, noqs=None): ''' Compute a circular average of the data. x0 : x center y0 : y center mask : the mask If SIMG is not null, put the data into this image. noqs : the number of qs to partition into. Default is the number of pixels approximately. ''' dimy, dimx = img.shape if (mask is None): pxlst = np.arange(dimx * dimy) else: pxlst = np.where(mask.ravel() == 1)[0] if (x0 is None): x0 = dimx / 2 if (y0 is None): y0 = dimy / 2 QS, PHIS = mkpolar(img, x0=x0, y0=y0) qs, phis = QS.ravel()[pxlst], PHIS.ravel()[pxlst] data = img.ravel()[pxlst] if (noqs is None): noqs = (np.max(qs) - np.min(qs)).astype(int) qlist_m1 = linplist(np.min(qs), np.max(qs), noqs) #philist_m1 = linplist(np.min(phis),np.max(phis),1) qid, pselect = partition1D(qlist_m1, qs) sqy = partition_avg(data[pselect], qid) #sqx = partition_avg(qs[pselect],qid) sqx = (qlist_m1[0::2] + qlist_m1[1::2]) / 2. if (SIMG is not None): SIMGtmp = 0 * SIMG SIMGtmp = np.interp(QS, sqx, sqy) np.copyto(SIMG, SIMGtmp) return sqx, sqy
def qphisum(img, x0=None, y0=None, mask=None, SIMG=None, qlist=None, philist=None, noqs=None, nophis=None, interp=None): ''' Compute a qphi average of the data. x0 : x center y0 : y center mask : the mask If SIMG is not null, put the data into this image. noqs : the number of qs to partition into. Default is the number of pixels approximately. interp : interpolation methods: None (default) : no interpolation 1 : interpolate in phi only (loop over q's) ... so far no other methods ''' dimy, dimx = img.shape if (mask is None): pxlst = np.arange(dimx * dimy) else: pxlst = np.where(mask.ravel() == 1)[0] if (x0 is None): x0 = dimx / 2 if (y0 is None): y0 = dimy / 2 if (qlist is None): if (noqs is None): noqs = 800 qlist_m1 = None elif (len(qlist) == 1): noqs = qlist qlist_m1 = None else: qlist_m1 = np.array(qlist) noqs = qlist_m1.shape[0] // 2 if (philist is None): if (nophis is None): nophis = 360 philist_m1 = None elif (len(philist) == 1): noqs = philist philist_m1 = None else: philist_m1 = np.array(philist) nophis = philist_m1.shape[0] // 2 QS, PHIS = mkpolar(img, x0=x0, y0=y0) qs, phis = QS.ravel()[pxlst], PHIS.ravel()[pxlst] data = img.ravel()[pxlst] if (noqs is None): noqs = (np.max(qs) - np.min(qs)) if (nophis is None): nophis = 12 nophis = int(nophis) noqs = int(noqs) if (qlist_m1 is None): qlist_m1 = linplist(np.min(qs), np.max(qs), noqs) if (philist_m1 is None): philist_m1 = linplist(np.min(phis), np.max(phis), nophis) qid, pid, pselect = partition2D(qlist_m1, philist_m1, qs, phis) bid = (qid * nophis + pid).astype(int) sqphi = partition_sum(data[pselect], bid) sqphitot = np.zeros((noqs, nophis)) maxid = np.max(bid) sqphitot.ravel()[:maxid + 1] = sqphi phis_m1 = (philist_m1[0::2] + philist_m1[1::2]) / 2. qs_m1 = (qlist_m1[0::2] + qlist_m1[1::2]) / 2. if (interp is not None): sqmask = np.zeros((noqs, nophis)) sqmask.ravel()[:maxid + 1] = partition_avg(pselect * 0 + 1, bid) if ((interp == 1) or (interp == 2)): for i in range(sqphitot.shape[0]): # won't work if you have numpy version < 1.10 sqphitot[i] = fillin1d(phis_m1, sqphitot[i], sqmask[i], period=2 * np.pi) # best suited for phi range -pi/2 to pi/2, might need to change # for diff versions if interp == 2: # second interp method also uses point symmetry # reverse philist, and rebin # assume the point of reflection is about zero, if not, maybe this # commented code could be tried (not tested) # first, find the point of reflection (is it about zero, -pi or pi?) #avgphi = np.average(phis_m1) #if(avgphi > -np.pi/2. and avgphi < np.pi/2.): #const = 0. #do nothing #elif(avgphi > np.pi/2. and avgphi < 3*np.pi/2.): #const = np.pi #elif(avgphi > -3*np.pi/2. and avgphi < -np.pi/2.): #const = np.pi const = 0. # now reflect philist philist_rev = const - philist_m1[::-1] qidr, pidr, pselectr = partition2D(qlist_m1, philist_rev, qs, phis) bidr = (qidr * nophis + pidr).astype(int) maxidr = np.max(bidr) sqphitotr = np.zeros((noqs, nophis)) sqphitotr.ravel()[:maxidr + 1] = partition_avg( data[pselectr], bidr) sqphitotr = sqphitotr[:, ::-1] sqmaskr = np.zeros((noqs, nophis)) sqmaskr.ravel()[:maxidr + 1] = partition_avg( pselectr * 0 + 1, bidr) sqmaskr = sqmaskr[:, ::-1] # now fill in values # just fill in the points, don't interp w = np.where((sqmask == 0) * (sqmaskr == 1)) sqphitot[w] = sqphitotr[w] if (SIMG is not None): SIMG.ravel()[pxlst[pselect]] = sqphitot.ravel()[bid] return sqphitot
def deltaphiqqdiff(img1, img2, mask=None, noqs=None, nophis=None, x0=None, y0=None, PF=False): ''' A delta phi difference correlation. This one returns a: q1,q2,dphi matrix where each element is <(I(q1,phi)-I(q2,phi+dphi))^2>_phi img1, img2 : used for the correlations (set to equal if same image) this is a 2nd moment calc so you need two quantities mask : the mask for the data set It uses the binning scheme only in one step. It transforms the image to a qphi square grid. It then uses FFT's to transform to a qphi correlation. ''' if (x0 is None): x0 = img1.shape[1] / 2 if (y0 is None): y0 = img1.shape[0] / 2 if (mask is None): mask = np.ones(IMG.shape) if (noqs is None): noqs = 800 if (nophis is None): nophis = 360 # 0. get pixellist and relevant data pxlst = np.where(mask.ravel() == 1) data1 = img1.ravel()[pxlst] data2 = img2.ravel()[pxlst] # 1. Make coord system and grab selected pixels QS, PHIS = mkpolar(img1, x0=x0, y0=y0) qs, phis = QS.ravel()[pxlst], PHIS.ravel()[pxlst] # 2. make the lists for selection qlist_m1 = linplist(np.min(qs), np.max(qs), noqs) philist_m1 = linplist(np.min(phis), np.max(phis), nophis) # 3. partition according to the lists, 2D here, make bin id 1 dimensional qid, pid, pselect = partition2D(qlist_m1, philist_m1, qs, phis) bid = (qid * nophis + pid).astype(int) # the sqphi here sq1 = np.zeros((noqs, nophis)) sq2 = np.zeros((noqs, nophis)) sq_qs = np.zeros((noqs, nophis)) sq_phis = np.zeros((noqs, nophis)) sqmask = np.zeros((noqs, nophis)) maxid = np.max(bid) sq1.ravel()[:maxid + 1] = partition_avg(data1[pselect], bid) sq2.ravel()[:maxid + 1] = partition_avg(data2[pselect], bid) sq_qs.ravel()[:maxid + 1] = partition_avg(qs[pselect], bid) sq_phis.ravel()[:maxid + 1] = partition_avg(phis[pselect], bid) sqmask.ravel()[:maxid + 1] = partition_avg(pselect * 0 + 1, bid) sq_qs = np.sum(sq_qs, axis=1) / np.sum(sqmask, axis=1) sq_phis = np.sum(sq_phis, axis=1) / np.sum(sqmask, axis=1) sqcphitot = np.zeros((noqs, noqs, nophis)) tx = np.arange(noqs) ty = np.arange(noqs) TX, TY = np.meshgrid(tx, ty) # perform convolution for i in np.arange(-noqs + 1, noqs): if (PF is True): print("Iterating over slice {} of {}".format( noqs + i, 2 * noqs + 1)) # grab the slice in q w = np.where(TX - TY == i) rngbeg = np.maximum(i, 0) rngend = np.minimum(noqs, noqs + i) sq1tmp = np.roll(sq1, i, axis=0)[rngbeg:rngend, :] sq2tmp = sq2[rngbeg:rngend] sqmask1 = np.roll(sqmask, i, axis=0)[rngbeg:rngend, :] sqmask2 = sqmask[rngbeg:rngend, :] sqcphi = ifft(fft(sq2tmp, axis=1) * np.conj(fft(sq1tmp, axis=1)), axis=1).real sqcphimask = ifft(fft(sqmask1, axis=1) * np.conj(fft(sqmask2, axis=1)), axis=1).real sqcphi /= sqcphimask sqcphitot[w[0], w[1], :] = sqcphi return sq_qs, sq_phis, sqcphitot
def deltaphidiff(img1, img2, mask=None, qlist=None, philist=None, x0=None, y0=None, PF=False, interp=0): ''' The new delta phi difference correlations. img1, img2 : used for the correlations (set to equal if same image) this is a 2nd moment calc so you need two quantities mask : the mask for the data set It uses the binning scheme only in one step. It transforms the image to a qphi square grid. It then uses FFT's to transform to a qphi correlation. interp : interpolation method. 0 - none (default) 1 - linear interpolation 2 - linear interpolation and reflect about 180 degrees (if possible) ''' if (x0 is None): x0 = img1.shape[1] / 2 if (y0 is None): y0 = img1.shape[0] / 2 if (mask is None): mask = np.ones(IMG.shape) if (qlist is None): noqs = 800 qlist_m1 = None elif (len(qlist) == 1): noqs = qlist qlist_m1 = None else: qlist_m1 = qlist if (philist is None): nophis = 360 philist_m1 = None elif (len(philist) == 1): noqs = philist philist_m1 = None else: philist_m1 = qlist # 0. get pixellist and relevant data pxlst = np.where(mask.ravel() == 1) data1 = img1.ravel()[pxlst] data2 = img2.ravel()[pxlst] # 1. Make coord system and grab selected pixels QS, PHIS = mkpolar(img1, x0=x0, y0=y0) qs, phis = QS.ravel()[pxlst], PHIS.ravel()[pxlst] # 2. make the lists for selection # m1 means 1st moment if (qlist_m1 is None): qlist_m1 = linplist(np.min(qs), np.max(qs), noqs) if (philist_m1 is None): philist_m1 = linplist(np.min(phis), np.max(phis), nophis) # 3. partition according to the lists, 2D here, make bin id 1 dimensional qid_m1, pid_m1, pselect_m1 = partition2D(qlist_m1, philist_m1, qs, phis) bid_m1 = (qid_m1 * nophis + pid_m1).astype(int) # the sqphi here sq1 = np.zeros((noqs, nophis)) sq2 = np.zeros((noqs, nophis)) sq_qs = np.zeros((noqs, nophis)) sq_phis = np.zeros((noqs, nophis)) sqmask = np.zeros((noqs, nophis)) sqcphi = np.zeros((noqs, nophis)) sqcphimask = np.zeros((noqs, nophis)) #transform image into a qphi map (1st moment) maxid = np.max(bid_m1) sq1.ravel()[:maxid + 1] = partition_avg(data1[pselect_m1], bid_m1) sq2.ravel()[:maxid + 1] = partition_avg(data2[pselect_m1], bid_m1) sqmask.ravel()[:maxid + 1] = partition_avg(pselect_m1 * 0 + 1, bid_m1) # calculate the correlation (2nd moment, keep same binning as first moment) nx = np.arange(nophis) NX = np.tile(nx, (nophis, 1)) NY = np.copy(NX.T) # in the case where img1 != img2 there should be an asymmetry, # but I ignore the direction and just take absolute value. It should not matter # as the order in which I supply img1 and img2 are not relevant NYX = NY - NX w = np.where(NYX < 0) NYX[w] = NYX[w] + nophis TAUID_m2 = NYX[np.newaxis, :, :] #import matplotlib.pyplot as plt #plt.figure(10);plt.imshow(TAUID[0]) # m2 means 2d moment QID_m2 = np.arange(noqs)[:, np.newaxis, np.newaxis] BID_m2 = TAUID_m2 * noqs + QID_m2 bid_m2 = BID_m2.ravel() # indexing tricks, expand phi dimension to a (phi, phi) dimension sqd1 = sq1[:, NX].ravel() sqd2 = sq2[:, NY].ravel() sqmask1 = sqmask[:, NX].ravel() sqmask2 = sqmask[:, NY].ravel() # cross multiply masks #sqd1 *= sqmask2 #sqd2 *= sqmask1 sqdiff = np.abs(sqd2 - sqd1)**2 # test first try convolution and see that it matches with current qphi corr sqdiff = sqd2 * sqd1 sqdiffmask = sqmask1 * sqmask2 sqdiff *= sqdiffmask res = partition_avg(sqdiff, bid_m2) resmask = partition_avg(sqdiffmask, bid_m2) w = np.where(resmask > 1e-6) res[w] /= resmask[w] bins = np.arange(np.max(bid_m2) + 1) sqcphi[bins % noqs, bins // noqs] = res # for i in range(dimy): # for j in range(dimx): # for k in range(dimx): # if(PF is True): # print("iteration {}, {}, {} of {}, {}, {}".format(i,j,k,dimy,dimx,dimx)) # sqcphi[i,k] += np.abs(sq1[i,j] - sq2[i,(j + k)%dimx])**2*sqmask[i,j]*sqmask[i,(j+k)%dimx] # sqcphimask[i,j] += sqmask[i,j]*sqmask[i,(j+k)%dimx] #sqcphi = ifft(fft(sq2,axis=1)*np.conj(fft(sq1,axis=1)),axis=1).real #sqcphimask = ifft(fft(sqmask,axis=1)*np.conj(fft(sqmask,axis=1)),axis=1).real return sq_qs, sq_phis, sqcphi