def subtractMeanUnderMask(volume, mask): """ subtract mean from volume/image under mask @param volume: volume/image @type volume: L{pytom_volume.vol} @param mask: mask @type mask: L{pytom_volume.vol} @return: volume/image @rtype: L{pytom_volume.vol} """ # npix = volume.sizeX() * volume.sizeY() * volume.sizeZ() normvol = volume * mask normvol = xp.sum(normvol) / xp.sum(mask) return normvol
def normaliseUnderMask(volume, mask, p=None): """ normalize volume within a mask - take care: only normalization, but NOT multiplication with mask! @param volume: volume for normalization @type volume: pytom volume @param mask: mask @type mask: pytom volume @param p: sum of gray values in mask (if pre-computed) @type p: C{int} or C{float} @return: volume normalized to mean=0 and std=1 within mask, p @rtype: C{list} @author: FF """ from pytom.tompy.correlation import meanUnderMask, stdUnderMask # from math import sqrt if not p: p = xp.sum(mask) print(p) # meanT = sum(volume) / p ## subtract mean and mask # res = mask * (volume - meanT) # stdT = sum(res*res) / p # stdT = sqrt(stdT) # res = res / stdT meanT = meanUnderMask(volume, mask, p) stdT = stdUnderMask(volume, mask, meanT, p) print(meanT, stdT) res = (volume - meanT) / stdT return (res, p)
def normalised_cross_correlation_mask(first, second, mask): """ Do cross correlation with a running mask based on numpy @param first: The first dataset (numpy 2D) @type first: numpy array 2D @param second: The second dataset (numpy 2D) @type second: numpy array 2D @param mask: The mask @type mask: numpy array 2D @return: The cross correlation result @returntype: numpy array 2D @requires: the shape of first to be equal to the shape of second and the shape of the mask """ # assert first.shape == second.shape # assert first.shape == mask.shape # assert len(first.shape) == 2 import xp.fft as nf a = norm_inside_mask(first, mask) b = norm_inside_mask(second, mask) return xp.real( nf.fftshift(nf.ifftn(xp.multiply(nf.fftn(b), xp.conj( nf.fftn(a)))))) / xp.sum(mask)
def norm_inside_mask(inp, mask): """ To normalise a 2D array within a mask @param inp: A 2D array to be normalized. @type inp: numpy array 2D @param mask: A 2D array of the same size as the input to mask of parts of the ixp. @type mask: numpy array 2D @return: A normalized 2D array. @returntype: numpy array 2D @requires: the shape of inp to be equal to the shape of the mask """ # assert ixp.shape == mask.shape # assert len(ixp.shape) == 2 mea = xp.divide(xp.sum(xp.multiply(inp, mask)), xp.sum(mask)) st = xp.sqrt( xp.sum((xp.multiply(mask, mea) + xp.multiply(inp, mask) - mea)**2) / xp.sum(mask)) return xp.multiply((inp - mea) / st, mask)
def rotation_distance(ang1, ang2): """Given two angles (lists), calculate the angular distance (degree). @param ang1: angle 1. [Phi, Psi, Theta], or [Z1, Z2, X] in Pytom format. @param ang2: angle 2. [Phi, Psi, Theta], or [Z1, Z2, X] in Pytom format. @return: rotation distance in degree. """ mtx1 = rotation_matrix_zxz(ang1) mtx2 = rotation_matrix_zxz(ang2) res = xp.multiply(mtx1, mtx2) # elementwise multiplication trace = xp.sum(res) from math import pi, acos temp = 0.5 * (trace - 1.0) if temp >= 1.0: return 0.0 if temp <= -1.0: return 180 return acos(temp) * 180 / pi
def bandCC(volume, reference, band, verbose=False, shared=None, index=None): """ bandCC: Determines the normalised correlation coefficient within a band @param volume: The volume @type volume: L{pytom_volume.vol} @param reference: The reference @type reference: L{pytom_volume.vol} @param band: [a,b] - specify the lower and upper end of band. @return: First parameter - The correlation of the two volumes in the specified band. Second parameter - The bandpass filter used. @rtype: List - [float,L{pytom_freqweight.weight}] @author: Thomas Hrabe """ if not index is None: print(index) from pytom.tompy.filter import bandpass from pytom.tompy.correlation import xcf #from pytom.tompy.filter import vol_comp if verbose: print('lowest freq : ', band[0], ' highest freq', band[1]) vf, m = bandpass(volume, band[0], band[1], returnMask=True, fourierOnly=True) rf = bandpass(reference, band[0], band[1], mask=m, fourierOnly=True) #,vf[1]) #ccVolume = vol_comp(rf[0].shape[0],rf[0].shape[1],rf[0].shape[2]) #ccVolume.copyVolume(rf[0]) vf = vf.astype(xp.complex128) ccVolume = rf.astype(vf.dtype) ccVolume = ccVolume * xp.conj(vf) #pytom_volume.conj_mult(ccVolume,vf[0]) cc = ccVolume.sum() cc = cc.real v = vf r = rf absV = xp.abs(v) absR = xp.abs(r) sumV = xp.sum(absV**2) sumR = xp.sum(absR**2) sumV = xp.abs(sumV) sumR = xp.abs(sumR) if sumV == 0: sumV = 1 if sumR == 0: sumR = 1 cc = cc / (xp.sqrt(sumV * sumR)) #numerical errors will be punished with nan if abs(cc) > 1.1: cc = float('nan') return float(cc)