Ejemplo n.º 1
0
// 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();
}
Ejemplo n.º 2
0
// Apply transformation ---------------------------------------------------
void applyTransformation(const MultidimArray<double> &V2,
                         MultidimArray<double> &Vaux,
                         double *p)
{
    Matrix1D<double> r(3);
    Matrix2D<double> A, Aaux;

    double greyScale = p[0];
    double greyShift = p[1];
    double rot       = p[2];
    double tilt      = p[3];
    double psi       = p[4];
    double scale     = p[5];
    ZZ(r)            = p[6];
    YY(r)            = p[7];
    XX(r)            = p[8];

    Euler_angles2matrix(rot, tilt, psi, A, true);
    translation3DMatrix(r,Aaux);
    A = A * Aaux;
    scale3DMatrix(vectorR3(scale, scale, scale),Aaux);
    A = A * Aaux;

    applyGeometry(LINEAR, Vaux, V2, A, IS_NOT_INV, WRAP);
    if (greyScale!=1 || greyShift!=0)
        FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(Vaux)
        DIRECT_MULTIDIM_ELEM(Vaux,n)=DIRECT_MULTIDIM_ELEM(Vaux,n)*greyScale+greyShift;
}
Ejemplo n.º 3
0
	/* Apply a transformation matrix to Euler angles --------------------------- */
	void Euler_apply_transf(const Matrix2D<DOUBLE> &L,
		const Matrix2D<DOUBLE> &R,
		DOUBLE rot,
		DOUBLE tilt,
		DOUBLE psi,
		DOUBLE &newrot,
		DOUBLE &newtilt,
		DOUBLE &newpsi)
	{

		Matrix2D<DOUBLE> euler(3, 3), temp;
		Euler_angles2matrix(rot, tilt, psi, euler);
		temp = L * euler * R;
		Euler_matrix2angles(temp, newrot, newtilt, newpsi);
	}
Ejemplo n.º 4
0
/* Compute alphas ---------------------------------------------------------- */
double matrix_fitness(double *p, void *prm)
{
    TiltPairAligner *aligner = (TiltPairAligner *) prm;
    Euler_angles2matrix(-p[1], p[3], p[2], aligner->pair_E);
    double retval = 0;
    for (int i = 0; i < 2; i++)
        for (int j = 0; j < 2; j++)
        {
            double error = fabs(
                               MAT_ELEM(aligner->pair_E,i, j)
                               - MAT_ELEM(aligner->Put, i, j));
            retval += error * error;
        }
    return retval;
}
Ejemplo n.º 5
0
// Draw wedge --------------------------------------------------------------
void drawWedge(double rotPos, double tiltPos, double rotNeg, double tiltNeg,
               const MultidimArray<double> *V,
               const MultidimArray<double> *Vmag, MultidimArray<double> *Vdraw)
{
    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);
    Vdraw->initZeros(*Vmag);
    FOR_ALL_ELEMENTS_IN_ARRAY3D(*Vdraw)
    {
        // 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)
            (*Vdraw)(k,i,j)+=1;
    }
}
Ejemplo n.º 6
0
	/* Rotate (3D) MultidimArray with 3 Euler angles ------------------------------------- */
	void Euler_rotation3DMatrix(DOUBLE rot, DOUBLE tilt, DOUBLE psi, Matrix2D<DOUBLE> &result)
	{
		Euler_angles2matrix(rot, tilt, psi, result, true);
	}
Ejemplo n.º 7
0
	double optimiseTransformationMatrix(bool do_optimise_nr_pairs)
	{
		std::vector<int> best_pairs_t2u, best_map;
		double score, best_score, best_dist=9999.;
		if (do_optimise_nr_pairs)
			best_score = 0.;
		else
			best_score = -999999.;

		int nn = XMIPP_MAX(1., (rotF-rot0)/rotStep);
		nn *= XMIPP_MAX(1., (tiltF-tilt0)/tiltStep);
		nn *= XMIPP_MAX(1., (xF-x0)/xStep);
		nn *= XMIPP_MAX(1., (yF-y0)/yStep);
		int n = 0;
		init_progress_bar(nn);
		for (double rot = rot0; rot <= rotF; rot+= rotStep)
		{
			for (double tilt = tilt0; tilt <= tiltF; tilt+= tiltStep)
			{
				// Assume tilt-axis lies in-plane...
				double psi = -rot;
				// Rotate all points correspondingly
				Euler_angles2matrix(rot, tilt, psi, Pass);
				//std::cerr << " Pass= " << Pass << std::endl;
				// Zero-translations for now (these are added in the x-y loops below)
				MAT_ELEM(Pass, 0, 2) = MAT_ELEM(Pass, 1, 2) = 0.;
				mapOntoTilt();
				for (int x = x0; x <= xF; x += xStep)
				{
					for (int y = y0; y <= yF; y += yStep, n++)
					{
						if (do_optimise_nr_pairs)
							score = getNumberOfPairs(x, y);
						else
							score = -getAverageDistance(x, y); // negative because smaller distance is better!

                                                bool is_best = false;
                                                if (do_optimise_nr_pairs && score==best_score)
                                                {
                                                    double dist = getAverageDistance(x, y);
                                                    if (dist < best_dist)
                                                    {
                                                        best_dist = dist;
                                                        is_best = true;
                                                    }
                                                }
						if (score > best_score || is_best)
						{
							best_score = score;
							best_pairs_t2u = pairs_t2u;
							best_rot = rot;
							best_tilt = tilt;
							best_x = x;
							best_y = y;
						}
						if (n%1000==0) progress_bar(n);
					}
				}
			}
		}
		progress_bar(nn);
		// Update pairs with the best_pairs
		if (do_optimise_nr_pairs)
			pairs_t2u = best_pairs_t2u;

		// Update the Passing matrix and the mapping
		Euler_angles2matrix(best_rot, best_tilt, -best_rot, Pass);
		// Zero-translations for now (these are added in the x-y loops below)
		MAT_ELEM(Pass, 0, 2) = MAT_ELEM(Pass, 1, 2) = 0.;
		mapOntoTilt();
		return best_score;

	}
