Beispiel #1
0
def findMaxWithGFit(img, sigma=0.5, win=11):
    '''
    find sub-pixel peaks from input img using n-dimensional Guassian fitting

    sigma: scaler or [simgaZ,sigmaY..]
    window: a window where the Guassian fit is performed on

    return [v, zyx, sigma]
    '''
    imgFit.fitFailedClear()
    vzyx = U.findMax(img)
    ndim = img.ndim
    try:
        ret, check = imgFit.fitGaussianND(img, vzyx[-ndim:], sigma, win)
    except IndexError:  # too close to the edge
        imgFit.fitFailedAppend("at %s" % str(vzyx[-ndim:]))
        sigma = imgFit._scalerToSeq(sigma, ndim)
        return list(vzyx)[0:1] + [vzyx[-ndim:]] + [list(sigma)]

    if check == 5:
        imgFit.fitFailedAppend("at %s, %s, check=%i" %
                               (str(vzyx[-ndim:]), str(ret), check))
        sigma = imgFit._scalerToSeq(sigma, ndim)
        return list(vzyx)[0:1] + [vzyx[-ndim:]] + [sigma]
    else:
        v = ret[1]
        zyx = ret[2:2 + ndim]
        sigma = ret[2 + ndim:2 + ndim * 2]
        return [v, zyx, sigma]
Beispiel #2
0
def findMaxWithGFit(img, sigma=0.5, win=11):
    '''
    find sub-pixel peaks from input img using n-dimensional Guassian fitting

    sigma: scaler or [simgaZ,sigmaY..]
    window: a window where the Guassian fit is performed on

    return [v, zyx, sigma]
    '''
    vzyx = N.array(U.findMax(img))
    ndim = img.ndim
    try:
        ret, check = imgFit.fitGaussianND(img, vzyx[-ndim:], sigma, win)
    except IndexError:  # too close to the edge
        imgFit.fitFailedAppend("at %s" % str(vzyx[-ndim:]))
        sigma = imgFit._scalerToSeq(sigma, ndim)
        return vzyx[0:1], vzyx[-ndim:], list(sigma)

    if check == 5 or N.any(ret[2:2 + ndim] > (vzyx[-ndim:] + win)) or N.any(
            ret[2:2 + ndim] < (vzyx[-ndim:] - win)):
        imgFit.fitFailedAppend("at %s, %s, check=%i" %
                               (str(vzyx[-ndim:]), str(ret), check))
        sigma = imgFit._scalerToSeq(sigma, ndim)
        return [vzyx[0:1], vzyx[-ndim:], sigma]
    #x= (vzyx[0:1] + [vzyx[-ndim:]] + [sigma])
    #    print x
    #    return x
    else:
        v = ret[1]
        zyx = ret[2:2 + ndim]
        sigma = ret[2 + ndim:2 + ndim * 2]
        return [v, zyx, sigma]
Beispiel #3
0
def findMaxWithGFit(img, sigma=0.5, win=11):
    '''
    find sub-pixel peaks from input img using n-dimensional Guassian fitting

    sigma: scaler or [simgaZ,sigmaY..]
    window: a window where the Guassian fit is performed on

    return [v, zyx, sigma]
    '''
    imgFit.fitFailedClear()
    vzyx = U.findMax(img)
    ndim = img.ndim
    try:
        ret, check = imgFit.fitGaussianND(img, vzyx[-ndim:], sigma, win)
    except IndexError: # too close to the edge
        imgFit.fitFailedAppend("at %s" % str(vzyx[-ndim:]))
        sigma = imgFit._scalerToSeq(sigma, ndim)
        return list(vzyx)[0:1] + [vzyx[-ndim:]] + [list(sigma)]

    if check == 5:
        imgFit.fitFailedAppend("at %s, %s, check=%i" % (str(vzyx[-ndim:]), str(ret), check))
        sigma = imgFit._scalerToSeq(sigma, ndim)
        return list(vzyx)[0:1] + [vzyx[-ndim:]] + [sigma]
    else:
        v = ret[1]
        zyx = ret[2:2+ndim]
        sigma = ret[2+ndim:2+ndim*2]
        return [v,zyx,sigma]
