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
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
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
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
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
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)
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)