Ejemplo n.º 8
0
void FourierProjector::project(double rot, double tilt, double psi)
{
    double freqy, freqx;
    std::complex< double > f;
    Euler_angles2matrix(rot,tilt,psi,E);

    projectionFourier.initZeros();
    double shift=-FIRST_XMIPP_INDEX(volumeSize);
    double xxshift = -2 * PI * shift / volumeSize;
    double maxFreq2=maxFrequency*maxFrequency;
    double volumePaddedSize=XSIZE(VfourierRealCoefs);
    for (size_t i=0; i<YSIZE(projectionFourier); ++i)
    {
        FFT_IDX2DIGFREQ(i,volumeSize,freqy);
        double freqy2=freqy*freqy;
        double phasey=(double)(i) * xxshift;

        double freqYvol_X=MAT_ELEM(E,1,0)*freqy;
        double freqYvol_Y=MAT_ELEM(E,1,1)*freqy;
        double freqYvol_Z=MAT_ELEM(E,1,2)*freqy;
        for (size_t j=0; j<XSIZE(projectionFourier); ++j)
        {
            // The frequency of pairs (i,j) in 2D
            FFT_IDX2DIGFREQ(j,volumeSize,freqx);

            // Do not consider pixels with high frequency
            if ((freqy2+freqx*freqx)>maxFreq2)
                continue;

            // Compute corresponding frequency in the volume
            double freqvol_X=freqYvol_X+MAT_ELEM(E,0,0)*freqx;
            double freqvol_Y=freqYvol_Y+MAT_ELEM(E,0,1)*freqx;
            double freqvol_Z=freqYvol_Z+MAT_ELEM(E,0,2)*freqx;

            double c,d;
            if (BSplineDeg==0)
            {
                // 0 order interpolation
                // Compute corresponding index in the volume
                int kVolume=(int)round(freqvol_Z*volumePaddedSize);
                int iVolume=(int)round(freqvol_Y*volumePaddedSize);
                int jVolume=(int)round(freqvol_X*volumePaddedSize);
                c = A3D_ELEM(VfourierRealCoefs,kVolume,iVolume,jVolume);
                d = A3D_ELEM(VfourierImagCoefs,kVolume,iVolume,jVolume);
            }
            else if (BSplineDeg==1)
            {
                // B-spline linear interpolation
                double kVolume=freqvol_Z*volumePaddedSize;
                double iVolume=freqvol_Y*volumePaddedSize;
                double jVolume=freqvol_X*volumePaddedSize;
                c=VfourierRealCoefs.interpolatedElement3D(jVolume,iVolume,kVolume);
                d=VfourierImagCoefs.interpolatedElement3D(jVolume,iVolume,kVolume);
            }
            else
            {
                // B-spline cubic interpolation
                double kVolume=freqvol_Z*volumePaddedSize;
                double iVolume=freqvol_Y*volumePaddedSize;
                double jVolume=freqvol_X*volumePaddedSize;
                c=VfourierRealCoefs.interpolatedElementBSpline3D(jVolume,iVolume,kVolume);
                d=VfourierImagCoefs.interpolatedElementBSpline3D(jVolume,iVolume,kVolume);
            }

            // Phase shift to move the origin of the image to the corner
            double dotp = (double)(j) * xxshift + phasey;
            double a,b;
            sincos(dotp,&b,&a);

            // Multiply Fourier coefficient in volume times phase shift
            double ac = a * c;
            double bd = b * d;
            double ab_cd = (a + b) * (c + d);

            // And store the multiplication
            double *ptrI_ij=(double *)&DIRECT_A2D_ELEM(projectionFourier,i,j);
            *ptrI_ij = ac - bd;
            *(ptrI_ij+1) = ab_cd - ac - bd;
        }
    }
    //VfourierRealCoefs.clear();
    //VfourierImagCoefs.clear();
    transformer2D.inverseFourierTransform();
}
Ejemplo n.º 9
0
void ProgValidationTiltPairs::run()
{
	MetaData MD_tilted, MD_untilted, DF1sorted, DF2sorted, DFweights;

	MD_tilted.read(fntiltimage_In);
	MD_untilted.read(fnuntiltimage_In);

	DF1sorted.sort(MD_tilted,MDL_ITEM_ID,true);
	DF2sorted.sort(MD_untilted,MDL_ITEM_ID,true);

	MDIterator iter1(DF1sorted), iter2(DF2sorted);
	std::vector< Matrix1D<double> > ang1, ang2;
	Matrix1D<double> rotTiltPsi(3), z(3);
	size_t currentId;
	bool anotherImageIn2=iter2.hasNext();
	size_t id1, id2;
	bool mirror;
	Matrix2D<double> Eu, Et, R;
	double alpha, beta;
	while (anotherImageIn2)
	{
		ang1.clear();
		ang2.clear();

		// Take current id
		DF2sorted.getValue(MDL_ITEM_ID,currentId,iter2.objId);

		// Grab all the angles in DF2 associated to this id
		bool anotherIteration=false;
		do
		{
			DF2sorted.getValue(MDL_ITEM_ID,id2,iter2.objId);
			anotherIteration=false;
			if (id2==currentId)
			{
				DF2sorted.getValue(MDL_ANGLE_ROT,XX(rotTiltPsi),iter2.objId);
				DF2sorted.getValue(MDL_ANGLE_TILT,YY(rotTiltPsi),iter2.objId);
				DF2sorted.getValue(MDL_ANGLE_PSI,ZZ(rotTiltPsi),iter2.objId);
				DF2sorted.getValue(MDL_FLIP,mirror,iter2.objId);
				std::cout << "From DF2:" << XX(rotTiltPsi) << " " << YY(rotTiltPsi) << " " << ZZ(rotTiltPsi) << " " << mirror << std::endl;
				//LINEA ANTERIOR ORIGINAL
				if (mirror)
				{
					double rotp, tiltp, psip;
					Euler_mirrorX(XX(rotTiltPsi),YY(rotTiltPsi),ZZ(rotTiltPsi), rotp, tiltp, psip);
					XX(rotTiltPsi)=rotp;
					YY(rotTiltPsi)=tiltp;
					ZZ(rotTiltPsi)=psip;
				}
				ang2.push_back(rotTiltPsi);
				iter2.moveNext();
				if (iter2.hasNext())
					anotherIteration=true;
			}
		} while (anotherIteration);

		// Advance Iter 1 to catch Iter 2
		double N=0, cumulatedDistance=0;
		size_t newObjId=0;
		if (iter1.objId>0)
		{
			DF1sorted.getValue(MDL_ITEM_ID,id1,iter1.objId);
			while (id1<currentId && iter1.hasNext())
			{
				iter1.moveNext();
				DF1sorted.getValue(MDL_ITEM_ID,id1,iter1.objId);
			}

			// If we are at the end of DF1, then we did not find id1 such that id1==currentId
			if (!iter1.hasNext())
				break;

			// Grab all the angles in DF1 associated to this id
			anotherIteration=false;
			do
			{
				DF1sorted.getValue(MDL_ITEM_ID,id1,iter1.objId);
				anotherIteration=false;
				if (id1==currentId)
				{
					DF1sorted.getValue(MDL_ANGLE_ROT,XX(rotTiltPsi),iter1.objId);
					DF1sorted.getValue(MDL_ANGLE_TILT,YY(rotTiltPsi),iter1.objId);
					DF1sorted.getValue(MDL_ANGLE_PSI,ZZ(rotTiltPsi),iter1.objId);
					DF1sorted.getValue(MDL_FLIP,mirror,iter1.objId);
					std::cout << "From DF1:" << XX(rotTiltPsi) << " " << YY(rotTiltPsi) << " " << ZZ(rotTiltPsi) << " " << mirror << std::endl;
					//LINEA ANTERIOR ORIGINAL
					if (mirror)
					{
						double rotp, tiltp, psip;
						Euler_mirrorX(XX(rotTiltPsi),YY(rotTiltPsi),ZZ(rotTiltPsi), rotp, tiltp, psip);
						XX(rotTiltPsi)=rotp;
						YY(rotTiltPsi)=tiltp;
						ZZ(rotTiltPsi)=psip;
					}
					ang1.push_back(rotTiltPsi);
					iter1.moveNext();
					if (iter1.hasNext())
						anotherIteration=true;
				}
			} while (anotherIteration);

			// Process both sets of angles
			for (size_t i=0; i<ang2.size(); ++i)
			{
				const Matrix1D<double> &anglesi=ang2[i];
				double rotu=XX(anglesi);
				double tiltu=YY(anglesi);
				double psiu=ZZ(anglesi);
				Euler_angles2matrix(rotu,tiltu,psiu,Eu,false);
				/*std::cout << "------UNTILTED MATRIX------" << std::endl;
				std::cout << Eu << std::endl;
				std::cout << "vector" << std::endl;
				std::cout << Eu(2,0) << "  " << Eu(2,1) << "  " << Eu(2,2) << std::endl;*/


				for (size_t j=0; j<ang1.size(); ++j)
				{
					const Matrix1D<double> &anglesj=ang1[j];
					double rott=XX(anglesj);
					double tiltt=YY(anglesj);
					double psit=ZZ(anglesj);
					double alpha_x, alpha_y;
					Euler_angles2matrix(rott,tiltt,psit,Et,false);
					//////////////////////////////////////////////////////////////////
					double untilt_angles[3]={rotu, tiltu, psiu}, tilt_angles[3]={rott, tiltt, psit};
					angles2tranformation(untilt_angles, tilt_angles, alpha_x, alpha_y);
					//std::cout << "alpha = " << (alpha_x*alpha_x+alpha_y*alpha_y) << std::endl;
					//////////////////////////////////////////////////////////////////
					/*std::cout << "------TILTED MATRIX------" << std::endl;
					std::cout << Et << std::endl;
					std::cout << "vector" << std::endl;
					std::cout << Et(2,0) << "  " << Et(2,1) << "  " << Et(2,2) << std::endl;
					std::cout << "---------------------------" << std::endl;
					std::cout << "---------------------------" << std::endl;*/
					R=Eu*Et.transpose();
					double rotTransf, tiltTransf, psiTransf;
					Euler_matrix2angles(R, rotTransf, tiltTransf, psiTransf);
					std::cout << "Rot_and_Tilt " << rotTransf << " " << tiltTransf << std::endl;
					//LINEA ANTERIOR ORIGINAL

				XX(z) = Eu(2,0) - Et(2,0);
				YY(z) = Eu(2,1) - Et(2,1);
				ZZ(z) = Eu(2,2) - Et(2,2);

				alpha = atan2(YY(z), XX(z));        //Expressed in rad
				beta = atan2(XX(z)/cos(alpha), ZZ(z));   //Expressed in rad
				std::cout << "alpha = " << alpha*180/PI << std::endl;
				std::cout << "beta = " << beta*180/PI << std::endl;
				}
			}
		}
		else
			N=0;

		if (N>0)
		{
			double meanDistance=cumulatedDistance/ang2.size();
			DFweights.setValue(MDL_ANGLE_DIFF,meanDistance,newObjId);
		}
		else
			if (newObjId>0)
				DFweights.setValue(MDL_ANGLE_DIFF,-1.0,newObjId);
		anotherImageIn2=iter2.hasNext();
	}

	std::complex<double> qu[4], qt[4], M[4], Inv_qu[4], test[4], P1[4], P2[4], Inv_quu[4];
	double rotu=34*PI/180, tiltu=10*PI/180, psiu=5*PI/180;
	double rott=25*PI/180, tiltt=15*PI/180, psit=40*PI/180;


    quaternion2Paulibasis(rotu, tiltu, psiu, qu);
    /*std::cout << "quaternion2Pauli" << std::endl;
    std::cout << "Untilted " << qu[0] << " " << qu[1] << " " << qu[2] << " " << qu[3] << std::endl;
    std::cout << "      " << std::endl;*/

    Paulibasis2matrix(qu,M);
    /*std::cout << "Pauli2matrix" << std::endl;
    std::cout << "Matriz   " << M[0] << " " << M[1] << " " << M[2] << " " << M[3] << std::endl;
    std::cout << "      " << std::endl;*/

    inverse_matrixSU2(M, Inv_qu);
    /*std::cout << "inverse_matrixSU(2)" << std::endl;
    std::cout << "Inversa  " << Inv_qu[0] << " " << Inv_qu[1] << " " << Inv_qu[2] << " " << Inv_qu[3] << std::endl;
    std::cout << "      " << std::endl;*/

    quaternion2Paulibasis(rott, tiltt, psit, qt);
    /*std::cout << "quaternion2Pauli" << std::endl;
    std::cout << "Tilted " << qt[0] << " " << qt[1] << " " << qt[2] << " " << qt[3] << std::endl;
    std::cout << "      " << std::endl;*/

    InversefromPaulibasis(qu,Inv_quu);

    Pauliproduct(qt, Inv_qu, P1);
    /*std::cout << "Pauliproduct" << std::endl;
    std::cout << "quaternion qt  " << P1[0] << " " << P1[1] << " " << P1[2] << " " << P1[3] << std::endl;
    std::cout << "      " << std::endl;
    std::cout << "-----------------------------------" << std::endl;*/

    //double alpha_x, alpha_y;
    //extrarotationangles(P1, alpha_x, alpha_y);
    //std::cout << "alpha_x = " << alpha_x << " " << "alpha_y = " << alpha_y << std::endl;
}
Ejemplo n.º 10
0
    void run ()
    {
        mask.allowed_data_types = INT_MASK;

        // Main program =========================================================
        params.V1.read(fn1);
        params.V1().setXmippOrigin();
        params.V2.read(fn2);
        params.V2().setXmippOrigin();

        // Initialize best_fit
        double best_fit = 1e38;
        Matrix1D<double> best_align(8);
        bool first = true;

        // Generate mask
        if (mask_enabled)
        {
            mask.generate_mask(params.V1());
            params.mask_ptr = &(mask.get_binary_mask());
        }
        else
            params.mask_ptr = NULL;

        // Exhaustive search
        if (!usePowell && !useFRM)
        {
            // Count number of iterations
            int times = 1;
            if (!tell)
            {
                if (grey_scale0 != grey_scaleF)
                    times *= FLOOR(1 + (grey_scaleF - grey_scale0) / step_grey);
                if (grey_shift0 != grey_shiftF)
                    times *= FLOOR(1 + (grey_shiftF - grey_shift0) / step_grey_shift);
                if (rot0 != rotF)
                    times *= FLOOR(1 + (rotF - rot0) / step_rot);
                if (tilt0 != tiltF)
                    times *= FLOOR(1 + (tiltF - tilt0) / step_tilt);
                if (psi0 != psiF)
                    times *= FLOOR(1 + (psiF - psi0) / step_psi);
                if (scale0 != scaleF)
                    times *= FLOOR(1 + (scaleF - scale0) / step_scale);
                if (z0 != zF)
                    times *= FLOOR(1 + (zF - z0) / step_z);
                if (y0 != yF)
                    times *= FLOOR(1 + (yF - y0) / step_y);
                if (x0 != xF)
                    times *= FLOOR(1 + (xF - x0) / step_x);
                init_progress_bar(times);
            }
            else
                std::cout << "#grey_factor rot tilt psi scale z y x fitness\n";

            // Iterate
            int itime = 0;
            int step_time = CEIL((double)times / 60.0);
            Matrix1D<double> r(3);
            Matrix1D<double> trial(9);
            for (double grey_scale = grey_scale0; grey_scale <= grey_scaleF ; grey_scale += step_grey)
                for (double grey_shift = grey_shift0; grey_shift <= grey_shiftF ; grey_shift += step_grey_shift)
                    for (double rot = rot0; rot <= rotF ; rot += step_rot)
                        for (double tilt = tilt0; tilt <= tiltF ; tilt += step_tilt)
                            for (double psi = psi0; psi <= psiF ; psi += step_psi)
                                for (double scale = scale0; scale <= scaleF ; scale += step_scale)
                                    for (ZZ(r) = z0; ZZ(r) <= zF ; ZZ(r) += step_z)
                                        for (YY(r) = y0; YY(r) <= yF ; YY(r) += step_y)
                                            for (XX(r) = x0; XX(r) <= xF ; XX(r) += step_x)
                                            {
                                                // Form trial vector
                                                trial(0) = grey_scale;
                                                trial(1) = grey_shift;
                                                trial(2) = rot;
                                                trial(3) = tilt;
                                                trial(4) = psi;
                                                trial(5) = scale;
                                                trial(6) = ZZ(r);
                                                trial(7) = YY(r);
                                                trial(8) = XX(r);

                                                // Evaluate
                                                double fit = fitness(MATRIX1D_ARRAY(trial));

                                                // The best?
                                                if (fit < best_fit || first)
                                                {
                                                    best_fit = fit;
                                                    best_align = trial;
                                                    first = false;
                                                    if (tell)
                                                    	std::cout << "Best so far\n";
                                                }

                                                // Show fit
                                                if (tell)
                                                    std::cout << trial << " " << fit << std::endl;
                                                else
                                                    if (++itime % step_time == 0)
                                                        progress_bar(itime);
                                            }
            if (!tell)
                progress_bar(times);
        }
        else if (usePowell)
        {
            // Use Powell optimization
            Matrix1D<double> x(9), steps(9);
            double fitness;
            int iter;
            steps.initConstant(1);
            if (onlyShift)
                steps(0)=steps(1)=steps(2)=steps(3)=steps(4)=steps(5)=0;
            if (params.alignment_method == COVARIANCE)
                steps(0)=steps(1)=0;
            x(0)=grey_scale0;
            x(1)=grey_shift0;
            x(2)=rot0;
            x(3)=tilt0;
            x(4)=psi0;
            x(5)=scale0;
            x(6)=z0;
            x(7)=y0;
            x(8)=x0;

            powellOptimizer(x,1,9,&wrapperFitness,NULL,0.01,fitness,iter,steps,true);
            best_align=x;
            best_fit=fitness;
            first=false;
        }
        else if (useFRM)
        {
    		String scipionPython;
    		initializeScipionPython(scipionPython);
    		PyObject * pFunc = getPointerToPythonFRMFunction();
    		double rot,tilt,psi,x,y,z,score;
    		Matrix2D<double> A;
    		alignVolumesFRM(pFunc, params.V1(), params.V2(), Py_None, rot,tilt,psi,x,y,z,score,A,maxShift,maxFreq,params.mask_ptr);
    		best_align.initZeros(9);
    		best_align(0)=1; // Gray scale
    		best_align(1)=0; // Gray shift
    		best_align(2)=rot;
    		best_align(3)=tilt;
    		best_align(4)=psi;
    		best_align(5)=1; // Scale
    		best_align(6)=z;
    		best_align(7)=y;
    		best_align(8)=x;
    		best_fit=-score;
        }

        if (!first)
            std::cout << "The best correlation is for\n"
            << "Scale                  : " << best_align(5) << std::endl
            << "Translation (X,Y,Z)    : " << best_align(8)
            << " " << best_align(7) << " " << best_align(6)
            << std::endl
            << "Rotation (rot,tilt,psi): "
            << best_align(2) << " " << best_align(3) << " "
            << best_align(4) << std::endl
            << "Best grey scale       : " << best_align(0) << std::endl
            << "Best grey shift       : " << best_align(1) << std::endl
            << "Fitness value         : " << best_fit << std::endl;
        Matrix1D<double> r(3);
        XX(r)            = best_align(8);
        YY(r)            = best_align(7);
        ZZ(r)            = best_align(6);
        Matrix2D<double> A,Aaux;
        Euler_angles2matrix(best_align(2), best_align(3), best_align(4),
                            A, true);
        translation3DMatrix(r,Aaux);
        A = A * Aaux;
        scale3DMatrix(vectorR3(best_align(5), best_align(5), best_align(5)),Aaux);
        A = A * Aaux;
        if (verbose!=0)
			std::cout << "xmipp_transform_geometry will require the following values"
					  << "\n   Angles: " << best_align(2) << " "
					  << best_align(3) << " " << best_align(4)
					  << "\n   Shifts: " << A(0,3) << " " << A(1,3) << " " << A(2,3)
					  << std::endl;
        if (apply)
        {
            applyTransformation(params.V2(),params.Vaux(),MATRIX1D_ARRAY(best_align));
            params.V2()=params.Vaux();
            params.V2.write(fnOut);
        }
    }