Beispiel #4
0
def findMaxWithGFit(img, sigma=0.5, win=11):
    '''
    find sub-pixel peaks from input img using n-dimensional Guassian fitting

    sigma: scaler or [simgaZ,sigmaY..]
    window: a window where the Guassian fit is performed on

    return [v, zyx, sigma]
    '''
    vzyx = N.array(U.findMax(img))
    ndim = img.ndim
    try:
        ret, check = imgFit.fitGaussianND(img, vzyx[-ndim:], sigma, win)
    except IndexError: # too close to the edge
        imgFit.fitFailedAppend("at %s" % str(vzyx[-ndim:]))
        sigma = imgFit._scalerToSeq(sigma, ndim)
        return vzyx[0:1], vzyx[-ndim:], list(sigma)

    if check == 5 or N.any(ret[2:2+ndim] > (vzyx[-ndim:] + win)) or  N.any(ret[2:2+ndim] < (vzyx[-ndim:] - win)):
        imgFit.fitFailedAppend("at %s, %s, check=%i" % (str(vzyx[-ndim:]), str(ret), check))
        sigma = imgFit._scalerToSeq(sigma, ndim)
        return [vzyx[0:1], vzyx[-ndim:], sigma]
    #x= (vzyx[0:1] + [vzyx[-ndim:]] + [sigma])
    #    print x
    #    return x
    else:
        v = ret[1]
        zyx = ret[2:2+ndim]
        sigma = ret[2+ndim:2+ndim*2]
        return [v,zyx,sigma]
Beispiel #5
0
def findMaxWithGFitAll(img, thre=0, sigma_peak=0.5, win=11, mask_npxls=3):
    """
    find peaks until either
    1. any pxls becomes below thre
    2. the same peak was found as the maximum

    mask_npxls: number of pixels to mask when Gaussian fitting failed

    return poslist
    """
    img = img.copy()
    imgFit.fitFailedClear()
    ndim = img.ndim
    sigma_peak = imgFit._scalerToSeq(sigma_peak, ndim)

    poses = []
    vzyx = U.findMax(img)
    while vzyx[0] > thre:
        prev = vzyx
        try:
            ret, check = imgFit.fitGaussianND(img, vzyx[-ndim:], sigma_peak, win)
        except IndexError: # too close to the edge
            imgFit.fitFailedAppend("at %s" % str(vzyx[-ndim:]))
            mask_value(img, vzyx[-ndim:], r=mask_npxls, value=img.min())
            poses.append(list(vzyx)[0:1] + [vzyx[-ndim:]] + [list(sigma_peak)])

        if check == 5:
            imgFit.fitFailedAppend("at %s, %s, check=%i" % (str(vzyx[-ndim:]), str(ret), check))
            mask_value(img, vzyx[-ndim:], r=mask_npxls, value=img.min())
            poses.append(list(vzyx)[0:1] + [vzyx[-ndim:]] + [sigma_peak])
        else:
            v = ret[1]
            zyx = ret[2:2+ndim]
            if N.any(N.abs(zyx - vzyx[1:]) > win/2.):#zyx < 0 or zyx > img.shape or ):
                mask_value(img, vzyx[-ndim:], r=mask_npxls, value=img.min())
                poses.append(list(vzyx)[0:1] + [vzyx[-ndim:]] + [sigma_peak])
            else:
                sigma = ret[2+ndim:2+ndim*2]
                mask_gaussianND(img, zyx, v, sigma)
                poses.append([v,zyx,sigma])

        vzyx = U.findMax(img)
        if N.all(vzyx == prev):
            break
        
    return poses#, img
