Exemplo n.º 1
0
def stdUnderMask(volume, mask, p, meanV):
    """
    stdUnderMask: calculate the std volume under the given mask
    @param volume: input volume
    @type volume:  L{pytom_volume.vol}
    @param mask: mask
    @type mask:  L{pytom_volume.vol}
    @param p: non zero value numbers in the mask
    @type p: L{int}
    @param meanV: mean volume under mask, which should already been caculated
    @type meanV:  L{pytom_volume.vol}
    @return: the calculated std volume under mask
    @rtype:  L{pytom_volume.vol}
    @author: Yuxiang Chen
    """
    from pytom.basic.fourier import fft, ifft, iftshift
    from pytom_volume import vol, power, limit
    
    copyV = vol(volume.sizeX(), volume.sizeY(), volume.sizeZ())
    copyV.copyVolume(volume)
    power(copyV, 2) #calculate the square of the volume
    
    copyMean = vol(meanV.sizeX(), meanV.sizeY(), meanV.sizeZ())
    copyMean.copyVolume(meanV)
    power(copyMean, 2)

    result = meanUnderMask(copyV, mask, p) - copyMean

#    from pytom_volume import abs
#    abs(result)
    limit(result, 1e-09, 1, 0, 0, True, False) # this step is needed to set all those value (close to 0) to 1
    power(result, 0.5)

    return result
Exemplo n.º 2
0
def rotateWeighting(weighting, z1, z2, x, mask=None, isReducedComplex=None, returnReducedComplex=False, binarize=False):
    """
    rotateWeighting: Rotates a frequency weighting volume around the center. If the volume provided is reduced complex, it will be rescaled to full size, ftshifted, rotated, iftshifted and scaled back to reduced size.
    @param weighting: A weighting volume
    @type weighting: L{pytom_volume.vol}
    @param z1: Z1 rotation angle
    @type z1: float
    @param z2: Z2 rotation angle
    @type z2: float
    @param x: X rotation angle
    @type x: float
    @param mask:=None is there a rotation mask? A mask with all = 1 will be generated otherwise. Such mask should be \
        provided anyway.
    @type mask: L{pytom_volume.vol}
    @param isReducedComplex: Either set to True or False. Will be determined otherwise
    @type isReducedComplex: bool
    @param returnReducedComplex: Return as reduced complex? (Default is False)
    @type returnReducedComplex: bool
    @param binarize: binarize weighting
    @type binarize: bool
    @return: weight as reduced complex volume
    @rtype: L{pytom_volume.vol_comp}
    """
    from pytom_volume import vol, limit, vol_comp
    from pytom_volume import rotate
    assert type(weighting) == vol or  type(weighting) == vol_comp, "rotateWeighting: input neither vol nor vol_comp"
    
    isReducedComplex = isReducedComplex or int(weighting.sizeX()/2)+1 == weighting.sizeZ();

    if isReducedComplex:
        #scale weighting to full size
        from pytom_fftplan import fftShift
        from pytom_volume import reducedToFull
        weighting = reducedToFull(weighting)
        fftShift(weighting, True)

    if not mask:
        mask = vol(weighting.sizeX(),weighting.sizeY(),weighting.sizeZ())
        mask.setAll(1)

    weightingRotated = vol(weighting.sizeX(),weighting.sizeY(),weighting.sizeZ())

    rotate(weighting,weightingRotated,z1,z2,x)
    weightingRotated = weightingRotated * mask
    
    if returnReducedComplex:
        from pytom_fftplan import fftShift
        from pytom_volume import fullToReduced
        fftShift(weightingRotated,True)
        returnVolume = fullToReduced(weightingRotated)
    else:
        returnVolume = weightingRotated

    if binarize:
        limit(returnVolume,0.5,0,0.5,1,True,True)
    
    return returnVolume
Exemplo n.º 3
0
    def create_average(self, pre, wedge):
        """For the master node, create the average according to the pre-wedge and wedge volumes.
        """
        from pytom_volume import complexDiv, limit
        from pytom.basic.fourier import fft, ifft

        limit(wedge, 0.1, 0, 0, 0, True,
              False)  # set all the values below the specified value to 0

        f_pre = fft(pre)
        r = complexDiv(f_pre, wedge)
        average = ifft(r)
        average.shiftscale(
            0.0,
            1 / float(average.sizeX() * average.sizeY() * average.sizeZ()))

        return average