Ejemplo n.º 11
0
void FourierProjector::project(double rot, double tilt, double psi, const MultidimArray<double> *ctf)
{
    double freqy, freqx;
    std::complex< double > f;
    Euler_angles2matrix(rot,tilt,psi,E);

    projectionFourier.initZeros();
    double maxFreq2=maxFrequency*maxFrequency;
    int Xdim=(int)XSIZE(VfourierRealCoefs);
    int Ydim=(int)YSIZE(VfourierRealCoefs);
    int Zdim=(int)ZSIZE(VfourierRealCoefs);

    for (size_t i=0; i<YSIZE(projectionFourier); ++i)
    {
        FFT_IDX2DIGFREQ(i,volumeSize,freqy);
        double freqy2=freqy*freqy;

        double freqYvol_X=MAT_ELEM(E,1,0)*freqy;
        double freqYvol_Y=MAT_ELEM(E,1,1)*freqy;
        double freqYvol_Z=MAT_ELEM(E,1,2)*freqy;
        for (size_t j=0; j<XSIZE(projectionFourier); ++j)
        {
            // The frequency of pairs (i,j) in 2D
            FFT_IDX2DIGFREQ(j,volumeSize,freqx);

            // Do not consider pixels with high frequency
            if ((freqy2+freqx*freqx)>maxFreq2)
                continue;

            // Compute corresponding frequency in the volume
            double freqvol_X=freqYvol_X+MAT_ELEM(E,0,0)*freqx;
            double freqvol_Y=freqYvol_Y+MAT_ELEM(E,0,1)*freqx;
            double freqvol_Z=freqYvol_Z+MAT_ELEM(E,0,2)*freqx;

            double c,d;
            if (BSplineDeg==0)
            {
                // 0 order interpolation
                // Compute corresponding index in the volume
                int kVolume=(int)round(freqvol_Z*volumePaddedSize);
                int iVolume=(int)round(freqvol_Y*volumePaddedSize);
                int jVolume=(int)round(freqvol_X*volumePaddedSize);
                c = A3D_ELEM(VfourierRealCoefs,kVolume,iVolume,jVolume);
                d = A3D_ELEM(VfourierImagCoefs,kVolume,iVolume,jVolume);
            }
            else if (BSplineDeg==1)
            {
                // B-spline linear interpolation
                double kVolume=freqvol_Z*volumePaddedSize;
                double iVolume=freqvol_Y*volumePaddedSize;
                double jVolume=freqvol_X*volumePaddedSize;
                c=VfourierRealCoefs.interpolatedElement3D(jVolume,iVolume,kVolume);
                d=VfourierImagCoefs.interpolatedElement3D(jVolume,iVolume,kVolume);
            }
            else
            {
                // B-spline cubic interpolation
                double kVolume=freqvol_Z*volumePaddedSize;
                double iVolume=freqvol_Y*volumePaddedSize;
                double jVolume=freqvol_X*volumePaddedSize;

                // Commented for speed-up, the corresponding code is below
                // c=VfourierRealCoefs.interpolatedElementBSpline3D(jVolume,iVolume,kVolume);
                // d=VfourierImagCoefs.interpolatedElementBSpline3D(jVolume,iVolume,kVolume);

                // The code below is a replicate for speed reasons of interpolatedElementBSpline3D
                double z=kVolume;
                double y=iVolume;
                double x=jVolume;

                // Logical to physical
                z -= STARTINGZ(VfourierRealCoefs);
                y -= STARTINGY(VfourierRealCoefs);
                x -= STARTINGX(VfourierRealCoefs);

                int l1 = (int)ceil(x - 2);
                int l2 = l1 + 3;

                int m1 = (int)ceil(y - 2);
                int m2 = m1 + 3;

                int n1 = (int)ceil(z - 2);
                int n2 = n1 + 3;

                c = d = 0.0;
                double aux;
                for (int nn = n1; nn <= n2; nn++)
                {
                    int equivalent_nn=nn;
                    if      (nn<0)
                        equivalent_nn=-nn-1;
                    else if (nn>=Zdim)
                        equivalent_nn=2*Zdim-nn-1;
                    double yxsumRe = 0.0, yxsumIm = 0.0;
                    for (int m = m1; m <= m2; m++)
                    {
                        int equivalent_m=m;
                        if      (m<0)
                            equivalent_m=-m-1;
                        else if (m>=Ydim)
                            equivalent_m=2*Ydim-m-1;
                        double xsumRe = 0.0, xsumIm = 0.0;
                        for (int l = l1; l <= l2; l++)
                        {
                            double xminusl = x - (double) l;
                            int equivalent_l=l;
                            if      (l<0)
                                equivalent_l=-l-1;
                            else if (l>=Xdim)
                                equivalent_l=2*Xdim-l-1;
                            double CoeffRe = (double) DIRECT_A3D_ELEM(VfourierRealCoefs,equivalent_nn,equivalent_m,equivalent_l);
                            double CoeffIm = (double) DIRECT_A3D_ELEM(VfourierImagCoefs,equivalent_nn,equivalent_m,equivalent_l);
                            BSPLINE03(aux,xminusl);
                            xsumRe += CoeffRe * aux;
                            xsumIm += CoeffIm * aux;
                        }

                        double yminusm = y - (double) m;
                        BSPLINE03(aux,yminusm);
						yxsumRe += xsumRe * aux;
						yxsumIm += xsumIm * aux;
                    }

                    double zminusn = z - (double) nn;
                    BSPLINE03(aux,zminusn);
					c += yxsumRe * aux;
					d += yxsumIm * aux;
                }
            }

            // Phase shift to move the origin of the image to the corner
            double a=DIRECT_A2D_ELEM(phaseShiftImgA,i,j);
            double b=DIRECT_A2D_ELEM(phaseShiftImgB,i,j);
            if (ctf!=NULL)
            {
            	double ctfij=DIRECT_A2D_ELEM(*ctf,i,j);
            	a*=ctfij;
            	b*=ctfij;
            }

            // Multiply Fourier coefficient in volume times phase shift
            double ac = a * c;
            double bd = b * d;
            double ab_cd = (a + b) * (c + d);

            // And store the multiplication
            double *ptrI_ij=(double *)&DIRECT_A2D_ELEM(projectionFourier,i,j);
            *ptrI_ij = ac - bd;
            *(ptrI_ij+1) = ab_cd - ac - bd;
        }
    }
    transformer2D.inverseFourierTransform();
}
Ejemplo n.º 12
0
	DOUBLE check_tilt_pairs(DOUBLE rot1, DOUBLE tilt1, DOUBLE psi1,
			DOUBLE &alpha, DOUBLE &tilt_angle, DOUBLE &beta)
	{
	    // Transformation matrices
		Matrix1D<DOUBLE> axis(3);
	    Matrix2D<DOUBLE> E1, E2;
	    axis.resize(3);
	    DOUBLE aux, sine_tilt_angle;
	    DOUBLE rot2 = alpha, tilt2 = tilt_angle, psi2 = beta;

	    // Calculate the transformation from one setting to the second one.
	    Euler_angles2matrix(psi1, tilt1, rot1, E1);
	    Euler_angles2matrix(psi2, tilt2, rot2, E2);
	    E2 = E2 * E1.inv();

	    // Get the tilt angle (and its sine)
	    aux = ( E2(0,0) + E2(1,1) + E2(2,2) - 1. ) / 2.;
	    if (ABS(aux) - 1. > XMIPP_EQUAL_ACCURACY)
	    	REPORT_ERROR("BUG: aux>1");
	    tilt_angle = ACOSD(aux);
	    sine_tilt_angle = 2. * SIND(tilt_angle);

	    // Get the tilt axis direction in angles alpha and beta
	    if (sine_tilt_angle > XMIPP_EQUAL_ACCURACY)
	    {
	    	axis(0) = ( E2(2,1) - E2(1,2) ) / sine_tilt_angle;
	    	axis(1) = ( E2(0,2) - E2(2,0) ) / sine_tilt_angle;
	    	axis(2) = ( E2(1,0) - E2(0,1) ) / sine_tilt_angle;
	    }
	    else
	    {
	    	axis(0) = axis(1) = 0.;
	    	axis(2) = 1.;
	    }

	    // Apply E1.inv() to the axis to get everyone in the same coordinate system again
	    axis = E1.inv() * axis;

	    // Convert to alpha and beta angle
	    Euler_direction2angles(axis, alpha, beta);

	    // Enforce positive beta: choose the other Euler angle combination to express the same direction
	    if (beta < 0.)
	    {
	    	beta = -beta;
	    	alpha+= 180.;
	    }

	    // Let alpha go from 0 to 360 degrees
	    alpha = realWRAP(alpha, 0., 360.);


	    // Return the value that needs to be optimized
	    DOUBLE minimizer=0.;
	    if (exp_beta < 999.)
	    	minimizer = ABS(beta - exp_beta);
	    if (exp_tilt < 999.)
	    	minimizer += ABS(tilt_angle - exp_tilt);

	    return minimizer;

	}
