예제 #1
0
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
예제 #2
0
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
예제 #3
0
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
예제 #4
0
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
예제 #5
0
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
예제 #6
0
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
예제 #7
0
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