Beispiel #6
0
def findMaxWithGFitAll(img, thre=0, sigma_peak=0.5, win=11, mask_npxls=3):
    """
    find peaks until either
    1. any pxls becomes below thre
    2. the same peak was found as the maximum

    mask_npxls: number of pixels to mask when Gaussian fitting failed

    return poslist
    """
    img = img.copy()
    imgFit.fitFailedClear()
    ndim = img.ndim
    sigma_peak = imgFit._scalerToSeq(sigma_peak, ndim)

    poses = []
    vzyx = U.findMax(img)
    while vzyx[0] > thre:
        prev = vzyx
        try:
            ret, check = imgFit.fitGaussianND(img, vzyx[-ndim:], sigma_peak,
                                              win)
        except IndexError:  # too close to the edge
            imgFit.fitFailedAppend("at %s" % str(vzyx[-ndim:]))
            mask_value(img, vzyx[-ndim:], r=mask_npxls, value=img.min())
            poses.append(list(vzyx)[0:1] + [vzyx[-ndim:]] + [list(sigma_peak)])

        if check == 5:
            imgFit.fitFailedAppend("at %s, %s, check=%i" %
                                   (str(vzyx[-ndim:]), str(ret), check))
            mask_value(img, vzyx[-ndim:], r=mask_npxls, value=img.min())
            poses.append(list(vzyx)[0:1] + [vzyx[-ndim:]] + [sigma_peak])
        else:
            v = ret[1]
            zyx = ret[2:2 + ndim]
            sigma = ret[2 + ndim:2 + ndim * 2]
            mask_gaussianND(img, zyx, v, sigma)
            poses.append([v, zyx, sigma])

        vzyx = U.findMax(img)
        if N.all(vzyx == prev):
            break

    return poses  #, img
Beispiel #7
0
def fitSkew1D(img, ts=None, sigma=0.5, exp=0):
    """
    img: 1D array containg one skewd gaussian peak
    """
    mi, ma, me, sd = U.mmms(img)
    ma, _1, _2, t = U.findMax(img)
    if ts is not None:
        t = ts[t]
        img = list(zip(ts, img))

    return U.fitAny(ySkew, (mi, ma - mi, t, sigma, exp), img, warning=None)
Beispiel #8
0
def fitSkew1D(img, ts=None, sigma=0.5, exp=0):
    """
    img: 1D array containg one skewd gaussian peak
    """
    mi, ma, me, sd = U.mmms(img)
    ma, _1, _2, t = U.findMax(img)
    if ts is not None:
        t = ts[t]
        img = list(zip(ts, img))

    return U.fitAny(ySkew, (mi, ma-mi, t, sigma, exp), img, warning=None)
Beispiel #9
0
def _findMaxXcor(c, win, gFit=True, niter=2):
    if gFit:
        for i in range(niter):
            v, zyx, s = findMaxWithGFit(c, win=win + (i * 2))
            if v:
                if N.any(zyx > N.array(c.shape)) or N.any(zyx < 0):
                    vzyx = N.array(U.findMax(c))  #continue
                    v = vzyx[0]
                    zyx = vzyx[-c.ndim:] + 0.5  # pixel center
                    s = 2.5
                else:
                    break

        if not v:
            v = U.findMax(c)[0]
    else:
        vzyx = U.findMax(c)
        v = vzyx[0]
        zyx = N.array(vzyx[-c.ndim:]) + 0.5  # pixel center
        s = 2.5
    return v, zyx, s
Beispiel #10
0
def _findMaxXcor(c, win, gFit=True, niter=2):
    if gFit:
        for i in range(niter):
            v, zyx, s = findMaxWithGFit(c, win=win+(i*2))
            if v:
                if N.any(zyx > N.array(c.shape)) or N.any(zyx < 0):
                    vzyx = N.array(U.findMax(c))#continue
                    v = vzyx[0]
                    zyx = vzyx[-c.ndim:] + 0.5 # pixel center
                    s = 2.5
                else:
                    break

        if not v:
            v = U.findMax(c)[0]
    else:
        vzyx = U.findMax(c)
        v = vzyx[0]
        zyx = N.array(vzyx[-c.ndim:]) + 0.5 # pixel center
        s = 2.5
    return v, zyx, s
Beispiel #11
0
def chopYX(shapeYX, ncpu=8):
    """
    return axis, YXmmlist
    """
    n, _1, _2, axis = U.findMax(shapeYX)
    n0 = n // ncpu
    mms = []
    pixel = 0
    for cpu in range(ncpu):
        mms += [[pixel, pixel + n0]]
        pixel += n0
    mms[-1][-1] = n
    return axis, mms