Ejemplo n.º 13
0
// Evaluate plane ----------------------------------------------------------
double evaluatePlane(double rot, double tilt,
                     const MultidimArray<double> *V, const MultidimArray<double> *Vmag,
                     double maxFreq, double planeWidth, int direction,
                     MultidimArray<double> *Vdraw=NULL,
                     bool setPos=false, double rotPos=0, double tiltPos=0)
{
    if (rot<0 || rot>360 || tilt<-90 || tilt>90)
        return 0;

    Matrix2D<double> E, Einv;
    Euler_angles2matrix(rot,tilt,0,E);
    Einv=E.transpose();

    if (setPos)
    {
        Matrix2D<double> Epos;
        Euler_angles2matrix(rotPos,tiltPos,0,Epos);
        double angle=acos(E(2,0)*Epos(2,0)+E(2,1)*Epos(2,1)+E(2,2)*Epos(2,2));
        angle=RAD2DEG(angle);
        if (fabs(angle)<20 || fabs(180-angle)<20)
            return 0;
    }

    size_t N=XMIPP_MAX(XSIZE(*Vmag),YSIZE(*Vmag)/2);
    N=XMIPP_MAX(N,ZSIZE(*Vmag)/2);
    double df=0.5/N;
    Matrix1D<double> freq(3), freqp(3);
    Matrix1D<int> idx(3);
    double sumNeg=0, sumPos=0;
    int Nneg=0, Npos=0;
    double maxFreq2=maxFreq*maxFreq;
    int iPlaneWidth=(int)ceil(planeWidth);
    for (double ix=0; ix<=N; ix++)
    {
        XX(freq)=ix*df;
        double fx2=XX(freq)*XX(freq);
        if (fx2>maxFreq2)
            continue;
        for (double iy=-(int)N; iy<=N; iy++)
        {
            YY(freq)=iy*df;
            double fx2fy2=fx2+YY(freq)*YY(freq);
            if (fx2fy2>maxFreq2)
                continue;
            for (int iz=-iPlaneWidth; iz<=iPlaneWidth; iz++)
            {
                if (iz==0 || ix==0 || iy==0)
                    continue;

                // Frequency in the coordinate system of the plane
                ZZ(freq)=iz*df;

                // Frequency in the coordinate system of the volume
                SPEED_UP_temps012;
                M3x3_BY_V3x1(freqp,Einv,freq);
                bool inverted=false;
                if (XX(freqp)<0)
                {
                    XX(freqp)=-XX(freqp);
                    YY(freqp)=-YY(freqp);
                    ZZ(freqp)=-ZZ(freqp);
                    inverted=true;
                }

                // Get the corresponding index
                DIGFREQ2FFT_IDX(ZZ(freqp), ZSIZE(*V), ZZ(idx));
                DIGFREQ2FFT_IDX(YY(freqp), YSIZE(*V), YY(idx));
                DIGFREQ2FFT_IDX(XX(freqp), XSIZE(*V), XX(idx));
                if (XX(idx) < STARTINGX(*Vmag) || XX(idx) > FINISHINGX(*Vmag) ||
                    YY(idx) < STARTINGY(*Vmag) || YY(idx) > FINISHINGY(*Vmag) ||
                    ZZ(idx) < STARTINGZ(*Vmag) || ZZ(idx) > FINISHINGZ(*Vmag))
                    continue;

                // Make the corresponding sums
                bool negativeSum;
                if (direction==1)
                    negativeSum=iz<0;
                else
                    negativeSum=iz>0;
                double val=A3D_ELEM(*Vmag,ZZ(idx),YY(idx),XX(idx));
                if ((negativeSum && !inverted) || (!negativeSum && inverted)) // XOR
                {
                    sumNeg+=val;
                    Nneg++;
                    if (Vdraw!=NULL)
                        (*Vdraw)(idx)=2*direction*val;
                }
                else
                {
                    sumPos+=val;
                    Npos++;
                    if (Vdraw!=NULL)
                        (*Vdraw)(idx)=1.0/2.0*direction*val;
                }
            }
        }
    }
    if (fabs(Nneg-Npos)/(0.5*(Nneg+Npos))>0.5)
        // If there is a difference of more than 50%
        return 1e38;
    if (Nneg!=0)
        sumNeg/=Nneg;
    else
        return 1e38;
    if (Npos!=0)
        sumPos/=Npos;
    else
        return 1e38;

    return -(sumPos-sumNeg);
}
Ejemplo n.º 14
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[])
{
   
    double angs[3];
    const double *p_angs=mxGetPr(prhs[1]);
    angs[0]=(double)p_angs[0];
    angs[1]=(double)p_angs[1];
    angs[2]=(double)p_angs[2];

    Matrix1D<double> axis;
    getMatrix1D(prhs[2],axis);

    Matrix2D<double> A3D, A2D;
    
    bool wrap = (bool)mxGetScalar(prhs[5]);
    mwSize ndims = mxGetNumberOfDimensions(prhs[0]);
    

    /*mode: 1 euler, 2 align_with_Z, 3 axis, 4 tform*/
    switch ((int)mxGetScalar(prhs[3])) {
        case 1:
            Euler_angles2matrix(angs[0], angs[1], angs[2], A3D, true);
            break;
        case 2:
            alignWithZ(axis,A3D);
            break;
        case 3:
            rotation3DMatrix(angs[0], axis, A3D);
            A2D.resize(3,3);
            A2D(0,0)=A3D(0,0); A2D(0,1)=A3D(0,1); A2D(0,2)=A3D(0,2);
            A2D(1,0)=A3D(1,0); A2D(1,1)=A3D(1,1); A2D(1,2)=A3D(1,2);
            A2D(2,0)=A3D(2,0); A2D(2,1)=A3D(2,1); A2D(2,2)=A3D(2,2);
            break;
        case 4:
            getMatrix2D(prhs[6],A2D);
            A3D = A2D;
            break;
    }
    
    if (ndims == 2)
    {
        Image<double> img, img_out;
        getMatrix2D(prhs[0],img());
        if (MAT_XSIZE(A2D) != 0)
        {
			applyGeometry(BSPLINE3,img_out(), img(), A2D, IS_NOT_INV, wrap);
			setMatrix2D(img_out(),plhs[0]);
        }
        else 
        {
            setMatrix2D(img(),plhs[0]);
        }
    }
    else
    {
        Image<double> vol, vol_out;
        getMatrix3D(prhs[0],vol());
		applyGeometry(BSPLINE3, vol_out(), vol(), A3D, IS_NOT_INV, wrap);
		setMatrix3D(vol_out(),plhs[0]);
    }
}