예제 #1
0
파일: steerable.cpp 프로젝트: I2PC/scipion
// Remove wedge ------------------------------------------------------------
void MissingWedge::removeWedge(MultidimArray<double> &V) const
{
    Matrix2D<double> Epos, Eneg;
    Euler_angles2matrix(rotPos,tiltPos,0,Epos);
    Euler_angles2matrix(rotNeg,tiltNeg,0,Eneg);
    
    Matrix1D<double> freq(3), freqPos, freqNeg;
    Matrix1D<int> idx(3);

    FourierTransformer transformer;
    MultidimArray< std::complex<double> > Vfft;
    transformer.FourierTransform(V,Vfft,false);

    FOR_ALL_ELEMENTS_IN_ARRAY3D(Vfft)
    {
        // Frequency in the coordinate system of the volume
        VECTOR_R3(idx,j,i,k);
        FFT_idx2digfreq(V,idx,freq);

        // Frequency in the coordinate system of the plane
        freqPos=Epos*freq;
        freqNeg=Eneg*freq;
        if (ZZ(freqPos)<0 || ZZ(freqNeg)>0)
            Vfft(k,i,j)=0;
    }
    transformer.inverseFourierTransform();
}
예제 #2
0
void actualPhaseFlip(MultidimArray<double> &I, CTFDescription ctf)
{
    // Perform the Fourier transform
    FourierTransformer transformer;
    MultidimArray< std::complex<double> > M_inFourier;
    transformer.FourierTransform(I,M_inFourier,false);

    Matrix1D<double> freq(2); // Frequencies for Fourier plane
    int yDim=YSIZE(I);
    int xDim=XSIZE(I);
    double iTm=1.0/ctf.Tm;
    for (size_t i=0; i<YSIZE(M_inFourier); ++i)
    {
    	FFT_IDX2DIGFREQ(i, yDim, YY(freq));
    	YY(freq) *= iTm;
        for (size_t j=0; j<XSIZE(M_inFourier); ++j)
        {
        	FFT_IDX2DIGFREQ(j, xDim, XX(freq));
        	XX(freq) *= iTm;
            ctf.precomputeValues(XX(freq),YY(freq));
            if (ctf.getValuePureWithoutDampingAt()<0)
                DIRECT_A2D_ELEM(M_inFourier,i,j)*=-1;
        }
    }

    // Perform inverse Fourier transform and finish
    transformer.inverseFourierTransform();
}
예제 #3
0
파일: fftw.cpp 프로젝트: shy3u/GeRelion
void getSpectrum(MultidimArray<double>& Min,
                 MultidimArray<double>& spectrum,
                 int spectrum_type)
{

	MultidimArray<Complex > Faux;
	int xsize = XSIZE(Min);
	Matrix1D<double> f(3);
	MultidimArray<double> count(xsize);
	FourierTransformer transformer;

	spectrum.initZeros(xsize);
	count.initZeros();
	transformer.FourierTransform(Min, Faux, false);
	FOR_ALL_ELEMENTS_IN_FFTW_TRANSFORM(Faux)
	{
		long int idx = ROUND(sqrt(kp * kp + ip * ip + jp * jp));
		if (spectrum_type == AMPLITUDE_SPECTRUM)
		{
			spectrum(idx) += abs(dAkij(Faux, k, i, j));
		}
		else
		{
			spectrum(idx) += norm(dAkij(Faux, k, i, j));
		}
		count(idx) += 1.;
	}

	for (long int i = 0; i < xsize; i++)
		if (count(i) > 0.)
		{
			spectrum(i) /= count(i);
		}

}
예제 #4
0
파일: fftw.cpp 프로젝트: shy3u/GeRelion
void multiplyBySpectrum(MultidimArray<double>& Min,
                        MultidimArray<double>& spectrum,
                        bool leave_origin_intact)
{

	MultidimArray<Complex > Faux;
	Matrix1D<double> f(3);
	MultidimArray<double> lspectrum;
	FourierTransformer transformer;
	double dim3 = XSIZE(Min) * YSIZE(Min) * ZSIZE(Min);

	transformer.FourierTransform(Min, Faux, false);
	lspectrum = spectrum;
	if (leave_origin_intact)
	{
		lspectrum(0) = 1.;
	}
	FOR_ALL_ELEMENTS_IN_FFTW_TRANSFORM(Faux)
	{
		long int idx = ROUND(sqrt(kp * kp + ip * ip + jp * jp));
		dAkij(Faux, k, i, j) *=  lspectrum(idx) * dim3;
	}
	transformer.inverseFourierTransform();

}
예제 #5
0
파일: fftw.cpp 프로젝트: shy3u/GeRelion
void correctMapForMTF(MultidimArray<double >& img, FileName& fn_mtf)
{
	FourierTransformer transformer;
	MultidimArray<Complex > FT;
	transformer.FourierTransform(img, FT, false);
	correctMapForMTF(FT, XSIZE(img), fn_mtf);
	transformer.inverseFourierTransform();

}
예제 #6
0
파일: fftw.cpp 프로젝트: shy3u/GeRelion
void getFSC(MultidimArray< double >& m1,
            MultidimArray< double >& m2,
            MultidimArray< double >& fsc)
{
	MultidimArray< Complex > FT1, FT2;
	FourierTransformer transformer;
	transformer.FourierTransform(m1, FT1);
	transformer.FourierTransform(m2, FT2);
	getFSC(FT1, FT2, fsc);
}
예제 #7
0
// Produce side info -------------------------------------------------------
void ProgDetectMissingWedge::produceSideInfo()
{
    V.read(fn_vol);
    FourierTransformer transformer;
    MultidimArray< std::complex<double> > Vfft;
    transformer.FourierTransform(MULTIDIM_ARRAY(V),Vfft,false);
    Vmag = new MultidimArray<double>();
    Vmag->resize(Vfft);
    FOR_ALL_ELEMENTS_IN_ARRAY3D(*Vmag)
    (*Vmag)(k,i,j)=20*log10(abs(Vfft(k,i,j)));
}
예제 #8
0
파일: fftw.cpp 프로젝트: shy3u/GeRelion
void resizeMap(MultidimArray<double >& img, int newsize)
{

	FourierTransformer transformer;
	MultidimArray<Complex > FT, FT2;
	transformer.FourierTransform(img, FT, false);
	windowFourierTransform(FT, FT2, newsize);
	if (img.getDim() == 2)
	{
		img.resize(newsize, newsize);
	}
	else if (img.getDim() == 3)
	{
		img.resize(newsize, newsize, newsize);
	}
	transformer.inverseFourierTransform(FT2, img);

}
예제 #9
0
파일: fftw.cpp 프로젝트: shy3u/GeRelion
void randomizePhasesBeyond(MultidimArray<double>& v, int index)
{
	MultidimArray< Complex > FT;
	FourierTransformer transformer;

	transformer.FourierTransform(v, FT, false);

	int index2 = index * index;
	FOR_ALL_ELEMENTS_IN_FFTW_TRANSFORM(FT)
	{
		if (kp * kp + ip * ip + jp * jp >= index2)
		{
			double mag = abs(DIRECT_A3D_ELEM(FT, k, i, j));
			double phas = rnd_unif(0., 2.*PI);
			double realval = mag * cos(phas);
			double imagval = mag * sin(phas);
			DIRECT_A3D_ELEM(FT, k, i, j) = Complex(realval, imagval);
		}
	}

	// Inverse transform
	transformer.inverseFourierTransform();

}
예제 #10
0
파일: steerable.cpp 프로젝트: I2PC/scipion
void Steerable::singleFilter(const MultidimArray<double>& Vin,
    MultidimArray<double> &hx1, MultidimArray<double> &hy1, MultidimArray<double> &hz1,
    MultidimArray<double> &Vout){

    MultidimArray< std::complex<double> > H, Aux;
    Vout.initZeros(Vin);

    // Filter in X
    #define MINUS_ONE_POWER(n) (((n)%2==0)? 1:-1)
    FourierTransformer transformer;
    transformer.FourierTransform(hx1,H);
    
    FOR_ALL_ELEMENTS_IN_ARRAY1D(H)
          H(i)*= MINUS_ONE_POWER(i);

    FourierTransformer transformer2;
    
    MultidimArray<double> aux(XSIZE(Vin));
        	   
    transformer2.setReal(aux);		   
		   
    for (size_t k=0; k<ZSIZE(Vin); k++)
        for (size_t i=0; i<YSIZE(Vin); i++)
        {
            for (size_t j=0; j<XSIZE(Vin); j++)
                DIRECT_A1D_ELEM(aux,j)=DIRECT_A3D_ELEM(Vin,k,i,j);
			    
	    transformer2.FourierTransform( );	    
	    transformer2.getFourierAlias( Aux );
	    Aux*=H;
	    transformer2.inverseFourierTransform( );
            	    
	    for (size_t j=0; j<XSIZE(Vin); j++)
                DIRECT_A3D_ELEM(Vout,k,i,j)=XSIZE(aux)*DIRECT_A1D_ELEM(aux,j);
        }

    // Filter in Y
    transformer.FourierTransform(hy1,H);
    
    FOR_ALL_ELEMENTS_IN_ARRAY1D(H)
          H(i)*= MINUS_ONE_POWER(i);

    aux.initZeros(YSIZE(Vin));
    transformer2.setReal(aux);		   
    
    for (size_t k=0; k<ZSIZE(Vin); k++)
        for (size_t j=0; j<XSIZE(Vin); j++)
        {
            for (size_t i=0; i<YSIZE(Vin); i++)
                DIRECT_A1D_ELEM(aux,i)=DIRECT_A3D_ELEM(Vout,k,i,j);

	    transformer2.FourierTransform( );	    
	    transformer2.getFourierAlias( Aux );
	    Aux*=H;
	    transformer2.inverseFourierTransform( );
            
	    for (size_t i=0; i<YSIZE(Vin); i++)
                DIRECT_A3D_ELEM(Vout,k,i,j)=XSIZE(aux)*DIRECT_A1D_ELEM(aux,i);
        }

    // Filter in Z

    transformer.FourierTransform(hz1,H);

    FOR_ALL_ELEMENTS_IN_ARRAY1D(H)
          H(i)*= MINUS_ONE_POWER(i);

    aux.initZeros(ZSIZE(Vin));    
    transformer2.setReal(aux);		   

    for (size_t i=0; i<YSIZE(Vin); i++)
        for (size_t j=0; j<XSIZE(Vin); j++)
        {
            for (size_t k=0; k<ZSIZE(Vin); k++)
                DIRECT_A1D_ELEM(aux,k)=DIRECT_A3D_ELEM(Vout,k,i,j);

	    transformer2.FourierTransform( );	    
	    transformer2.getFourierAlias( Aux );
	    Aux*=H;
	    transformer2.inverseFourierTransform( );

            for (size_t k=0; k<ZSIZE(Vin); k++)
                DIRECT_A3D_ELEM(Vout,k,i,j)=XSIZE(aux)*DIRECT_A1D_ELEM(aux,k);
        }
    
    // If Missing wedge
    if (MW!=NULL)
        MW->removeWedge(Vout);
}
예제 #11
0
// Fill data array with oversampled Fourier transform, and calculate its power spectrum
void Projector::computeFourierTransformMap(MultidimArray<DOUBLE> &vol_in, MultidimArray<DOUBLE> &power_spectrum, int current_size, int nr_threads, bool do_gridding)
{

	MultidimArray<DOUBLE> Mpad;
	MultidimArray<Complex > Faux;
    FourierTransformer transformer;
    // DEBUGGING: multi-threaded FFTWs are giving me a headache?
	// For a long while: switch them off!
	//transformer.setThreadsNumber(nr_threads);
    DOUBLE normfft;

	// Size of padded real-space volume
	int padoridim = padding_factor * ori_size;

	// Initialize data array of the oversampled transform
	ref_dim = vol_in.getDim();

	// Make Mpad
	switch (ref_dim)
	{
	case 2:
	   Mpad.initZeros(padoridim, padoridim);
	   normfft = (DOUBLE)(padding_factor * padding_factor);
	   break;
	case 3:
	   Mpad.initZeros(padoridim, padoridim, padoridim);
	   if (data_dim ==3)
		   normfft = (DOUBLE)(padding_factor * padding_factor * padding_factor);
	   else
		   normfft = (DOUBLE)(padding_factor * padding_factor * padding_factor * ori_size);
	   break;
	default:
	   REPORT_ERROR("Projector::computeFourierTransformMap%%ERROR: Dimension of the data array should be 2 or 3");
	}

	// First do a gridding pre-correction on the real-space map:
	// Divide by the inverse Fourier transform of the interpolator in Fourier-space
	// 10feb11: at least in 2D case, this seems to be the wrong thing to do!!!
	// TODO: check what is best for subtomo!
	if (do_gridding)// && data_dim != 3)
		griddingCorrect(vol_in);

	// Pad translated map with zeros
	vol_in.setXmippOrigin();
	Mpad.setXmippOrigin();
	FOR_ALL_ELEMENTS_IN_ARRAY3D(vol_in) // This will also work for 2D
		A3D_ELEM(Mpad, k, i, j) = A3D_ELEM(vol_in, k, i, j);

	// Translate padded map to put origin of FT in the center
	CenterFFT(Mpad, true);

	// Calculate the oversampled Fourier transform
	transformer.FourierTransform(Mpad, Faux, false);

	// Free memory: Mpad no longer needed
	Mpad.clear();

	// Resize data array to the right size and initialise to zero
	initZeros(current_size);

	// Fill data only for those points with distance to origin less than max_r
	// (other points will be zero because of initZeros() call above
	// Also calculate radial power spectrum
	power_spectrum.initZeros(ori_size / 2 + 1);
	MultidimArray<DOUBLE> counter(power_spectrum);
	counter.initZeros();

	int max_r2 = r_max * r_max * padding_factor * padding_factor;
	FOR_ALL_ELEMENTS_IN_FFTW_TRANSFORM(Faux) // This will also work for 2D
	{
		int r2 = kp*kp + ip*ip + jp*jp;
		// The Fourier Transforms are all "normalised" for 2D transforms of size = ori_size x ori_size
		if (r2 <= max_r2)
		{
			// Set data array
			A3D_ELEM(data, kp, ip, jp) = DIRECT_A3D_ELEM(Faux, k, i, j) * normfft;

			// Calculate power spectrum
			int ires = ROUND( sqrt((DOUBLE)r2) / padding_factor );
			// Factor two because of two-dimensionality of the complex plane
			DIRECT_A1D_ELEM(power_spectrum, ires) += norm(A3D_ELEM(data, kp, ip, jp)) / 2.;
			DIRECT_A1D_ELEM(counter, ires) += 1.;
		}
	}

	// Calculate radial average of power spectrum
	FOR_ALL_DIRECT_ELEMENTS_IN_ARRAY1D(power_spectrum)
	{
		if (DIRECT_A1D_ELEM(counter, i) < 1.)
			DIRECT_A1D_ELEM(power_spectrum, i) = 0.;
		else
			DIRECT_A1D_ELEM(power_spectrum, i) /= DIRECT_A1D_ELEM(counter, i);
	}

	transformer.cleanup();

}
예제 #12
0
void Postprocessing::sharpenMap()
{

	MultidimArray<Complex > FT;
	FourierTransformer transformer;
	transformer.FourierTransform(I1(), FT, true);

	makeGuinierPlot(FT, guinierin);

	// A. If MTF curve is given, first divide by the MTF
	divideByMtf(FT);
	makeGuinierPlot(FT, guinierinvmtf);

	// B. Then perform B-factor sharpening
	if (do_fsc_weighting)
	{
		if (verb > 0)
		{
			std::cout <<"== Applying sqrt(2*FSC/(FSC+1)) weighting (as in Rosenthal & Henderson, 2003) ..." <<std::endl;
		}
		applyFscWeighting(FT, fsc_true);
	}
	makeGuinierPlot(FT, guinierweighted);

	global_bfactor = 0.;
	if (do_auto_bfac)
	{
		if (verb > 0)
		{
			std::cout <<"== Fitting straight line through Guinier plot to find B-factor ..." <<std::endl;
			std::cout.width(35); std::cout << std::left <<"  + fit from resolution: "; std::cout << fit_minres << std::endl;
			std::cout.width(35); std::cout << std::left  <<"  + fit until resolution: "; std::cout << fit_maxres << std::endl;
		}

		fitStraightLine(guinierweighted, global_slope, global_intercept, global_corr_coeff);
		global_bfactor = 4. * global_slope;
		if (verb > 0)
		{
			std::cout.width(35); std::cout << std::left  <<"  + slope of fit: "; std::cout << global_slope << std::endl;
			std::cout.width(35); std::cout << std::left  <<"  + intercept of fit: "; std::cout << global_intercept << std::endl;
			std::cout.width(35); std::cout << std::left  <<"  + correlation of fit: "; std::cout << global_corr_coeff << std::endl;
		}
	}
	else if (ABS(adhoc_bfac) > 0.)
	{
		if (verb > 0)
		{
			std::cout <<"== Using a user-provided (ad-hoc) B-factor ..." <<std::endl;
		}
		if (adhoc_bfac > 0.)
			std::cout <<" WARNING: using a positive B-factor. This will effectively dampen your map. Use negative value to sharpen it!" << std::endl;
		global_bfactor = adhoc_bfac;
	}

	// Now apply the B-factor
	if (ABS(global_bfactor) > 0.)
	{
		if (verb > 0)
		{
			std::cout.width(35); std::cout << std::left  <<"  + apply b-factor of: "; std::cout << global_bfactor << std::endl;
		}
		applyBFactorToMap(FT, XSIZE(I1()), global_bfactor, angpix);
	}

	makeGuinierPlot(FT, guiniersharpen);

	if (verb > 0)
	{
		std::cout << "== Low-pass filtering final map ... " << std::endl;
	}
	DOUBLE my_filter = (low_pass_freq > 0.) ? low_pass_freq : global_resol;
	if (verb > 0)
	{
		std::cout.width(35); std::cout << std::left  <<"  + filter frequency: "; std::cout << my_filter << std::endl;
	}
	lowPassFilterMap(FT, XSIZE(I1()), my_filter, angpix, filter_edge_width);

	transformer.inverseFourierTransform(FT, I1());

}