Beispiel #12
0
def chopYX(shapeYX, ncpu=8):
    """
    return axis, YXmmlist
    """
    n, _1, _2, axis = U.findMax(shapeYX)
    n0 = n // ncpu
    mms = []
    pixel = 0
    for cpu in range(ncpu):
        mms += [[pixel, pixel + n0]]
        pixel += n0
    mms[-1][-1] = n
    return axis, mms
Beispiel #13
0
def testCorrelation(arr, win=64):
    from Priithon.all import U
    half = win / 2.
    arr = arr.copy()
    for i in range(10):
        v, z, y, x = U.findMax(arr)
        if y - half >= 0 and y + half < arr.shape[
                0] and x - half >= 0 and x + half < arr.shape[1]:
            a = arr[y - half:y + half, x - half:x + half]
            break
        else:
            arr[y, x] = 0
    b = a.copy()
    yx, c = xcorr.Xcorr(a, b, phaseContrast=True)
    cme = c[:c.shape[0] // 4].mean()
    return c.max() - cme
Beispiel #14
0
def Xcorr(a, b, highpassSigma=2.5, wiener=0.2, cutoffFreq=3,
forceSecondPeak=None, acceptOrigin=True, maskSigmaFact=1., removeY=None, removeX=None, ret=None, normalize=True, gFit=True, lap=None, win=11):
    """
    returns (y,x), image
    if ret is True, returns [v, yx, image]

    to get yx cordinate of the image,
    yx += N.divide(picture.shape, 2)

    a, b:            2D array
    highpassSigma:   sigma value used for highpass pre-filter
    wiener:          wiener value used for highpass pre-filter
    cutoffFreq:      kill lowest frequency component from 0 to this level
    forceSecondPeak: If input is n>0 (True is 1), pick up n-th peak
    acceptOrigin:    If None, result at origin is rejected, look for the next peak
    maskSigmaFact:   Modifier to remove previous peak to look for another peak
    removeYX:        Rremove given number of pixel high intensity lines of the Xcorr
                     Y: Vertical, X: Horizontal
    normalize:       intensity normalized
    gFit:            peak is fitted to 2D gaussian array, if None use center of mass
    win:             window for gFit

    if b is a + (y,x) then, answer is (-y,-x)
    """
    shapeA = N.asarray(a.shape)
    shapeB = N.asarray(b.shape)
    shapeM = N.max([shapeA, shapeB], axis=0)
    shapeM = N.where(shapeM % 2, shapeM+1, shapeM)
    center = shapeM / 2.

    arrs = [a,b]
    arrsS = ['a','b']
    arrsF = []
    for i, arr in enumerate(arrs):
        if arr.dtype not in [N.float32, N.float64]:
            arr = N.asarray(arr, N.float32)
        # this convolution has to be done beforehand to remove 2 pixels at the edge
        if lap == 'nothing':
            pass
        elif lap:
            arr = arr_Laplace(arr, mask=2)
        else:
            arr = arr_sorbel(arr, mask=1)
    
        if N.sometrue(shapeA < shapeM):
            arr = paddingMed(arr, shapeM)

        if normalize:
            mi, ma, me, sd = U.mmms(arr)
            arr = (arr - me) / sd
    
        if i ==1:
            arr = F.shift(arr)
        af = F.rfft(arr)

        af = highPassF(af, highpassSigma, wiener, cutoffFreq)
        arrsF.append(af)

    # start cross correlation
    af, bf = arrsF
    bf = bf.conjugate()
    cf = af * bf

    # go back to space domain
    c = F.irfft(cf)
  #  c = _changeOrigin(cr)

    # removing lines
    if removeX:
        yi, xi = N.indices((removeX, shapeM[-1]))#sx))
        yi += center[-2] - removeX/2.#sy/2 - removeX/2
        c[yi, xi] = 0
    if removeY:
        yi, xi = N.indices((shapeM[-2], removeY))#sy, removeY))
        xi += center[-1] - removeY/2.#sx/2 - removeY/2
        c[yi, xi] = 0

    # find the first peak
    if gFit:
        v, yx, s = findMaxWithGFit(c, win=win)#, window=win, gFit=gFit)
        if v == 0:
            v, yx, s = findMaxWithGFit(c, win=win+2)#, window=win+2, gFit=gFit)
            if v == 0:
                v = U.findMax(c)[0]
        yx = N.add(yx, 0.5)
        #yx += 0.5
    else:
        vzyx = U.findMax(c)
        v = vzyx[0]
        yx = vzyx[-2:]
        s = 2.5

    yx -= center

    if N.alltrue(N.abs(yx) < 1.0) and not acceptOrigin:
        forceSecondPeak = True

    # forceSecondPeak:
    if not forceSecondPeak:
        forceSecondPeak = 0
    for i in range(int(forceSecondPeak)):
        print('%i peak was removed' % (i+1)) #, sigma: %.2f' % (i+1, s)
        yx += center
        g = gaussianArr2D(c.shape, sigma=s/maskSigmaFact, peakVal=v, orig=yx)
        c = c - g
        #c = mask_gaussian(c, yx[0], yx[1], v, s)
        if gFit:
            v, yx, s = findMaxWithGFit(c, win=win)#, window=win, gFit=gFit)
            if v == 0:
                v, yx, s = findMaxWithGFit(c, win=win+2)#, window=win+2, gFit=gFit)
                if v == 0:
                    v = U.findMax(c)[0]
            yx -= (center - 0.5)
        else:
            vzyx = U.findMax(c)
            v = vzyx[0]

    if not gFit:
        yx = centerOfMass(c, vzyx[-2:]) - center
    if lap is not 'nothing':
        c = paddingValue(c, shapeM+2)

    if ret == 2:
        return yx, af, bf.conjugate()
    elif ret:
        return v, yx, c
    else:
        return yx, c
Beispiel #15
0
def Xcorr(a,
          b,
          highpassSigma=2.5,
          wiener=0.2,
          cutoffFreq=3,
          forceSecondPeak=None,
          acceptOrigin=True,
          maskSigmaFact=1.,
          removeY=None,
          removeX=None,
          ret=None,
          normalize=True,
          gFit=True,
          lap=None,
          win=11):
    """
    returns (y,x), image
    if ret is True, returns [v, yx, image]

    to get yx cordinate of the image,
    yx += N.divide(picture.shape, 2)

    a, b:            2D array
    highpassSigma:   sigma value used for highpass pre-filter
    wiener:          wiener value used for highpass pre-filter
    cutoffFreq:      kill lowest frequency component from 0 to this level
    forceSecondPeak: If input is n>0 (True is 1), pick up n-th peak
    acceptOrigin:    If None, result at origin is rejected, look for the next peak
    maskSigmaFact:   Modifier to remove previous peak to look for another peak
    removeYX:        Rremove given number of pixel high intensity lines of the Xcorr
                     Y: Vertical, X: Horizontal
    normalize:       intensity normalized
    gFit:            peak is fitted to 2D gaussian array, if None use center of mass
    win:             window for gFit

    if b is a + (y,x) then, answer is (-y,-x)
    """
    shapeA = N.asarray(a.shape)
    shapeB = N.asarray(b.shape)
    shapeM = N.max([shapeA, shapeB], axis=0)
    shapeM = N.where(shapeM % 2, shapeM + 1, shapeM)
    center = shapeM / 2.

    arrs = [a, b]
    arrsS = ['a', 'b']
    arrsF = []
    for i, arr in enumerate(arrs):
        if arr.dtype not in [N.float32, N.float64]:
            arr = N.asarray(arr, N.float32)
        # this convolution has to be done beforehand to remove 2 pixels at the edge
        if lap == 'nothing':
            pass
        elif lap:
            arr = arr_Laplace(arr, mask=2)
        else:
            arr = arr_sorbel(arr, mask=1)

        if N.sometrue(shapeA < shapeM):
            arr = paddingMed(arr, shapeM)

        if normalize:
            mi, ma, me, sd = U.mmms(arr)
            arr = (arr - me) / sd

        if i == 1:
            arr = F.shift(arr)
        af = F.rfft(arr)

        af = highPassF(af, highpassSigma, wiener, cutoffFreq)
        arrsF.append(af)

    # start cross correlation
    af, bf = arrsF
    bf = bf.conjugate()
    cf = af * bf

    # go back to space domain
    c = F.irfft(cf)
    #  c = _changeOrigin(cr)

    # removing lines
    if removeX:
        yi, xi = N.indices((removeX, shapeM[-1]))  #sx))
        yi += center[-2] - removeX / 2.  #sy/2 - removeX/2
        c[yi, xi] = 0
    if removeY:
        yi, xi = N.indices((shapeM[-2], removeY))  #sy, removeY))
        xi += center[-1] - removeY / 2.  #sx/2 - removeY/2
        c[yi, xi] = 0

    # find the first peak
    if gFit:
        v, yx, s = findMaxWithGFit(c, win=win)  #, window=win, gFit=gFit)
        if v == 0:
            v, yx, s = findMaxWithGFit(c, win=win +
                                       2)  #, window=win+2, gFit=gFit)
            if v == 0:
                v = U.findMax(c)[0]
        yx = N.add(yx, 0.5)
        #yx += 0.5
    else:
        vzyx = U.findMax(c)
        v = vzyx[0]
        yx = vzyx[-2:]
        s = 2.5

    yx -= center

    if N.alltrue(N.abs(yx) < 1.0) and not acceptOrigin:
        forceSecondPeak = True

    # forceSecondPeak:
    if not forceSecondPeak:
        forceSecondPeak = 0
    for i in range(int(forceSecondPeak)):
        print('%i peak was removed' % (i + 1))  #, sigma: %.2f' % (i+1, s)
        yx += center
        g = gaussianArr2D(c.shape, sigma=s / maskSigmaFact, peakVal=v, orig=yx)
        c = c - g
        #c = mask_gaussian(c, yx[0], yx[1], v, s)
        if gFit:
            v, yx, s = findMaxWithGFit(c, win=win)  #, window=win, gFit=gFit)
            if v == 0:
                v, yx, s = findMaxWithGFit(c, win=win +
                                           2)  #, window=win+2, gFit=gFit)
                if v == 0:
                    v = U.findMax(c)[0]
            yx -= (center - 0.5)
        else:
            vzyx = U.findMax(c)
            v = vzyx[0]

    if not gFit:
        yx = centerOfMass(c, vzyx[-2:]) - center
    if lap is not 'nothing':
        c = paddingValue(c, shapeM + 2)

    if ret == 2:
        return yx, af, bf.conjugate()
    elif ret:
        return v, yx, c
    else:
        return yx, c
Beispiel #16
0
def beads_analyzeBeads(fn,
                       thre_sigma=1.,
                       refwave=2,
                       nbeads=60,
                       win=5,
                       maxdist=600,
                       maxrefdist=5):  #0.6, maxrefdist=0.005):
    """
    maxdist: nm
    maxrefdist: nm

    return dic
    """
    from PriCommon import mrcIO, imgFilters, imgFit, imgGeo, microscope
    from Priithon.all import Y
    h = mrcIO.MrcReader(fn)
    if refwave >= h.nw:
        raise ValueError, 'reference wave does not exists'
    shape = h.hdr.Num[::-1].copy()
    shape[0] /= (h.hdr.NumTimes * h.hdr.NumWaves)
    pzyx = h.hdr.d[::-1]

    NA = 1.35
    difflimitYX = microscope.resolution(NA, h.hdr.wave[refwave]) / 1000.
    difflimit = N.array([difflimitYX * 2, difflimitYX, difflimitYX]) / pzyx
    print 'diffraction limit (px) is:', difflimit
    simres = difflimit / 1.5  #2.

    arr = h.get3DArr(w=refwave).copy()
    ndim = arr.ndim
    me = arr.mean()
    sd = arr.std()
    thre = me + sd * thre_sigma
    sigma = 1.5

    zyxs = []
    #found = []
    sigmas = []
    i = 0
    pmax = 0
    failed = 0
    while i < nbeads:
        Y.refresh()
        amax, z, y, x = U.findMax(arr)
        zyx = N.array((z, y, x), N.float32)
        #found.append(zyx)
        zyx0 = N.where(zyx > simres, zyx - simres, 0).astype(N.int)
        zyx1 = N.where(zyx + simres < shape, zyx + simres, shape).astype(N.int)
        rmslice = [slice(*zyx) for zyx in zip(zyx0, zyx1)]

        if failed > 10:
            raise RuntimeError
            break
        elif amax == pmax:
            arr[rmslice] = me
        elif amax > thre:
            # Gaussian fitting
            try:
                ret, check = imgFit.fitGaussianND(arr, [z, y, x][-ndim:],
                                                  sigma, win)
            except IndexError:  # too close to the edge
                arr[rmslice] = me
                print 'Index Error, too close to the edge', z, y, x
                failed += 1
                continue
            if check == 5:
                arr[rmslice] = me
                print 'fit failed', z, y, x
                failed += 1
                continue

            # retreive results
            v = ret[1]
            zyx = ret[2:2 + ndim]
            sigma = ret[2 + ndim:2 + ndim * 2]
            if any(sigma) < 1:
                sigma = N.where(sigma < 1, 1, sigma)

            # check if the result is inside the image
            if N.any(zyx < 0) or N.any(zyx > (shape)):
                print 'fitting results outside the image', zyx, z, y, x, rmslice
                arr[rmslice] = me
                failed += 1
                continue  # too close to the edge

            # remove the point
            imgFilters.mask_gaussianND(arr, zyx, v, sigma)

            # check if the bead is too close to the exisisting ones
            skipped = """
            if len(found):#zyxs):
                close = imgGeo.closeEnough(zyx, found, difflimit*2)#zyxs, difflimit*2)
                if N.any(close):
                    if len(zyxs):
                        close = imgGeo.closeEnough(zyx, zyxs, difflimit*2)
                        if N.any(close):
                            idx = close.argmax()
                            already = zyxs.pop(idx)
                            #print 'too close', zyx, already
                    print 'found in the previous list'
                    continue"""

            # remove beads too close to the edge
            if N.any(zyx < 2) or N.any(zyx > (shape - 2)):
                print 'too close to the edge', zyx
                if N.any(arr[rmslice] > thre):
                    arr[rmslice] = me
                failed += 1
                continue  # too close to the edge

            # remove beads with bad shape
            elif N.any(sigma < 0.5) or N.any(sigma > 3):
                print 'sigma too different from expected', sigma, zyx
                if N.any(arr[rmslice] > thre):
                    arr[rmslice] = me
                sigma = 1.5
                failed += 1
                continue

            old = """
            # remove beads too elliptic
            elif sigma[1] / sigma[2] > 1.5 or sigma[2] / sigma[1] > 1.5:
                print 'too elliptic', sigma[2] / sigma[1]
                if N.any(arr[rmslice] > thre):
                    arr[rmslice] = me
                    #if (sigma[2] / sigma[1]) > 20:
                    #raise ValueError
                sigma = 1.5
                failed += 1
                continue

            elif N.any(sigma[-2:] > 3.0):
                print 'sigma too large', sigma, zyx
                if N.any(arr[rmslice] > thre):
                    arr[rmslice] = me
                sigma = 1.5
                failed += 1
                continue

            elif sigma[0] < 0.5 or sigma[0] > 3:
                print 'sigma z too different from expected', sigma, zyx
                if N.any(arr[rmslice] > thre):
                    arr[rmslice] = me
                sigma = 1.5
                failed += 1
                continue


            #elif imgGeo.closeEnough(zyx, N.array((17,719,810), N.float32), 4):
            #    raise RuntimeError"""

            # add results
            zyxs.append(zyx)
            sigmas.append(sigma)
            i += 1
            pmax = amax
            failed = 0
            #print i

        # maximum is below threshold
        else:
            break
    del arr

    sigmas = N.array(sigmas)
    sigmaYX = N.mean(sigmas[:, 1:], axis=1)
    sigmaZ = sigmas[:, 0]
    idxyx = sigmaYX.argmax()
    idxz = sigmaZ.argmax()
    print 'sigmaYX', round(sigmaYX.mean(),
                           3), round(sigmaYX.min(),
                                     3), round(sigmaYX.std(),
                                               3), round(sigmaYX.max(),
                                                         3), zyxs[idxyx]
    print 'sigmaZ', round(sigmaZ.mean(),
                          3), round(sigmaZ.min(),
                                    3), round(sigmaZ.std(),
                                              3), round(sigmaZ.max(),
                                                        3), zyxs[idxz]

    # remove overlaps
    zyxs2 = []
    zyxs = N.array(zyxs)
    for i, zyx in enumerate(zyxs):
        close = imgGeo.closeEnough(zyx, zyxs, difflimit * 4)
        if not N.any(close[:i]) and not N.any(close[i + 1:]):
            #idx = close.argmax()
            #already = zyxs.pop(idx)
            zyxs2.append(zyx)
    zyxs = zyxs2

    waves = range(h.nw)
    #waves.remove(refwave)

    difdic = {}
    removes = []

    checks = 0
    zeros = 0
    toofars = 0

    pzyx *= 1000

    for w in waves:
        if w == refwave:
            continue
        arr = h.get3DArr(w=w)
        #me = arr.mean()
        #sd = arr.std()
        #thre = me + sd * thre_sigma

        for zyx in zyxs:
            key = tuple(zyx * pzyx)
            if key in removes:
                continue

            #win0 = win
            #while win0 >= 3:
            try:
                ret, check = imgFit.fitGaussianND(arr,
                                                  zyx,
                                                  sigma=sigma,
                                                  window=win)  #0)
                #break
            except (IndexError, ValueError):
                ret = zyx
                check = 5
                #win0 -= 2
                #ret, check = imgFit.fitGaussianND(arr, zyx, sigma=sigma, window=3)

            dif = (zyx - ret[2:5]) * pzyx
            if check == 5 or (
                    w != refwave and N.any(N.abs(dif) > maxdist)) or (
                        w == refwave and N.any(N.abs(dif) > maxrefdist)
                    ):  #(N.all(dif == 0) or N.any(N.abs(dif) > maxdist))):
                if check == 5:
                    checks += 1
                    #elif N.all(dif == 0):
                    #zeros += 1
                elif w == refwave and N.any(N.abs(dif) > maxrefdist):
                    zeros += 1
                elif N.any(N.abs(dif) > maxdist):
                    toofars += 1
                #if N.any(N.abs(dif) > maxdist):
                #    raise ValueError
                #raise RuntimeError
                removes.append(key)
                if difdic.has_key(key):
                    del difdic[key]
                #elif not N.sum(dif) or N.any(dif > 10):
                #raise RuntimeError, 'something is wrong'
            else:
                difdic.setdefault(key, [])
                difdic[key].append(dif)
                sigma = ret[5:8]
                #del arr

    h.close()
    del arr
    del h

    print 'check:', checks, 'zeros:', zeros, 'toofars', toofars

    # subtracting the center
    newdic = {}
    keys = difdic.keys()
    newkeys = N.array(keys)
    zmin = N.min(newkeys[:, 0])
    center = (shape * pzyx) / 2.
    #yx0 = (N.max(newkeys[:,1:], axis=0) - N.min(newkeys[:,1:], axis=0)) / 2.
    newkeys[:, 0] -= zmin
    newkeys[:, 1:] -= center[1:]  #yx0
    newkeys = [tuple(key) for key in newkeys]

    items = [difdic[key] for key in keys]
    newdic = dict(zip(newkeys, items))
    difdic = newdic

    # plot
    P.figure(0, figsize=(8, 8))
    keys = N.array(difdic.keys())
    P.hold(0)
    P.scatter(keys[:, 2], keys[:, 1], alpha=0.5)
    P.xlabel('X (nm)')
    P.ylabel('Y (nm)')
    P.savefig(fn + '_fig0.png')

    return difdic  #, shape