//  [python]
def wfc_r(self, ispin=1, ikpt=1, iband=1,
              gvec=None, Cg=None, ngrid=None,
              rescale=None,
              norm=False, kr_phase=False, r0=[0.0, 0.0, 0.0]):
        '''
        Obtain the pseudo-wavefunction of the specified KS states in real space
        by performing FT transform on the reciprocal space planewave
        coefficients.  The 3D FT grid size is determined by ngrid, which
        defaults to self._ngrid if not given.  Gvectors of the KS states is used
        to put 1D planewave coefficients back to 3D grid.

        Inputs:
            ispin : spin index of the desired KS states, starting from 1
            ikpt  : k-point index of the desired KS states, starting from 1
            iband : band index of the desired KS states, starting from 1
            gvec  : the G-vectors correspond to the plane-wave coefficients
            Cg    : the plane-wave coefficients. If None, read from WAVECAR
            ngrid : the FFT grid size
            norm  : normalized Cg?
         kr_phase : whether or not to multiply the exp(ikr) phase
               r0 : shift of the kr-phase to get full wfc other than primitive cell

        The return wavefunctions are normalized in a way that

                        \sum_{ijk} | \phi_{ijk} | ^ 2 = 1

        '''
        self.checkIndex(ispin, ikpt, iband)

        if ngrid is None:
            ngrid = self._ngrid.copy() * 2
        else:
            ngrid = np.array(ngrid, dtype=int)
            assert ngrid.shape == (3,)
            assert np.all(ngrid >= self._ngrid), \
                "Minium FT grid size: (%d, %d, %d)" % \
                (self._ngrid[0], self._ngrid[1], self._ngrid[2])

        # By default, the WAVECAR only stores the periodic part of the Bloch
        # wavefunction. In order to get the full Bloch wavefunction, one need to
        # multiply the periodic part with the phase: exp(i k (r + r0). Below, the
        # k-point vector and the real-space grid are both in the direct
        # coordinates.
        if kr_phase:
            phase = np.exp(1j * np.pi * 2 *
                           np.sum(
                               self._kvecs[ikpt-1] *
                               (
                                   # r
                                   np.mgrid[
                                       0:ngrid[0], 0:ngrid[1], 0:ngrid[2]
                                   ].reshape((3, np.prod(ngrid))).T /
                                   ngrid.astype(float) +
                                   # r0
                                   np.array(r0, dtype=float)
                               ),
                               axis=1
                           )).reshape(ngrid)
        else:
            phase = 1.0

        # The default normalization of np.fft.fftn has the direct transforms
        # unscaled and the inverse transforms are scaled by 1/n. It is possible
        # to obtain unitary transforms by setting the keyword argument norm to
        # "ortho" (default is None) so that both direct and inverse transforms
        # will be scaled by 1/\sqrt{n}.

        # default normalization factor so that
        # \sum_{ijk} | \phi_{ijk} | ^ 2 = 1
        normFac = rescale if rescale is not None else np.sqrt(np.prod(ngrid))

        if gvec is None:
            gvec = self.gvectors(ikpt)

        if self._lgam:
            if self._gam_half == 'z':
                phi_k = np.zeros(
                    (ngrid[0], ngrid[1], ngrid[2]//2 + 1), dtype=np.complex128)
            else:
                phi_k = np.zeros(
                    (ngrid[0]//2 + 1, ngrid[1], ngrid[2]), dtype=np.complex128)
        else:
            phi_k = np.zeros(ngrid, dtype=np.complex128)

        gvec %= ngrid[np.newaxis, :]

        if self._lsoc:
            wfc_spinor = []
            if Cg:
                dump = Cg
            else:
                dump = self.readBandCoeff(ispin, ikpt, iband, norm)
            nplw = dump.shape[0] // 2

            # spinor up
            phi_k[gvec[:, 0], gvec[:, 1], gvec[:, 2]] = dump[:nplw]
            wfc_spinor.append(ifftn(phi_k) * normFac * phase)
            # spinor down
            phi_k[:, :, :] = 0.0j
            phi_k[gvec[:, 0], gvec[:, 1], gvec[:, 2]] = dump[nplw:]
            wfc_spinor.append(ifftn(phi_k) * normFac * phase)

            del dump
            return wfc_spinor

        else:
            if Cg is not None:
                phi_k[gvec[:, 0], gvec[:, 1], gvec[:, 2]] = Cg
            else:
                phi_k[gvec[:, 0], gvec[:, 1], gvec[:, 2]
                      ] = self.readBandCoeff(ispin, ikpt, iband, norm)

            if self._lgam:
                # add some components that are excluded and perform c2r FFT
                if self._gam_half == 'z':
                    for ii in range(ngrid[0]):
                        for jj in range(ngrid[1]):
                            fx = ii if ii < ngrid[0] // 2 + \
                                1 else ii - ngrid[0]
                            fy = jj if jj < ngrid[1] // 2 + \
                                1 else jj - ngrid[1]
                            if (fy > 0) or (fy == 0 and fx >= 0):
                                continue
                            phi_k[ii, jj, 0] = phi_k[-ii, -jj, 0].conjugate()

                    # VASP add a factor of SQRT2 for G != 0 in Gamma-only VASP
                    phi_k /= np.sqrt(2.)
                    phi_k[0, 0, 0] *= np.sqrt(2.)
                    return np.fft.irfftn(phi_k, s=ngrid) * normFac
                elif self._gam_half == 'x':
                    for jj in range(ngrid[1]):
                        for kk in range(ngrid[2]):
                            fy = jj if jj < ngrid[1] // 2 + \
                                1 else jj - ngrid[1]
                            fz = kk if kk < ngrid[2] // 2 + \
                                1 else kk - ngrid[2]
                            if (fy > 0) or (fy == 0 and fz >= 0):
                                continue
                            phi_k[0, jj, kk] = phi_k[0, -jj, -kk].conjugate()

                    phi_k /= np.sqrt(2.)
                    phi_k[0, 0, 0] *= np.sqrt(2.)
                    phi_k = np.swapaxes(phi_k, 0, 2)
                    tmp = np.fft.irfftn(
                        phi_k, s=(ngrid[2], ngrid[1], ngrid[0])) * normFac
                    return np.swapaxes(tmp, 0, 2)
            else:
                # perform complex2complex FFT
                return ifftn(phi_k * normFac) * phase