Exemplo n.º 4
0
    def create_average(self, pre, wedge):
        """For the master node, create the average according to the pre-wedge and wedge volumes.
           @param pre: density prior to weighting
           @type pre: L{pytom_volume.vol}
           @param wedge: wedge 
           @type wedge: L{pytom.basic.Wedge}
           @return: wedge-weighted density
           @rtype: L{pytom_volume.vol}
        """
        from pytom_volume import complexDiv, limit
        from pytom.basic.fourier import fft, ifft

        limit(wedge, 0.1, 0, 0, 0, True,
              False)  # set all the values below the specified value to 0

        f_pre = fft(pre)
        r = complexDiv(f_pre, wedge)
        average = ifft(r)
        average.shiftscale(
            0.0,
            1 / float(average.sizeX() * average.sizeY() * average.sizeZ()))

        return average
Exemplo n.º 5
0
    def create_average(self, sum_ctf_conv, sum_ctf_squared, wedge_weight):
        """For the master node, this function is rewritten.
        """
        from pytom_volume import vol, complexDiv, fullToReduced, initSphere, complexRealMult, limit
        from pytom.basic.fourier import fft, ifft, ftshift
        from pytom.basic.normalise import mean0std1

        limit(wedge_weight, 0.1, 0, 0, 0, True,
              False)  # set all the values below the specified value to 0

        # for mask out the outside area
        #        mask = vol(sum_ctf_conv)
        #        mask.setAll(0)
        #        initSphere(mask, sum_ctf_conv.sizeX()/2-1, 0,0, sum_ctf_conv.sizeX()/2, sum_ctf_conv.sizeX()/2, sum_ctf_conv.sizeX()/2)
        #        mask = fullToReduced(ftshift(mask, inplace=False))

        # Wiener filter
        numerator = fft(sum_ctf_conv)
        sum_ctf_squared = fullToReduced(ftshift(sum_ctf_squared,
                                                inplace=False))
        denominator = (sum_ctf_squared + 1) * wedge_weight
        r = complexDiv(numerator, denominator)
        #        average = ifft(complexRealMult(r, mask))
        average = ifft(r)
        average.shiftscale(
            0.0,
            1 / float(average.sizeX() * average.sizeY() * average.sizeZ()))

        # nomalize the average
        try:
            average = mean0std1(average, True)
        except:
            average *= 1000  # in case the average volume is too small to normalize
            average = mean0std1(average, True)

        return average
