void FourierProjector::produceSideInfo() { // Zero padding MultidimArray<double> Vpadded; int paddedDim=(int)(paddingFactor*volumeSize); // JMRT: TODO: I think it is a very poor design to modify the volume passed // in the construct, it will be padded anyway, so new memory should be allocated volume->window(Vpadded,FIRST_XMIPP_INDEX(paddedDim),FIRST_XMIPP_INDEX(paddedDim),FIRST_XMIPP_INDEX(paddedDim), LAST_XMIPP_INDEX(paddedDim),LAST_XMIPP_INDEX(paddedDim),LAST_XMIPP_INDEX(paddedDim)); volume->clear(); // Make Fourier transform, shift the volume origin to the volume center and center it MultidimArray< std::complex<double> > Vfourier; transformer3D.completeFourierTransform(Vpadded,Vfourier); ShiftFFT(Vfourier, FIRST_XMIPP_INDEX(XSIZE(Vpadded)), FIRST_XMIPP_INDEX(YSIZE(Vpadded)), FIRST_XMIPP_INDEX(ZSIZE(Vpadded))); CenterFFT(Vfourier,true); Vfourier.setXmippOrigin(); // Compensate for the Fourier normalization factor double K=(double)(XSIZE(Vpadded)*XSIZE(Vpadded)*XSIZE(Vpadded))/(double)(volumeSize*volumeSize); FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(Vfourier) DIRECT_MULTIDIM_ELEM(Vfourier,n)*=K; Vpadded.clear(); // Compute Bspline coefficients if (BSplineDeg==3) { MultidimArray< double > VfourierRealAux, VfourierImagAux; Complex2RealImag(Vfourier, VfourierRealAux, VfourierImagAux); Vfourier.clear(); produceSplineCoefficients(BSPLINE3,VfourierRealCoefs,VfourierRealAux); produceSplineCoefficients(BSPLINE3,VfourierImagCoefs,VfourierImagAux); //VfourierRealAux.clear(); //VfourierImagAux.clear(); } else Complex2RealImag(Vfourier, VfourierRealCoefs, VfourierImagCoefs); // Allocate memory for the 2D Fourier transform projection().initZeros(volumeSize,volumeSize); projection().setXmippOrigin(); transformer2D.FourierTransform(projection(),projectionFourier,false); // Calculate phase shift terms phaseShiftImgA.initZeros(projectionFourier); phaseShiftImgB.initZeros(projectionFourier); double shift=-FIRST_XMIPP_INDEX(volumeSize); double xxshift = -2 * PI * shift / volumeSize; for (size_t i=0; i<YSIZE(projectionFourier); ++i) { double phasey=(double)(i) * xxshift; for (size_t j=0; j<XSIZE(projectionFourier); ++j) { // Phase shift to move the origin of the image to the corner double dotp = (double)(j) * xxshift + phasey; sincos(dotp,&DIRECT_A2D_ELEM(phaseShiftImgB,i,j),&DIRECT_A2D_ELEM(phaseShiftImgA,i,j)); } } }
void FourierProjector::produceSideInfo() { // Zero padding MultidimArray<double> Vpadded; int paddedDim=(int)(paddingFactor*volumeSize); volume->window(Vpadded,FIRST_XMIPP_INDEX(paddedDim),FIRST_XMIPP_INDEX(paddedDim),FIRST_XMIPP_INDEX(paddedDim), LAST_XMIPP_INDEX(paddedDim),LAST_XMIPP_INDEX(paddedDim),LAST_XMIPP_INDEX(paddedDim)); volume->clear(); // Make Fourier transform, shift the volume origin to the volume center and center it MultidimArray< std::complex<double> > Vfourier; transformer3D.completeFourierTransform(Vpadded,Vfourier); ShiftFFT(Vfourier, FIRST_XMIPP_INDEX(XSIZE(Vpadded)), FIRST_XMIPP_INDEX(YSIZE(Vpadded)), FIRST_XMIPP_INDEX(ZSIZE(Vpadded))); CenterFFT(Vfourier,true); Vfourier.setXmippOrigin(); // Compensate for the Fourier normalization factor double K=(double)(XSIZE(Vpadded)*XSIZE(Vpadded)*XSIZE(Vpadded))/(double)(volumeSize*volumeSize); FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(Vfourier) DIRECT_MULTIDIM_ELEM(Vfourier,n)*=K; Vpadded.clear(); // Compute Bspline coefficients if (BSplineDeg==3) { MultidimArray< double > VfourierRealAux, VfourierImagAux; Complex2RealImag(Vfourier, VfourierRealAux, VfourierImagAux); Vfourier.clear(); produceSplineCoefficients(BSPLINE3,VfourierRealCoefs,VfourierRealAux); produceSplineCoefficients(BSPLINE3,VfourierImagCoefs,VfourierImagAux); //VfourierRealAux.clear(); //VfourierImagAux.clear(); } else Complex2RealImag(Vfourier, VfourierRealCoefs, VfourierImagCoefs); // Allocate memory for the 2D Fourier transform projection().initZeros(volumeSize,volumeSize); projection().setXmippOrigin(); transformer2D.FourierTransform(projection(),projectionFourier,false); }
//#define DEBUG void ProgResolutionIBW::run() { V.read(fnVol); //Mask generation Image<double> aux; double bg_mean; MultidimArray<double> Vmask; detectBackground(V(),aux(),0.1,bg_mean); #ifdef DEBUG aux.write("PPPmask_no_ero_03.vol"); #endif //Mask volume erosion to expand the mask boundaries Vmask.initZeros(V()); erode3D(aux(),Vmask, 18,0,2); //Correction of some flaws produced in the edges of the mask volume FOR_ALL_DIRECT_ELEMENTS_IN_ARRAY3D(Vmask) if (k<=4 || i<=4 || j<=4 || k>=ZSIZE(Vmask)-4 || i>=YSIZE(Vmask)-4 || j>=XSIZE(Vmask)-4) DIRECT_A3D_ELEM(Vmask,k,i,j)=1; aux()=Vmask; #ifdef DEBUG aux.write("PPPmask_ero_03.vol"); #endif //Sobel edge detection applied to original volume Image<double> Vedge; computeEdges(V(),Vedge()); #ifdef DEBUG Vedge.write("PPPvolume_sobel_unmask_03.vol"); #endif //Masked volume generation const MultidimArray<double> &mVedge=Vedge(); FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(mVedge) if (DIRECT_MULTIDIM_ELEM(Vmask,n)==1) DIRECT_MULTIDIM_ELEM(mVedge,n)=0; #ifdef DEBUG Vedge.write("volume_sobel_mask_03.vol"); #endif double minval, maxval, avg, stddev; //Invert the mask to meet computeStats_within_binary_mask requirements FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(Vmask) if (DIRECT_MULTIDIM_ELEM(Vmask,n)==1) DIRECT_MULTIDIM_ELEM(Vmask,n)=0; else DIRECT_MULTIDIM_ELEM(Vmask,n)=1; //Threshold is 3 times the standard deviation of unmasked pixel values double thresh; computeStats_within_binary_mask(Vmask,mVedge,minval, maxval, avg, stddev); thresh=3*stddev; //Final edge volume generated by setting to 1 positions with values > threshold Image<double> Vaux; Vaux().initZeros(mVedge); FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(mVedge) if (DIRECT_MULTIDIM_ELEM(mVedge,n)>=thresh) DIRECT_MULTIDIM_ELEM(Vaux(),n)=1; #ifdef DEBUG Vaux.write("volumen_bordes_definitivo_03.vol"); #endif const MultidimArray<double> &mVaux=Vaux(); //Spline coefficient volume from original volume, to allow <1 step sizes MultidimArray<double> Volcoeffs; Volcoeffs.initZeros(V()); produceSplineCoefficients(3,Volcoeffs,V()); //Width parameter volume initialization Image<double> widths; widths().resizeNoCopy(V()); widths().initConstant(1e5); double step=0.25; Matrix1D<double> direction(3); //Calculation of edge width for 10 different directions, if a smaller value is found for a different //direction on a given position the former value is overwritten //Direction (1,0,0) VECTOR_R3(direction,1,0,0); edgeWidth(Volcoeffs, mVaux, widths(), direction, step); //Direction (0,1,0) VECTOR_R3(direction,0,1,0); edgeWidth(Volcoeffs, mVaux, widths(), direction, step); //Direction (0,0,1) VECTOR_R3(direction,0,0,1); edgeWidth(Volcoeffs, mVaux, widths(), direction, step); //Direction (1,1,0) VECTOR_R3(direction,(1/sqrt(2)),(1/sqrt(2)),0); edgeWidth(Volcoeffs, mVaux, widths(), direction, step); //Direction (1,0,1) VECTOR_R3(direction,(1/sqrt(2)),0,(1/sqrt(2))); edgeWidth(Volcoeffs, mVaux, widths(), direction, step); //Direction (0,1,1) VECTOR_R3(direction,0,(1/sqrt(2)),(1/sqrt(2))); edgeWidth(Volcoeffs, mVaux, widths(), direction, step); //Direction (1,1,1) VECTOR_R3(direction,(1/sqrt(3)),(1/sqrt(3)),(1/sqrt(3))); edgeWidth(Volcoeffs, mVaux, widths(), direction, step); //Direction (-1,1,1) VECTOR_R3(direction,-(1/sqrt(3)),(1/sqrt(3)),(1/sqrt(3))); edgeWidth(Volcoeffs, mVaux, widths(), direction, step); //Direction (1,1,-1) VECTOR_R3(direction,(1/sqrt(3)),(1/sqrt(3)),-(1/sqrt(3))); edgeWidth(Volcoeffs, mVaux, widths(), direction, step); //Direction (1,-1,1) VECTOR_R3(direction,(1/sqrt(3)),-(1/sqrt(3)),(1/sqrt(3))); edgeWidth(Volcoeffs, mVaux, widths(), direction, step); #ifdef DEBUG std::cout << "width stats: "; widths().printStats(); std::cout << std::endl; widths.write("PPPwidths.vol"); #endif double ibw=calculateIBW(widths()); std::cout << "Resolution ibw= " << ibw << std::endl; if (fnOut!="") widths.write(fnOut); }