コード例 #1
0
ファイル: projector.cpp プロジェクト: dtegunov/vlion
void Projector::initialiseData(int current_size)
{
	// By default r_max is half ori_size
	if (current_size < 0)
		r_max = ori_size / 2;
	else
		r_max = current_size / 2;

	// Never allow r_max beyond Nyquist...
	r_max = XMIPP_MIN(r_max, ori_size / 2);

	// Set pad_size
	pad_size = 2 * (padding_factor * r_max + 1) + 1;

	// Short side of data array
	switch (ref_dim)
	{
	case 2:
	   data.resize(pad_size, pad_size / 2 + 1);
	   break;
	case 3:
	   data.resize(pad_size, pad_size, pad_size / 2 + 1);
	   break;
	default:
	   REPORT_ERROR("Projector::resizeData%%ERROR: Dimension of the data array should be 2 or 3");
	}

	// Set origin in the y.z-center, but on the left side for x.
	data.setXmippOrigin();
	data.xinit=0;

}
コード例 #2
0
	void read(int argc, char **argv)
	{

		parser.setCommandLine(argc, argv);

		int general_section = parser.addSection("General Options");
		fn_unt = parser.getOption("--u", "STAR file with the untilted xy-coordinates");
		fn_til = parser.getOption("--t", "STAR file with the untilted xy-coordinates");
		size = textToInteger(parser.getOption("--size", "Largest dimension of the micrograph (in pixels), e.g. 4096"));
		dim = textToInteger(parser.getOption("--dim", "Dimension of boxed particles (for EMAN .box files in pixels)", "200"));
		acc = textToFloat(parser.getOption("--acc", "Allowed accuracy (in pixels), e.g. half the particle diameter"));
		tilt = textToFloat(parser.getOption("--tilt", "Fix tilt angle (in degrees)", "99999."));
		rot = textToFloat(parser.getOption("--rot", "Fix direction of the tilt axis (in degrees), 0 = along y, 90 = along x", "99999."));
		do_opt = !parser.checkOption("--dont_opt", "Skip optimization of the transformation matrix");
		mind2 = ROUND(acc * acc);

		int angle_section = parser.addSection("Specified tilt axis and translational search ranges");
		tilt0 = textToFloat(parser.getOption("--tilt0", "Minimum tilt angle (in degrees)","0."));
		tiltF = textToFloat(parser.getOption("--tiltF", "Maximum tilt angle (in degrees)","99999."));
		if (tiltF == 99999.) tiltF = tilt0;
		tiltStep = textToFloat(parser.getOption("--tiltStep", "Tilt angle step size (in degrees)","1."));

		rot0 = textToFloat(parser.getOption("--rot0", "Minimum rot angle (in degrees)","0."));
		rotF = textToFloat(parser.getOption("--rotF", "Maximum rot angle (in degrees)","99999."));
		if (rotF == 99999.) rotF = rot0;
		rotStep = textToFloat(parser.getOption("--rotStep", "Rot angle step size (in degrees)","1."));

		x0 = textToInteger(parser.getOption("--x0", "Minimum X offset (pixels)","-99999"));
		xF = textToInteger(parser.getOption("--xF", "Maximum X offset (pixels)","99999"));
		xStep = textToInteger(parser.getOption("--xStep", "X offset step size (pixels)","-1"));
		y0 = textToInteger(parser.getOption("--y0", "Minimum Y offset (pixels)","-99999"));
		yF = textToInteger(parser.getOption("--yF", "Maximum Y offset (pixels)","99999"));
		yStep = textToInteger(parser.getOption("--yStep", "Y offset step size (pixels)","-1"));

       	// Check for errors in the command-line option
    	if (parser.checkForErrors())
    		REPORT_ERROR("Errors encountered on the command line, exiting...");

		// If tilt and rot were given: do not search those
		if (tilt != 99999.)
		{
			tilt0 = tiltF = tilt;
			tiltStep = 1.;
		}
		if (rot != 99999.)
		{
			rot0 = rotF = rot;
			rotStep = 1.;
		}

		// By default search the entire micrograph
		x0 = XMIPP_MAX(x0, -size);
		xF = XMIPP_MIN(xF, size);
		// By default use a xStep of one third the accuracy
		if (xStep < 0)
			xStep = acc / 3;

		// By default treat y search in the same way as the x-search
		if (y0 == -99999)
			y0 = x0;
		if (yF == 99999)
			yF = xF;
		if (yStep < 0)
			yStep = xStep;

		// Done reading, now fill p_unt and p_til
		MDunt.read(fn_unt);
		MDtil.read(fn_til);

		// Check for the correct labels
		if (!MDunt.containsLabel(EMDL_IMAGE_COORD_X) || !MDunt.containsLabel(EMDL_IMAGE_COORD_Y))
			REPORT_ERROR("ERROR: Untilted STAR file does not contain the rlnCoordinateX or Y labels");
		if (!MDtil.containsLabel(EMDL_IMAGE_COORD_X) || !MDtil.containsLabel(EMDL_IMAGE_COORD_Y))
			REPORT_ERROR("ERROR: Tilted STAR file does not contain the rlnCoordinateX or Y labels");

		double x, y;

		p_unt.clear();
		FOR_ALL_OBJECTS_IN_METADATA_TABLE(MDunt)
		{
			MDunt.getValue(EMDL_IMAGE_COORD_X, x);
			MDunt.getValue(EMDL_IMAGE_COORD_Y, y);
			p_unt.push_back((int)x);
			p_unt.push_back((int)y);
		}
		p_til.clear();
		FOR_ALL_OBJECTS_IN_METADATA_TABLE(MDtil)
		{
			MDtil.getValue(EMDL_IMAGE_COORD_X, x);
			MDtil.getValue(EMDL_IMAGE_COORD_Y, y);
			p_til.push_back((int)x);
			p_til.push_back((int)y);
		}

		// Initialize best transformation params
		best_x = best_y = 9999;
		best_rot = best_tilt = 9999.;

	}