Exemplo n.º 6
0
def calculate_difference_map(v1,
                             band1,
                             v2,
                             band2,
                             mask=None,
                             focus_mask=None,
                             align=True,
                             sigma=None,
                             threshold=0.4):
    """mask if for alignment, while focus_mask is for difference map.
    """
    from pytom_volume import vol, power, abs, limit, transformSpline, variance, mean, max, min
    from pytom.basic.normalise import mean0std1
    from pytom.basic.filter import lowpassFilter

    # do lowpass filtering first
    lv1 = lowpassFilter(v1, band1, band1 / 10.)[0]
    lv2 = lowpassFilter(v2, band2, band2 / 10.)[0]

    # do alignment of two volumes, if required. v1 is used as reference.
    if align:
        from sh_alignment.frm import frm_align
        band = int(band1 if band1 < band2 else band2)
        pos, angle, score = frm_align(lv2, None, lv1, None, [4, 64], band,
                                      lv1.sizeX() // 4, mask)
        shift = [
            pos[0] - v1.sizeX() // 2, pos[1] - v1.sizeY() // 2,
            pos[2] - v1.sizeZ() // 2
        ]

        # transform v2
        lvv2 = vol(lv2)
        transformSpline(lv2, lvv2, -angle[1], -angle[0], -angle[2],
                        lv2.sizeX() // 2,
                        lv2.sizeY() // 2,
                        lv2.sizeZ() // 2, -shift[0], -shift[1], -shift[2], 0,
                        0, 0)
    else:
        lvv2 = lv2

    # do normalization
    mean0std1(lv1)
    mean0std1(lvv2)

    # only consider the density beyond certain sigma
    if sigma is None or sigma == 0:
        pass
    elif sigma < 0:  # negative density counts
        assert min(lv1) < sigma
        assert min(lvv2) < sigma
        limit(lv1, 0, 0, sigma, 0, False, True)
        limit(lvv2, 0, 0, sigma, 0, False, True)
    else:  # positive density counts
        assert max(lv1) > sigma
        assert max(lvv2) > sigma
        limit(lv1, sigma, 0, 0, 0, True, False)
        limit(lvv2, sigma, 0, 0, 0, True, False)

    # if we want to focus on specific area only
    if focus_mask:
        lv1 *= focus_mask
        lvv2 *= focus_mask

    # calculate the STD map
    avg = (lv1 + lvv2) / 2
    var1 = avg - lv1
    power(var1, 2)
    var2 = avg - lvv2
    power(var2, 2)

    std_map = var1 + var2
    power(std_map, 0.5)

    # calculate the coefficient of variance map
    # std_map = std_map/abs(avg)

    if focus_mask:
        std_map *= focus_mask

    # threshold the STD map
    mv = mean(std_map)
    threshold = mv + (max(std_map) - mv) * threshold
    limit(std_map, threshold, 0, threshold, 1, True, True)

    # do a lowpass filtering
    std_map1 = lowpassFilter(std_map, v1.sizeX() // 4, v1.sizeX() / 40.)[0]

    if align:
        std_map2 = vol(std_map)
        transformSpline(std_map1, std_map2, angle[0], angle[1], angle[2],
                        v1.sizeX() // 2,
                        v1.sizeY() // 2,
                        v1.sizeZ() // 2, 0, 0, 0, shift[0], shift[1], shift[2])
    else:
        std_map2 = std_map1

    limit(std_map1, 0.5, 0, 1, 1, True, True)
    limit(std_map2, 0.5, 0, 1, 1, True, True)

    # return the respective difference maps
    return (std_map1, std_map2)
Exemplo n.º 7
0
    def maskOut(self, mask, center, size):
        """
        maskOut: Set part of mask volume to all zero. The region is specified by center and size.
        @param mask: volume that you handle with
        @type mask: L{pytom_volume.vol}
        @param center: center of the region
        @type center: [x,y,z]
        @param size: size of the region
        @type size: [sizeX, sizeY, sizeZ] or radius
        """

        from pytom_volume import vol, putSubVolume

        if size.__class__ == list:
            p_sizeX = size[0]
            p_sizeY = size[1]
            p_sizeZ = size[2]
        elif size.__class__ == vol:
            mm = size
            p_sizeX = mm.sizeX()
            p_sizeY = mm.sizeY()
            p_sizeZ = mm.sizeZ()
        else:
            radius = size
            p_sizeX = radius * 2
            p_sizeY = radius * 2
            p_sizeZ = radius * 2

        maskSize = [mask.sizeX(), mask.sizeY(), mask.sizeZ()]

        if maskSize < center:
            raise RuntimeError('Center out of range!')

        # [)
        # mask out double size. CHANGED!!!
        startX = int(center[0] - p_sizeX / 2)
        endX = int(center[0] + p_sizeX / 2)
        startY = int(center[1] - p_sizeY / 2)
        endY = int(center[1] + p_sizeY / 2)
        startZ = int(center[2] - p_sizeZ / 2)
        endZ = int(center[2] + p_sizeZ / 2)

        # only used for radius
        sub_startX = 0
        sub_startY = 0
        sub_startZ = 0

        if startX < 0:
            sub_startX = -startX
            startX = 0
        if endX > maskSize[0]:
            endX = maskSize[0]
        if startY < 0:
            sub_startY = -startY
            startY = 0
        if endY > maskSize[1]:
            endY = maskSize[1]
        if startZ < 0:
            sub_startZ = -startZ
            startZ = 0
        if endZ > maskSize[2]:
            endZ = maskSize[2]

        sizeX = endX - startX
        sizeY = endY - startY
        sizeZ = endZ - startZ

        if size.__class__ == list:
            subV = vol(sizeX, sizeY, sizeZ)
            subV.setAll(0)
        elif size.__class__ == vol:
            from pytom_volume import limit, subvolume
            subV = (mm - 1) / -1
            limit(subV, 0.999, 0, 0, 0, True, False)
            subV = subvolume(subV, sub_startX, sub_startY, sub_startZ, sizeX,
                             sizeY, sizeZ)
            tempV = subvolume(mask, startX, startY, startZ, sizeX, sizeY,
                              sizeZ)
            subV = subV * tempV  # AND operation
        else:
            from pytom_volume import initSphere, subvolume
            subV = vol(radius * 2, radius * 2, radius * 2)
            initSphere(subV, radius, 0, 0, radius, radius, radius)
            tempV = vol(radius * 2, radius * 2, radius * 2)
            tempV.setAll(1)
            subV = tempV - subV
            subV = subvolume(subV, sub_startX, sub_startY, sub_startZ, sizeX,
                             sizeY, sizeZ)
            tempV = subvolume(mask, startX, startY, startZ, sizeX, sizeY,
                              sizeZ)
            subV = subV * tempV  # AND operation

        putSubVolume(subV, mask, startX, startY, startZ)