コード例 #3
0
ファイル: splines.cpp プロジェクト: josegutab/scipion
//#define DEBUG
void spatial_Bspline032voxels(const GridVolume &vol_splines,
                              MultidimArray<double> *vol_voxels, int Zdim, int Ydim, int Xdim)
{
    // Resize and set starting corner .......................................
    if (Zdim == 0 || Ydim == 0 || Xdim == 0)
    {
        Matrix1D<double> size = vol_splines.grid(0).highest -
                                vol_splines.grid(0).lowest;
        Matrix1D<double> corner = vol_splines.grid(0).lowest;
        (*vol_voxels).initZeros(CEIL(ZZ(size)), CEIL(YY(size)), CEIL(XX(size)));
        STARTINGX(*vol_voxels) = FLOOR(XX(corner));
        STARTINGY(*vol_voxels) = FLOOR(YY(corner));
        STARTINGZ(*vol_voxels) = FLOOR(ZZ(corner));
    }
    else
    {
        (*vol_voxels).initZeros(Zdim, Ydim, Xdim);
        (*vol_voxels).setXmippOrigin();
    }

    // Convert each subvolume ...............................................
    for (size_t i = 0; i < vol_splines.VolumesNo(); i++)
    {
        spatial_Bspline032voxels_SimpleGrid(vol_splines(i)(), vol_splines.grid(i),
                                            vol_voxels);
#ifdef DEBUG
        std::cout << "Spline grid no " << i << " stats: ";
        vol_splines(i)().printStats();
        std::cout << std::endl;
        std::cout << "So far vol stats: ";
        (*vol_voxels).printStats();
        std::cout << std::endl;
        VolumeXmipp save;
        save() = *vol_voxels;
        save.write((std::string)"PPPvoxels" + integerToString(i));
#endif
    }

    // Now normalise the resulting volume ..................................
    double inorm = 1.0 / sum_spatial_Bspline03_Grid(vol_splines.grid());
    FOR_ALL_ELEMENTS_IN_ARRAY3D(*vol_voxels)
    A3D_ELEM(*vol_voxels, k, i, j) *= inorm;

    // Set voxels outside interest region to minimum value .................
    double R = vol_splines.grid(0).get_interest_radius();
    if (R != -1)
    {
        double R2 = (R - 6) * (R - 6);

        // Compute minimum value within sphere
        double min_val = A3D_ELEM(*vol_voxels, 0, 0, 0);
        FOR_ALL_ELEMENTS_IN_ARRAY3D(*vol_voxels)
        if (j*j + i*i + k*k <= R2 - 4)
            min_val = XMIPP_MIN(min_val, A3D_ELEM(*vol_voxels, k, i, j));

        // Substitute minimum value
        R2 = (R - 2) * (R - 2);
        FOR_ALL_ELEMENTS_IN_ARRAY3D(*vol_voxels)
        if (j*j + i*i + k*k >= R2)
            A3D_ELEM(*vol_voxels, k, i, j) = min_val;
    }
コード例 #4
0
ファイル: splines.cpp プロジェクト: josegutab/scipion
//#define DEBUG
double spatial_Bspline03_proj(
    const Matrix1D<double> &r, const Matrix1D<double> &u)
{
    // Avoids divisions by zero and allows orthogonal rays computation
    static Matrix1D<double> ur(3);
    if (XX(u) == 0) XX(ur) = XMIPP_EQUAL_ACCURACY;
    else XX(ur) = XX(u);
    if (YY(u) == 0) YY(ur) = XMIPP_EQUAL_ACCURACY;
    else YY(ur) = YY(u);
    if (ZZ(u) == 0) ZZ(ur) = XMIPP_EQUAL_ACCURACY;
    else ZZ(ur) = ZZ(u);

    // Some precalculated variables
    double x_sign = SGN(XX(ur));
    double y_sign = SGN(YY(ur));
    double z_sign = SGN(ZZ(ur));

    // Compute the minimum and maximum alpha for the ray
    double alpha_xmin = (-2 - XX(r)) / XX(ur);
    double alpha_xmax = (2 - XX(r)) / XX(ur);
    double alpha_ymin = (-2 - YY(r)) / YY(ur);
    double alpha_ymax = (2 - YY(r)) / YY(ur);
    double alpha_zmin = (-2 - ZZ(r)) / ZZ(ur);
    double alpha_zmax = (2 - ZZ(r)) / ZZ(ur);

    double alpha_min = XMIPP_MAX(XMIPP_MIN(alpha_xmin, alpha_xmax),
                           XMIPP_MIN(alpha_ymin, alpha_ymax));
    alpha_min = XMIPP_MAX(alpha_min, XMIPP_MIN(alpha_zmin, alpha_zmax));
    double alpha_max = XMIPP_MIN(XMIPP_MAX(alpha_xmin, alpha_xmax),
                           XMIPP_MAX(alpha_ymin, alpha_ymax));
    alpha_max = XMIPP_MIN(alpha_max, XMIPP_MAX(alpha_zmin, alpha_zmax));
    if (alpha_max - alpha_min < XMIPP_EQUAL_ACCURACY) return 0.0;

#ifdef DEBUG
    std::cout << "Pixel:  " << r.transpose() << std::endl
    << "Dir:    " << ur.transpose() << std::endl
    << "Alpha x:" << alpha_xmin << " " << alpha_xmax << std::endl
    << "        " << (r + alpha_xmin*ur).transpose() << std::endl
    << "        " << (r + alpha_xmax*ur).transpose() << std::endl
    << "Alpha y:" << alpha_ymin << " " << alpha_ymax << std::endl
    << "        " << (r + alpha_ymin*ur).transpose() << std::endl
    << "        " << (r + alpha_ymax*ur).transpose() << std::endl
    << "Alpha z:" << alpha_zmin << " " << alpha_zmax << std::endl
    << "        " << (r + alpha_zmin*ur).transpose() << std::endl
    << "        " << (r + alpha_zmax*ur).transpose() << std::endl
    << "alpha  :" << alpha_min  << " " << alpha_max  << std::endl
    << std::endl;
#endif

    // Compute the first point in the volume intersecting the ray
    static Matrix1D<double> v(3);
    V3_BY_CT(v, ur, alpha_min);
    V3_PLUS_V3(v, r, v);

#ifdef DEBUG
    std::cout << "First entry point: " << v.transpose() << std::endl;
    std::cout << "   Alpha_min: " << alpha_min << std::endl;
#endif

    // Follow the ray
    double alpha = alpha_min;
    double ray_sum = 0;
    do
    {
        double alpha_x = (XX(v) + x_sign - XX(r)) / XX(ur);
        double alpha_y = (YY(v) + y_sign - YY(r)) / YY(ur);
        double alpha_z = (ZZ(v) + z_sign - ZZ(r)) / ZZ(ur);

        // Which dimension will ray move next step into?, it isn't neccesary to be only
        // one.
        double diffx = ABS(alpha - alpha_x);
        double diffy = ABS(alpha - alpha_y);
        double diffz = ABS(alpha - alpha_z);
        double diff_alpha = XMIPP_MIN(XMIPP_MIN(diffx, diffy), diffz);
        ray_sum += spatial_Bspline03_integral(r, ur, alpha, alpha + diff_alpha);

        // Update alpha and the next entry point
        if (ABS(diff_alpha - diffx) <= XMIPP_EQUAL_ACCURACY) alpha = alpha_x;
        if (ABS(diff_alpha - diffy) <= XMIPP_EQUAL_ACCURACY) alpha = alpha_y;
        if (ABS(diff_alpha - diffz) <= XMIPP_EQUAL_ACCURACY) alpha = alpha_z;
        XX(v) += diff_alpha * XX(ur);
        YY(v) += diff_alpha * YY(ur);
        ZZ(v) += diff_alpha * ZZ(ur);

#ifdef DEBUG
        std::cout << "Alpha x,y,z: " << alpha_x << " " << alpha_y
        << " " << alpha_z << " ---> " << alpha << std::endl;

        std::cout << "    Next entry point: " << v.transpose() << std::endl
        << "    diff_alpha: " << diff_alpha << std::endl
        << "    ray_sum: " << ray_sum << std::endl
        << "    Alfa tot: " << alpha << "alpha_max: " << alpha_max <<
        std::endl;

#endif
    }
    while ((alpha_max - alpha) > XMIPP_EQUAL_ACCURACY);
    return ray_sum;
}
コード例 #5
0
ファイル: normalize.cpp プロジェクト: josegutab/scipion
//#define DEBUG
void normalize_tomography(MultidimArray<double> &I, double tilt, double &mui,
                          double &sigmai, bool tiltMask, bool tomography0,
                          double mu0, double sigma0)
{
    // Tilt series are always 2D
    I.checkDimension(2);

    const int L=2;

    // Build a mask using the tilt angle
    I.setXmippOrigin();
    MultidimArray<int> mask;
    mask.initZeros(I);
    int Xdimtilt=(int)XMIPP_MIN(FLOOR(0.5*(XSIZE(I)*cos(DEG2RAD(tilt)))),
                           0.5*(XSIZE(I)-(2*L+1)));
    int N=0;
    for (int i=STARTINGY(I); i<=FINISHINGY(I); i++)
        for (int j=-Xdimtilt; j<=Xdimtilt;j++)
        {
            A2D_ELEM(mask,i,j)=1;
            N++;
        }

    // Estimate the local variance
    MultidimArray<double> localVariance;
    localVariance.initZeros(I);
    double meanVariance=0;
    FOR_ALL_ELEMENTS_IN_ARRAY2D(I)
    {
        // Center a mask of size 5x5 and estimate the variance within the mask
        double meanPiece=0, variancePiece=0;
        double Npiece=0;
        for (int ii=i-L; ii<=i+L; ii++)
        {
            if (INSIDEY(I,ii))
                for (int jj=j-L; jj<=j+L; jj++)
                {
                    if (INSIDEX(I,jj))
                    {
                        double pixval=A2D_ELEM(I,ii,jj);
                        meanPiece+=pixval;
                        variancePiece+=pixval*pixval;
                        ++Npiece;
                    }
                }
        }
        meanPiece/=Npiece;
        variancePiece=variancePiece/(Npiece-1)-
                      Npiece/(Npiece-1)*meanPiece*meanPiece;
        A2D_ELEM(localVariance,i,j)=variancePiece;
        meanVariance+=variancePiece;
    }
    meanVariance*=1.0/N;

    // Test the hypothesis that the variance in this piece is
    // the same as the variance in the whole image
    double iFu=1/icdf_FSnedecor(4*L*L+4*L,N-1,0.975);
    double iFl=1/icdf_FSnedecor(4*L*L+4*L,N-1,0.025);
    double iMeanVariance=1.0/meanVariance;
    FOR_ALL_ELEMENTS_IN_ARRAY2D(localVariance)
    {
        if (A2D_ELEM(localVariance,i,j)==0)
            A2D_ELEM(mask,i,j)=-2;
        if (A2D_ELEM(mask,i,j)==1)
        {
            double ratio=A2D_ELEM(localVariance,i,j)*iMeanVariance;
            double thl=ratio*iFu;
            double thu=ratio*iFl;
            if (thl>1 || thu<1)
                A2D_ELEM(mask,i,j)=-1;
        }
    }
#ifdef DEBUG
    Image<double> save;
    save()=I;
    save.write("PPP.xmp");
    save()=localVariance;
    save.write("PPPLocalVariance.xmp");
    Image<int> savemask;
    savemask()=mask;
    savemask.write("PPPmask.xmp");
#endif

    // Compute the statistics again in the reduced mask
    double avg, stddev, min, max;
    computeStats_within_binary_mask(mask, I, min, max, avg, stddev);
    double cosTilt=cos(DEG2RAD(tilt));
    double iCosTilt=1.0/cosTilt;
    if (tomography0)
    {
        double iadjustedStddev=1.0/(sigma0*cosTilt);
        FOR_ALL_ELEMENTS_IN_ARRAY2D(I)
        switch (A2D_ELEM(mask,i,j))
        {
        case -2:
            A2D_ELEM(I,i,j)=0;
            break;
        case 0:
            if (tiltMask)
                A2D_ELEM(I,i,j)=0;
            else
                A2D_ELEM(I,i,j)=(A2D_ELEM(I,i,j)*iCosTilt-mu0)*iadjustedStddev;
            break;
        case -1:
        case 1:
            A2D_ELEM(I,i,j)=(A2D_ELEM(I,i,j)*iCosTilt-mu0)*iadjustedStddev;
            break;
        }
    }
    else
    {
コード例 #6
0
void busca()
{
    static float f[22][22];
    float pi = 3.141592653;
    short in1, mu5, i, mu3, ind, ind1, indice, iflag, j, ix=0, iy=0, k;
    float h, th, costh, sinth, fi, anc, xk0, yk0, hpi, x, y, z, xx, yy;
    float b, g, d1, e1, ext;
    int count = 0;

    suaviza();
    in = XMIPP_MIN(in, 10);
    mu1 = mu - 1;
    m = 2 * mu;
    mu4 = mu * ncic;
    mt = 2 * m;
    ntot = mt * ncic;
    ntot4 = ntot + mu4 + ncic;
    zzz0 = ntot;
    ncic2 = 2 * ncic;
    in1 = in + 1;
    h = 2. * pi / ntot;
    idz = 2 - ntot;
    th = ncic * h;
    costh = cos(th);
    sinth = sin(th);
    b = 2. / (th * th) * (1. + costh * costh - sin(2. * th) / th);
    g = 4. / (th * th) * (sinth / th - costh);
    d1 = 2. * th / 45.;
    e1 = d1 * sinth * 2.;
    d1 *= sin(2. * th);
    mu5 = mu4 - 1;
    for (i = 1; i <= mu5; i++)
    {
        fi = i * h;
        coseno[i] = sin(fi);
    }
    coseno[mu4] = 1.;
    mu3 = 2 * mu4;
    for (i = 1; i <= mu5; i++)
    {
        coseno[mu3-i] = coseno[i];
        coseno[mu3+i] = -coseno[i];
        coseno[ntot-i] = -coseno[i];
        coseno[ntot+i] = coseno[i];
    }
    coseno[mu3] = 0.;
    coseno[mu3+mu4] = -1.;
    coseno[ntot] = 0.;
    coseno[ntot+mu4] = 1.;
    ind = 2 * in + 1;
    ind1 = ind - 1;
    indice = 0;
    iflag = 0;
e9:
    if (indice >= ni)
        goto e10;
    if (iflag == 2)
        goto e22;
    anc = (int)(3. + in * del);
    xk0 = xc0;
    yk0 = yc0;
    rh = XMIPP_MIN(rh, r2);
    rh = XMIPP_MIN(rh, xk0 - anc - 1.);
    rh = XMIPP_MIN(rh, yk0 - anc - 1.);
    rh = XMIPP_MIN(rh, largo - xk0 - anc);
    rh = XMIPP_MIN(rh, lancho - yk0 - anc);
    ir = (int)((rh - r1) / r3 + 1);
    hpi = h / 2. / pi / ir;
    cxp1 = 2. * b * e1 * hpi;
    cxp2 = -2. * g * d1 * hpi;
    cxp3 = 2. * (g * e1 - b * d1) * hpi;
    cxm1 = (b * b + e1 * e1) * hpi;
    cxm2 = (g * g + d1 * d1) * hpi;
    cxm3 = 2. * (b * g - d1 * e1) * hpi;
    /*    if(iflag == 1) goto 21            */
    if (iflag == 2)
        goto e22;
    x = xc0 - in * del;
    for (i = 1; i <= ind; i++) /* do 5 */
    { y = yc0 - in * del;
        for (j = 1; j <= ind; j++) /*do 4 */
        {   ergrot(x, y, &z);
            /*     printf ("%10.3f%10.3f%10.5f%10.3f%10.3f AA\n", x,y,z,del,rh);*/
            printf(".");
            fflush(stdout);
            z = 100. + indmul * z;
            f[i][j] = z;
            y += del;
        }
        x += del;
    }
    // Introduced by Sjors dd 28.9.2004 to avoid infinite loops
    count++;
    if (count > 1000)
        goto s1;
e23:
    ext = -1000000.;
    for (i = 1; i <= ind; i++) /* do 7 */
        for (j = 1; j <= ind; j++) /* do 7 */
            {   if (f[i][j] > ext)
            {
                ix = i;
                iy = j;
                ext = f[i][j];
            }
        }
    xc0 = xc0 + (ix - in - 1) * del;
    yc0 = yc0 + (iy - in - 1) * del;
    if (ix == 1 || ix == ind || iy == 1 || iy == ind)
        goto e8;
    del /= in;
    iflag = 2;
    indice++;
    goto e9;
e8:
    iflag = 1;
    goto e9;
e22:
    f[1][1] = f[ix-1][iy-1];
    f[ind][1] = f[ix+1][iy-1];
    f[1][ind] = f[ix-1][iy+1];
    f[ind][ind] = f[ix+1][iy+1];
    f[1][in1] = f[ix-1][iy];
    f[in1][1] = f[ix][iy-1];
    f[ind][in1] = f[ix+1][iy];
    f[in1][ind] = f[ix][iy+1];
    f[in1][in1] = f[ix][iy];
    x = xc0 - (in - 1) * del;
    for (i = 2; i < ind1; i++) /* do 11 */
    { y = yc0 - (in - 1) * del;
        for (j = 2;j <= ind1; j++) /* do 12 */
            {   if (i == in1 && j == in1)
                goto e13;
            ergrot(x, y, &z);
            /*     printf ("%10.3f%10.3f%10.5f%10.3f BB \n", x,y,z,del);*/
            printf(".");
            fflush(stdout);
            z = 100. + indmul * z;
            f[i][j] = z;
e13:
            y += del;
        }
        x += del;
    }
    x = xc0 - (in - 1) * del;
    y = yc0 - (in - 1) * del;

    for (k = 2; k <= ind1; k++) /* do 16 */
        { if (k == in1)
            goto e17;
        xx = xc0 - in * del;
        ergrot(xx, y, &z);
        /* printf ("%10.3f%10.3f%10.5f%10.3f CC \n", xx,y,z,del);*/
        printf(".");
        fflush(stdout);
        z = 100. + indmul * z;
        f[1][k] = z;
        yy = yc0 - in * del;
        ergrot(x, yy, &z);
        /* printf ("%10.3f%10.3f%10.5f%10.3f DD \n", xx,y,z,del);*/
        printf(".");
        fflush(stdout);
        z = 100. + indmul * z;
        f[k][1] = z;
        xx = xc0 + in * del;
        ergrot(xx, y, &z);
        /* printf ("%10.3f%10.3f%10.5f%10.3f EE \n", xx,y,z,del);*/
        printf(".");
        fflush(stdout);
        z = 100. + indmul * z;
        f[ind][k] = z;
        yy = yc0 + in * del;
        ergrot(x, yy, &z);
        /* printf ("%10.3f%10.3f%10.5f%10.3f FF\n", x,yy,z,del);*/
        printf(".");
        fflush(stdout);
        z = 100. + indmul * z;
        f[k][ind] = z;
e17:
        x += del;
        y += del;
    }
    goto e23;
e10:
    std::cout << "\nOptimal center coordinates: x= " << yc0-1 << " ,y= " << xc0-1 << " " << std::endl;
    return;
s1:
    yc0=xc0=-1;
    printf("\nNot-converged\n");
    return;
}
コード例 #7
0
ファイル: projector.cpp プロジェクト: dtegunov/vlion
void Projector::rotate3D(MultidimArray<Complex > &f3d, Matrix2D<DOUBLE> &A, bool inv)
{
	DOUBLE fx, fy, fz, xp, yp, zp;
	int x0, x1, y0, y1, z0, z1, y, z, y2, z2, r2;
	bool is_neg_x;
	Complex d000, d010, d100, d110, d001, d011, d101, d111, dx00, dx10, dxy0, dx01, dx11, dxy1;
	Matrix2D<DOUBLE> Ainv;

    // f3d should already be in the right size (ori_size,orihalfdim)
    // AND the points outside max_r should already be zero...
    // f3d.initZeros();
	// Use the inverse matrix
    if (inv)
    	Ainv = A;
    else
    	Ainv = A.transpose();

    // The f3d image may be smaller than r_max, in that case also make sure not to fill the corners!
    int my_r_max = XMIPP_MIN(r_max, XSIZE(f3d) - 1);

    // Go from the 3D rotated coordinates to the original map coordinates
    Ainv *= (DOUBLE)padding_factor;  // take scaling into account directly
    int max_r2 = my_r_max * my_r_max;
    int min_r2_nn = r_min_nn * r_min_nn;
#ifdef DEBUG
    std::cerr << " XSIZE(f3d)= "<< XSIZE(f3d) << std::endl;
    std::cerr << " YSIZE(f3d)= "<< YSIZE(f3d) << std::endl;
    std::cerr << " XSIZE(data)= "<< XSIZE(data) << std::endl;
    std::cerr << " YSIZE(data)= "<< YSIZE(data) << std::endl;
    std::cerr << " STARTINGX(data)= "<< STARTINGX(data) << std::endl;
    std::cerr << " STARTINGY(data)= "<< STARTINGY(data) << std::endl;
    std::cerr << " STARTINGZ(data)= "<< STARTINGZ(data) << std::endl;
    std::cerr << " max_r= "<< r_max << std::endl;
    std::cerr << " Ainv= " << Ainv << std::endl;
#endif
	for (int k=0; k < ZSIZE(f3d); k++)
	{
		// Don't search beyond square with side max_r
		if (k <= my_r_max)
		{
			z = k;
		}
		else if (k >= ZSIZE(f3d) - my_r_max)
		{
			z = k - ZSIZE(f3d);
		}
		else
			continue;
		z2 = z * z;

		for (int i=0; i < YSIZE(f3d); i++)
		{
			// Don't search beyond square with side max_r
			if (i <= my_r_max)
			{
				y = i;
			}
			else if (i >= YSIZE(f3d) - my_r_max)
			{
				y = i - YSIZE(f3d);
			}
			else
				continue;
			y2 = y * y;

			for (int x=0; x <= my_r_max; x++)
			{
				// Only include points with radius < max_r (exclude points outside circle in square)
				r2 = x * x + y2 + z2;
				if (r2 > max_r2)
					continue;

				// Get logical coordinates in the 3D map
				xp = Ainv(0,0) * x + Ainv(0,1) * y + Ainv(0,2) * z;
				yp = Ainv(1,0) * x + Ainv(1,1) * y + Ainv(1,2) * z;
				zp = Ainv(2,0) * x + Ainv(2,1) * y + Ainv(2,2) * z;

				if (interpolator == TRILINEAR || r2 < min_r2_nn)
				{
					// Only asymmetric half is stored
					if (xp < 0)
					{
						// Get complex conjugated hermitian symmetry pair
						xp = -xp;
						yp = -yp;
						zp = -zp;
						is_neg_x = true;
					}
					else
					{
						is_neg_x = false;
					}

					// Trilinear interpolation (with physical coords)
					// Subtract STARTINGY to accelerate access to data (STARTINGX=0)
					// In that way use DIRECT_A3D_ELEM, rather than A3D_ELEM
					x0 = FLOOR(xp);
					fx = xp - x0;
					x1 = x0 + 1;

					y0 = FLOOR(yp);
					fy = yp - y0;
					y0 -=  STARTINGY(data);
					y1 = y0 + 1;

					z0 = FLOOR(zp);
					fz = zp - z0;
					z0 -=  STARTINGZ(data);
					z1 = z0 + 1;

					// Matrix access can be accelerated through pre-calculation of z0*xydim etc.
					d000 = DIRECT_A3D_ELEM(data, z0, y0, x0);
					d001 = DIRECT_A3D_ELEM(data, z0, y0, x1);
					d010 = DIRECT_A3D_ELEM(data, z0, y1, x0);
					d011 = DIRECT_A3D_ELEM(data, z0, y1, x1);
					d100 = DIRECT_A3D_ELEM(data, z1, y0, x0);
					d101 = DIRECT_A3D_ELEM(data, z1, y0, x1);
					d110 = DIRECT_A3D_ELEM(data, z1, y1, x0);
					d111 = DIRECT_A3D_ELEM(data, z1, y1, x1);

					// Set the interpolated value in the 2D output array
					// interpolate in x
#ifndef FLOAT_PRECISION
                    __m256d __fx = _mm256_set1_pd(fx);
                    __m256d __interpx1 = LIN_INTERP_AVX(_mm256_setr_pd(d000.real, d000.imag, d100.real, d100.imag),
                                                        _mm256_setr_pd(d001.real, d001.imag, d101.real, d101.imag),
                                                        __fx);
                    __m256d __interpx2 = LIN_INTERP_AVX(_mm256_setr_pd(d010.real, d010.imag, d110.real, d110.imag),
                                                        _mm256_setr_pd(d011.real, d011.imag, d111.real, d111.imag),
                                                        __fx);

                    // interpolate in y
                    __m256d __fy = _mm256_set1_pd(fy);
                    __m256d __interpy = LIN_INTERP_AVX(__interpx1, __interpx2, __fy);
#else
                    __m128 __fx = _mm_set1_ps(fx);
                    __m128 __interpx1 = LIN_INTERP_AVX(_mm_setr_ps(d000.real, d000.imag, d100.real, d100.imag),
                                                       _mm_setr_ps(d001.real, d001.imag, d101.real, d101.imag),
                                                       __fx);
                    __m128 __interpx2 = LIN_INTERP_AVX(_mm_setr_ps(d010.real, d010.imag, d110.real, d110.imag),
                                                       _mm_setr_ps(d011.real, d011.imag, d111.real, d111.imag),
                                                       __fx);

                    // interpolate in y
                    __m128 __fy = _mm_set1_ps(fy);
                    __m128 __interpy = LIN_INTERP_AVX(__interpx1, __interpx2, __fy);
#endif

                    Complex* interpy = (Complex*)&__interpy;

					//interpolate in z
					DIRECT_A3D_ELEM(f3d, k, i, x) = LIN_INTERP(fz, interpy[0], interpy[1]);

					// Take complex conjugated for half with negative x
					if (is_neg_x)
						DIRECT_A3D_ELEM(f3d, k, i, x) = conj(DIRECT_A3D_ELEM(f3d, k, i, x));

				} // endif TRILINEAR
				else if (interpolator == NEAREST_NEIGHBOUR )
				{
					x0 = ROUND(xp);
					y0 = ROUND(yp);
					z0 = ROUND(zp);

					if (x0 < 0)
						DIRECT_A3D_ELEM(f3d, k, i, x) = conj(A3D_ELEM(data, -z0, -y0, -x0));
					else
						DIRECT_A3D_ELEM(f3d, k, i, x) = A3D_ELEM(data, z0, y0, x0);

				} // endif NEAREST_NEIGHBOUR
				else
					REPORT_ERROR("Unrecognized interpolator in Projector::project");
			} // endif x-loop
		} // endif y-loop
	} // endif z-loop
}