Beispiel #1
0
void 
project(
    float *obj, int ox, int oy, int oz, 
    float *data, int dx, int dy, int dz, float *center, float *theta,
    int istart, int iend)
{

    float *gridx = (float *)malloc((oy+1)*sizeof(float));
    float *gridy = (float *)malloc((oz+1)*sizeof(float));
    float *coordx = (float *)malloc((oz+1)*sizeof(float));
    float *coordy = (float *)malloc((oy+1)*sizeof(float));
    float *ax = (float *)malloc((oy+oz)*sizeof(float));
    float *ay = (float *)malloc((oy+oz)*sizeof(float));
    float *bx = (float *)malloc((oy+oz)*sizeof(float));
    float *by = (float *)malloc((oy+oz)*sizeof(float));
    float *coorx = (float *)malloc((oy+oz)*sizeof(float));
    float *coory = (float *)malloc((oy+oz)*sizeof(float));
    float *dist = (float *)malloc((oy+oz)*sizeof(float));
    int *indi = (int *)malloc((oy+oz)*sizeof(int));

    assert(coordx != NULL && coordy != NULL &&
        ax != NULL && ay != NULL && by != NULL && bx != NULL &&
        coorx != NULL && coory != NULL && dist != NULL && indi != NULL);

    int s, p, d;
    int quadrant;
    float theta_p, sin_p, cos_p;
    float mov, xi, yi;
    int asize, bsize, csize;

    preprocessing(oy, oz, dz, center[0], 
        &mov, gridx, gridy); // Outputs: mov, gridx, gridy

    // For each projection angle
    for (p=istart; p<iend; p++) 
    {
        // Calculate the sin and cos values 
        // of the projection angle and find
        // at which quadrant on the cartesian grid.
        theta_p = fmod(theta[p], 2*M_PI);
        quadrant = calc_quadrant(theta_p);
        sin_p = sinf(theta_p);
        cos_p = cosf(theta_p);

        for (d=0; d<dz; d++) 
        {
            // Calculate coordinates
            xi = -oy-oz;
            yi = (1-dz)/2.0+d+mov;
            calc_coords(
                oy, oz, xi, yi, sin_p, cos_p, gridx, gridy, 
                coordx, coordy);

            // Merge the (coordx, gridy) and (gridx, coordy)
            trim_coords(
                oy, oz, coordx, coordy, gridx, gridy, 
                &asize, ax, ay, &bsize, bx, by);

            // Sort the array of intersection points (ax, ay) and
            // (bx, by). The new sorted intersection points are 
            // stored in (coorx, coory). Total number of points 
            // are csize.
            sort_intersections(
                quadrant, asize, ax, ay, bsize, bx, by, 
                &csize, coorx, coory);

            // Calculate the distances (dist) between the 
            // intersection points (coorx, coory). Find the 
            // indices of the pixels on the object grid.
            calc_dist(
                oy, oz, csize, coorx, coory, 
                indi, dist);

            // For each slice
            for (s=0; s<dy; s++) 
            {
                // Calculate simdata 
                calc_simdata(p, s, d, oy, oz, dy, dz,
                    csize, indi, dist, obj,
                    data); // Output: simulated data
            }
        }
    }

    free(gridx);
    free(gridy);
    free(coordx);
    free(coordy);
    free(ax);
    free(ay);
    free(bx);
    free(by);
    free(coorx);
    free(coory);
    free(dist);
    free(indi);
}
Beispiel #2
0
void
ospml_hybrid(const float* data, int dy, int dt, int dx, const float* center,
             const float* theta, float* recon, int ngridx, int ngridy, int num_iter,
             const float* reg_pars, int num_block, const float* ind_block)
{
    if(dy == 0 || dt == 0 || dx == 0)
        return;

    float* gridx  = (float*) malloc((ngridx + 1) * sizeof(float));
    float* gridy  = (float*) malloc((ngridy + 1) * sizeof(float));
    float* coordx = (float*) malloc((ngridy + 1) * sizeof(float));
    float* coordy = (float*) malloc((ngridx + 1) * sizeof(float));
    float* ax     = (float*) malloc((ngridx + ngridy) * sizeof(float));
    float* ay     = (float*) malloc((ngridx + ngridy) * sizeof(float));
    float* bx     = (float*) malloc((ngridx + ngridy) * sizeof(float));
    float* by     = (float*) malloc((ngridx + ngridy) * sizeof(float));
    float* coorx  = (float*) malloc((ngridx + ngridy) * sizeof(float));
    float* coory  = (float*) malloc((ngridx + ngridy) * sizeof(float));
    float* dist   = (float*) malloc((ngridx + ngridy) * sizeof(float));
    int*   indi   = (int*) malloc((ngridx + ngridy) * sizeof(int));

    assert(coordx != NULL && coordy != NULL && ax != NULL && ay != NULL && by != NULL &&
           bx != NULL && coorx != NULL && coory != NULL && dist != NULL && indi != NULL);

    int    s, q, p, d, i, m, n, os;
    int    quadrant;
    float  theta_p, sin_p, cos_p;
    float  mov, xi, yi;
    int    asize, bsize, csize;
    float* simdata;
    float  upd;
    int    ind_data, ind_recon;
    float* sum_dist;
    float  sum_dist2;
    float *E, *F, *G;
    int    ind0, ind1, indg[8];
    float  totalwg, wg[8], mg[8], rg[8], gammag[8];
    int    subset_ind1, subset_ind2;

    for(i = 0; i < num_iter; i++)
    {
        simdata = (float*) calloc((dt * dy * dx), sizeof(float));

        // For each slice
        for(s = 0; s < dy; s++)
        {
            preprocessing(ngridx, ngridy, dx, center[s], &mov, gridx,
                          gridy);  // Outputs: mov, gridx, gridy

            subset_ind1 = dt / num_block;
            subset_ind2 = subset_ind1;

            // For each ordered-subset num_subset
            for(os = 0; os < num_block + 1; os++)
            {
                if(os == num_block)
                {
                    subset_ind2 = dt % num_block;
                }

                sum_dist = (float*) calloc((ngridx * ngridy), sizeof(float));
                E        = (float*) calloc((ngridx * ngridy), sizeof(float));
                F        = (float*) calloc((ngridx * ngridy), sizeof(float));
                G        = (float*) calloc((ngridx * ngridy), sizeof(float));

                // For each projection angle
                for(q = 0; q < subset_ind2; q++)
                {
                    p = ind_block[q + os * subset_ind1];

                    // Calculate the sin and cos values
                    // of the projection angle and find
                    // at which quadrant on the cartesian grid.
                    theta_p  = fmodf(theta[p], 2.0f * (float) M_PI);
                    quadrant = calc_quadrant(theta_p);
                    sin_p    = sinf(theta_p);
                    cos_p    = cosf(theta_p);

                    // For each detector pixel
                    for(d = 0; d < dx; d++)
                    {
                        // Calculate coordinates
                        xi = -ngridx - ngridy;
                        yi = 0.5f * (1 - dx) + d + mov;
                        calc_coords(ngridx, ngridy, xi, yi, sin_p, cos_p, gridx, gridy,
                                    coordx, coordy);

                        // Merge the (coordx, gridy) and (gridx, coordy)
                        trim_coords(ngridx, ngridy, coordx, coordy, gridx, gridy, &asize,
                                    ax, ay, &bsize, bx, by);

                        // Sort the array of intersection points (ax, ay) and
                        // (bx, by). The new sorted intersection points are
                        // stored in (coorx, coory). Total number of points
                        // are csize.
                        sort_intersections(quadrant, asize, ax, ay, bsize, bx, by, &csize,
                                           coorx, coory);

                        // Calculate the distances (dist) between the
                        // intersection points (coorx, coory). Find the
                        // indices of the pixels on the reconstruction grid.
                        calc_dist(ngridx, ngridy, csize, coorx, coory, indi, dist);

                        // Calculate simdata
                        calc_simdata(s, p, d, ngridx, ngridy, dt, dx, csize, indi, dist,
                                     recon,
                                     simdata);  // Output: simdata

                        // Calculate dist*dist
                        sum_dist2 = 0.0f;
                        for(n = 0; n < csize - 1; n++)
                        {
                            sum_dist2 += dist[n] * dist[n];
                            sum_dist[indi[n]] += dist[n];
                        }

                        // Update
                        if(sum_dist2 != 0.0f)
                        {
                            ind_data  = d + p * dx + s * dt * dx;
                            ind_recon = s * ngridx * ngridy;
                            upd       = data[ind_data] / simdata[ind_data];
                            for(n = 0; n < csize - 1; n++)
                            {
                                E[indi[n]] -= recon[indi[n] + ind_recon] * upd * dist[n];
                            }
                        }
                    }
                }

                // Weights for inner neighborhoods.
                totalwg = 4 + 4 / sqrt(2);
                wg[0]   = 1 / totalwg;
                wg[1]   = 1 / totalwg;
                wg[2]   = 1 / totalwg;
                wg[3]   = 1 / totalwg;
                wg[4]   = 1 / sqrt(2) / totalwg;
                wg[5]   = 1 / sqrt(2) / totalwg;
                wg[6]   = 1 / sqrt(2) / totalwg;
                wg[7]   = 1 / sqrt(2) / totalwg;

                // (inner region)
                for(n = 1; n < ngridx - 1; n++)
                {
                    for(m = 1; m < ngridy - 1; m++)
                    {
                        ind0 = m + n * ngridy;
                        ind1 = ind0 + s * ngridx * ngridy;

                        indg[0] = ind1 + 1;
                        indg[1] = ind1 - 1;
                        indg[2] = ind1 + ngridy;
                        indg[3] = ind1 - ngridy;
                        indg[4] = ind1 + ngridy + 1;
                        indg[5] = ind1 + ngridy - 1;
                        indg[6] = ind1 - ngridy + 1;
                        indg[7] = ind1 - ngridy - 1;

                        for(q = 0; q < 8; q++)
                        {
                            mg[q]     = recon[ind1] + recon[indg[q]];
                            rg[q]     = recon[ind1] - recon[indg[q]];
                            gammag[q] = 1 / (1 + fabs(rg[q] / reg_pars[1]));
                            F[ind0] += 2 * reg_pars[0] * wg[q] * gammag[q];
                            G[ind0] -= 2 * reg_pars[0] * wg[q] * gammag[q] * mg[q];
                        }
                    }
                }

                // Weights for edges.
                totalwg = 3 + 2 / sqrt(2);
                wg[0]   = 1 / totalwg;
                wg[1]   = 1 / totalwg;
                wg[2]   = 1 / totalwg;
                wg[3]   = 1 / sqrt(2) / totalwg;
                wg[4]   = 1 / sqrt(2) / totalwg;

                // (top)
                for(m = 1; m < ngridy - 1; m++)
                {
                    ind0 = m;
                    ind1 = ind0 + s * ngridx * ngridy;

                    indg[0] = ind1 + 1;
                    indg[1] = ind1 - 1;
                    indg[2] = ind1 + ngridy;
                    indg[3] = ind1 + ngridy + 1;
                    indg[4] = ind1 + ngridy - 1;

                    for(q = 0; q < 5; q++)
                    {
                        mg[q]     = recon[ind1] + recon[indg[q]];
                        rg[q]     = recon[ind1] - recon[indg[q]];
                        gammag[q] = 1 / (1 + fabs(rg[q] / reg_pars[1]));
                        F[ind0] += 2 * reg_pars[0] * wg[q] * gammag[q];
                        G[ind0] -= 2 * reg_pars[0] * wg[q] * gammag[q] * mg[q];
                    }
                }

                // (bottom)
                for(m = 1; m < ngridy - 1; m++)
                {
                    ind0 = m + (ngridx - 1) * ngridy;
                    ind1 = ind0 + s * ngridx * ngridy;

                    indg[0] = ind1 + 1;
                    indg[1] = ind1 - 1;
                    indg[2] = ind1 - ngridy;
                    indg[3] = ind1 - ngridy + 1;
                    indg[4] = ind1 - ngridy - 1;

                    for(q = 0; q < 5; q++)
                    {
                        mg[q]     = recon[ind1] + recon[indg[q]];
                        rg[q]     = recon[ind1] - recon[indg[q]];
                        gammag[q] = 1 / (1 + fabs(rg[q] / reg_pars[1]));
                        F[ind0] += 2 * reg_pars[0] * wg[q] * gammag[q];
                        G[ind0] -= 2 * reg_pars[0] * wg[q] * gammag[q] * mg[q];
                    }
                }

                // (left)
                for(n = 1; n < ngridx - 1; n++)
                {
                    ind0 = n * ngridy;
                    ind1 = ind0 + s * ngridx * ngridy;

                    indg[0] = ind1 + 1;
                    indg[1] = ind1 + ngridy;
                    indg[2] = ind1 - ngridy;
                    indg[3] = ind1 + ngridy + 1;
                    indg[4] = ind1 - ngridy + 1;

                    for(q = 0; q < 5; q++)
                    {
                        mg[q]     = recon[ind1] + recon[indg[q]];
                        rg[q]     = recon[ind1] - recon[indg[q]];
                        gammag[q] = 1 / (1 + fabs(rg[q] / reg_pars[1]));
                        F[ind0] += 2 * reg_pars[0] * wg[q] * gammag[q];
                        G[ind0] -= 2 * reg_pars[0] * wg[q] * gammag[q] * mg[q];
                    }
                }

                // (right)
                for(n = 1; n < ngridx - 1; n++)
                {
                    ind0 = (ngridy - 1) + n * ngridy;
                    ind1 = ind0 + s * ngridx * ngridy;

                    indg[0] = ind1 - 1;
                    indg[1] = ind1 + ngridy;
                    indg[2] = ind1 - ngridy;
                    indg[3] = ind1 + ngridy - 1;
                    indg[4] = ind1 - ngridy - 1;

                    for(q = 0; q < 5; q++)
                    {
                        mg[q]     = recon[ind1] + recon[indg[q]];
                        rg[q]     = recon[ind1] - recon[indg[q]];
                        gammag[q] = 1 / (1 + fabs(rg[q] / reg_pars[1]));
                        F[ind0] += 2 * reg_pars[0] * wg[q] * gammag[q];
                        G[ind0] -= 2 * reg_pars[0] * wg[q] * gammag[q] * mg[q];
                    }
                }

                // Weights for corners.
                totalwg = 2 + 1 / sqrt(2);
                wg[0]   = 1 / totalwg;
                wg[1]   = 1 / totalwg;
                wg[2]   = 1 / sqrt(2) / totalwg;

                // (top-left)
                ind0 = 0;
                ind1 = ind0 + s * ngridx * ngridy;

                indg[0] = ind1 + 1;
                indg[1] = ind1 + ngridy;
                indg[2] = ind1 + ngridy + 1;

                for(q = 0; q < 3; q++)
                {
                    mg[q]     = recon[ind1] + recon[indg[q]];
                    rg[q]     = recon[ind1] - recon[indg[q]];
                    gammag[q] = 1 / (1 + fabs(rg[q] / reg_pars[1]));
                    F[ind0] += 2 * reg_pars[0] * wg[q] * gammag[q];
                    G[ind0] -= 2 * reg_pars[0] * wg[q] * gammag[q] * mg[q];
                }

                // (top-right)
                ind0 = (ngridy - 1);
                ind1 = ind0 + s * ngridx * ngridy;

                indg[0] = ind1 - 1;
                indg[1] = ind1 + ngridy;
                indg[2] = ind1 + ngridy - 1;

                for(q = 0; q < 3; q++)
                {
                    mg[q]     = recon[ind1] + recon[indg[q]];
                    rg[q]     = recon[ind1] - recon[indg[q]];
                    gammag[q] = 1 / (1 + fabs(rg[q] / reg_pars[1]));
                    F[ind0] += 2 * reg_pars[0] * wg[q] * gammag[q];
                    G[ind0] -= 2 * reg_pars[0] * wg[q] * gammag[q] * mg[q];
                }

                // (bottom-left)
                ind0 = (ngridx - 1) * ngridy;
                ind1 = ind0 + s * ngridx * ngridy;

                indg[0] = ind1 + 1;
                indg[1] = ind1 - ngridy;
                indg[2] = ind1 - ngridy + 1;

                for(q = 0; q < 3; q++)
                {
                    mg[q]     = recon[ind1] + recon[indg[q]];
                    rg[q]     = recon[ind1] - recon[indg[q]];
                    gammag[q] = 1 / (1 + fabs(rg[q] / reg_pars[1]));
                    F[ind0] += 2 * reg_pars[0] * wg[q] * gammag[q];
                    G[ind0] -= 2 * reg_pars[0] * wg[q] * gammag[q] * mg[q];
                }

                // (bottom-right)
                ind0 = (ngridy - 1) + (ngridx - 1) * ngridy;
                ind1 = ind0 + s * ngridx * ngridy;

                indg[0] = ind1 - 1;
                indg[1] = ind1 - ngridy;
                indg[2] = ind1 - ngridy - 1;

                for(q = 0; q < 3; q++)
                {
                    mg[q]     = recon[ind1] + recon[indg[q]];
                    rg[q]     = recon[ind1] - recon[indg[q]];
                    gammag[q] = 1 / (1 + fabs(rg[q] / reg_pars[1]));
                    F[ind0] += 2 * reg_pars[0] * wg[q] * gammag[q];
                    G[ind0] -= 2 * reg_pars[0] * wg[q] * gammag[q] * mg[q];
                }

                q = 0;
                for(n = 0; n < ngridx * ngridy; n++)
                {
                    G[q] += sum_dist[n];
                    q++;
                }

                for(n = 0; n < ngridx; n++)
                {
                    for(m = 0; m < ngridy; m++)
                    {
                        q = m + n * ngridy;
                        if(F[q] != 0.0)
                        {
                            ind0        = q + s * ngridx * ngridy;
                            recon[ind0] = (-G[q] + sqrt(G[q] * G[q] - 8 * E[q] * F[q])) /
                                          (4 * F[q]);
                        }
                    }
                }

                free(sum_dist);
                free(E);
                free(F);
                free(G);
            }
        }

        free(simdata);
    }

    free(gridx);
    free(gridy);
    free(coordx);
    free(coordy);
    free(ax);
    free(ay);
    free(bx);
    free(by);
    free(coorx);
    free(coory);
    free(dist);
    free(indi);
}
Beispiel #3
0
void 
bart(
    float *data, int dx, int dy, int dz, float *center, float *theta,
    float *recon, int ngridx, int ngridy, int num_iter, 
    int num_block, float *ind_block)
{
    float *gridx = (float *)malloc((ngridx+1)*sizeof(float));
    float *gridy = (float *)malloc((ngridy+1)*sizeof(float));
    float *coordx = (float *)malloc((ngridy+1)*sizeof(float));
    float *coordy = (float *)malloc((ngridx+1)*sizeof(float));
    float *ax = (float *)malloc((ngridx+ngridy)*sizeof(float));
    float *ay = (float *)malloc((ngridx+ngridy)*sizeof(float));
    float *bx = (float *)malloc((ngridx+ngridy)*sizeof(float));
    float *by = (float *)malloc((ngridx+ngridy)*sizeof(float));
    float *coorx = (float *)malloc((ngridx+ngridy)*sizeof(float));
    float *coory = (float *)malloc((ngridx+ngridy)*sizeof(float));
    float *dist = (float *)malloc((ngridx+ngridy)*sizeof(float));
    int *indi = (int *)malloc((ngridx+ngridy)*sizeof(int));

    assert(coordx != NULL && coordy != NULL &&
        ax != NULL && ay != NULL && by != NULL && bx != NULL &&
        coorx != NULL && coory != NULL && dist != NULL && indi != NULL);

    int s, q, p, d, i, m, n, os;
    int quadrant;
    float theta_p, sin_p, cos_p;
    float mov, xi, yi;
    int asize, bsize, csize;
    float *simdata;
    float upd;
    int ind_data, ind_recon;
    float *sum_dist;
    float sum_dist2;
    float *update;
    int subset_ind1, subset_ind2;

    for (i=0; i<num_iter; i++) 
    {
        simdata = (float *)calloc((dx*dy*dz), sizeof(float));

        // For each slice
        for (s=0; s<dy; s++) 
        {
            preprocessing(ngridx, ngridy, dz, center[s], 
                &mov, gridx, gridy); // Outputs: mov, gridx, gridy

            subset_ind1 = dx/num_block;
            subset_ind2 = subset_ind1;

            // For each ordered-subset num_subset
            for (os=0; os<num_block+1; os++) 
            {
                if (os == num_block) 
                {
                    subset_ind2 = dx%num_block;
                }

                sum_dist = (float *)calloc((ngridx*ngridy), sizeof(float));
                update = (float *)calloc((ngridx*ngridy), sizeof(float));
                
                // For each projection angle 
                for (q=0; q<subset_ind2; q++) 
                {
                    p = ind_block[q+os*subset_ind1];

                    // Calculate the sin and cos values 
                    // of the projection angle and find
                    // at which quadrant on the cartesian grid.
                    theta_p = fmod(theta[p], 2*M_PI);
                    quadrant = calc_quadrant(theta_p);
                    sin_p = sinf(theta_p);
                    cos_p = cosf(theta_p);

                    // For each detector pixel 
                    for (d=0; d<dz; d++) 
                    {
                        // Calculate coordinates
                        xi = -1e6;
                        yi = -(dz-1)/2.0+d+mov;
                        calc_coords(
                            ngridx, ngridy, xi, yi, sin_p, cos_p, gridx, gridy, 
                            coordx, coordy);

                        // Merge the (coordx, gridy) and (gridx, coordy)
                        trim_coords(
                            ngridx, ngridy, coordx, coordy, gridx, gridy, 
                            &asize, ax, ay, &bsize, bx, by);

                        // Sort the array of intersection points (ax, ay) and
                        // (bx, by). The new sorted intersection points are 
                        // stored in (coorx, coory). Total number of points 
                        // are csize.
                        sort_intersections(
                            quadrant, asize, ax, ay, bsize, bx, by, 
                            &csize, coorx, coory);

                        // Calculate the distances (dist) between the 
                        // intersection points (coorx, coory). Find the 
                        // indices of the pixels on the reconstruction grid.
                        calc_dist(
                            ngridx, ngridy, csize, coorx, coory, 
                            indi, dist);

                        // Calculate simdata 
                        calc_simdata(p, s, d, ngridx, ngridy, dy, dz,
                            csize, indi, dist, recon,
                            simdata); // Output: simdata


                        // Calculate dist*dist
                        sum_dist2 = 0.0;
                        for (n=0; n<csize-1; n++) 
                        {
                            sum_dist2 += dist[n]*dist[n];
                            sum_dist[indi[n]] += dist[n];
                        }

                        // Update
                        if (sum_dist2 != 0.0) 
                        {
                            ind_data = d+s*dz+p*dy*dz;
                            upd = (data[ind_data]-simdata[ind_data])/sum_dist2;
                            for (n=0; n<csize-1; n++) 
                            {
                                update[indi[n]] += upd*dist[n];
                            }
                        }
                    }
                }

                m = 0;
                for (n = 0; n < ngridx*ngridy; n++) {
                    if (sum_dist[n] != 0.0) {
                        ind_recon = s*ngridx*ngridy;
                        recon[m+ind_recon] += update[m]/sum_dist[n];
                    }
                    m++;
                }

                free(sum_dist);
                free(update);
            }
        }

        free(simdata);
    }

    free(gridx);
    free(gridy);
    free(coordx);
    free(coordy);
    free(ax);
    free(ay);
    free(bx);
    free(by);
    free(coorx);
    free(coory);
    free(dist);
    free(indi);
}
Beispiel #4
0
void 
fbp(
    float *data, int dx, int dy, int dz, float *center, float *theta,
    float *recon, int ngridx, int ngridy, char *fname, 
    int istart, int iend)
{
    float *gridx = (float *)malloc((ngridx+1)*sizeof(float));
    float *gridy = (float *)malloc((ngridy+1)*sizeof(float));
    float *coordx = (float *)malloc((ngridy+1)*sizeof(float));
    float *coordy = (float *)malloc((ngridx+1)*sizeof(float));
    float *ax = (float *)malloc((ngridx+ngridy)*sizeof(float));
    float *ay = (float *)malloc((ngridx+ngridy)*sizeof(float));
    float *bx = (float *)malloc((ngridx+ngridy)*sizeof(float));
    float *by = (float *)malloc((ngridx+ngridy)*sizeof(float));
    float *coorx = (float *)malloc((ngridx+ngridy)*sizeof(float));
    float *coory = (float *)malloc((ngridx+ngridy)*sizeof(float));
    float *dist = (float *)malloc((ngridx+ngridy)*sizeof(float));
    int *indi = (int *)malloc((ngridx+ngridy)*sizeof(int));

    assert(coordx != NULL && coordy != NULL &&
        ax != NULL && ay != NULL && by != NULL && bx != NULL &&
        coorx != NULL && coory != NULL && dist != NULL && indi != NULL);

    int s, p, d, n;
    int quadrant;
    float theta_p, sin_p, cos_p;
    float mov, xi, yi;
    int asize, bsize, csize;
    float* simdata;
    int ind_data, ind_recon;

    simdata = (float *)calloc((dx*dy*dz), sizeof(float));

    // For each slice
    for (s=istart; s<iend; s++)
    {
        preprocessing(ngridx, ngridy, dz, center[s], 
            &mov, gridx, gridy); // Outputs: mov, gridx, gridy
            
        // For each projection angle 
        for (p=0; p<dx; p++) 
        {
            // Calculate the sin and cos values 
            // of the projection angle and find
            // at which quadrant on the cartesian grid.
            theta_p = fmod(theta[p], 2*M_PI);
            quadrant = calc_quadrant(theta_p);
            sin_p = sinf(theta_p);
            cos_p = cosf(theta_p);

            // For each detector pixel 
            for (d=0; d<dz; d++) 
            {
                // Calculate coordinates
                xi = -ngridx-ngridy;
                yi = (1-dz)/2.0+d+mov;
                calc_coords(
                    ngridx, ngridy, xi, yi, sin_p, cos_p, gridx, gridy, 
                    coordx, coordy);

                // Merge the (coordx, gridy) and (gridx, coordy)
                trim_coords(
                    ngridx, ngridy, coordx, coordy, gridx, gridy, 
                    &asize, ax, ay, &bsize, bx, by);

                // Sort the array of intersection points (ax, ay) and
                // (bx, by). The new sorted intersection points are 
                // stored in (coorx, coory). Total number of points 
                // are csize.
                sort_intersections(
                    quadrant, asize, ax, ay, bsize, bx, by, 
                    &csize, coorx, coory);

                // Calculate the distances (dist) between the 
                // intersection points (coorx, coory). Find the 
                // indices of the pixels on the reconstruction grid.
                calc_dist(
                    ngridx, ngridy, csize, coorx, coory, 
                    indi, dist);

                // Calculate simdata 
                calc_simdata(p, s, d, ngridx, ngridy, dy, dz,
                    csize, indi, dist, recon,
                    simdata); // Output: simdata


                // Calculate dist*dist
                float sum_dist2 = 0.0;
                for (n=0; n<csize-1; n++) 
                {
                    sum_dist2 += dist[n]*dist[n];
                }

                // Update
                if (sum_dist2 != 0.0) 
                {
                    ind_recon = s*ngridx*ngridy;
                    ind_data = d+s*dz+p*dy*dz;
                    for (n=0; n<csize-1; n++) 
                    {
                        recon[indi[n]+ind_recon] += data[ind_data]*dist[n];
                    }
                }
            }
        }
    }

    free(simdata);
    free(gridx);
    free(gridy);
    free(coordx);
    free(coordy);
    free(ax);
    free(ay);
    free(bx);
    free(by);
    free(coorx);
    free(coory);
    free(dist);
    free(indi);
}
Beispiel #5
0
void fbp(const float *data, int dy, int dt, int dx, const float *center,
         const float *theta, float *recon, int ngridx, int ngridy,
         const char *fname, const float *filter_par) {

  int s, p, d, n;
  int quadrant;
  float theta_p, sin_p, cos_p;
  float mov, xi, yi;
  int asize, bsize, csize;
  int ind_data, ind_recon;

  float *gridx, *gridy, *coordx, *coordy, *ax, *ay, *bx, *by, *coorx, *coory,
      *dist;
  int *indi;

  gridx = (float *)malloc((size_t)(ngridx + 1) * sizeof(float));
  gridy = (float *)malloc((size_t)(ngridy + 1) * sizeof(float));
  coordx = (float *)malloc((size_t)(ngridy + 1) * sizeof(float));
  coordy = (float *)malloc((size_t)(ngridx + 1) * sizeof(float));
  ax = (float *)malloc((size_t)(ngridx + ngridy) * sizeof(float));
  ay = (float *)malloc((size_t)(ngridx + ngridy) * sizeof(float));
  bx = (float *)malloc((size_t)(ngridx + ngridy) * sizeof(float));
  by = (float *)malloc((size_t)(ngridx + ngridy) * sizeof(float));
  coorx = (float *)malloc((size_t)(ngridx + ngridy) * sizeof(float));
  coory = (float *)malloc((size_t)(ngridx + ngridy) * sizeof(float));
  dist = (float *)malloc((size_t)(ngridx + ngridy) * sizeof(float));
  indi = (int *)malloc((size_t)(ngridx + ngridy) * sizeof(int));

  /* unused arguments: */
  (void)fname;
  (void)filter_par;

  assert(coordx != NULL && coordy != NULL && ax != NULL && ay != NULL &&
         by != NULL && bx != NULL && coorx != NULL && coory != NULL &&
         dist != NULL && indi != NULL);

  /* For each slice */
  for (s = 0; s < dy; s++) {
    preprocessing(ngridx, ngridy, dx, center[s], &mov, gridx,
                  gridy); /* Outputs: mov, gridx, gridy */

    /* For each projection angle */
    for (p = 0; p < dt; p++) {
      /*
         Calculate the sin and cos values
         of the projection angle and find
         at which quadrant on the cartesian grid.
      */
      theta_p = (float)fmod(theta[p], 2 * M_PI);
      quadrant = calc_quadrant(theta_p);
      sin_p = sinf(theta_p);
      cos_p = cosf(theta_p);

      /* For each detector pixel */
      for (d = 0; d < dx; d++) {
        /* Calculate coordinates */
        xi = (float)(-ngridx - ngridy);
        yi = (float)(1 - dx) / 2.0f + (float)d + mov;
        calc_coords(ngridx, ngridy, xi, yi, sin_p, cos_p, gridx, gridy, coordx,
                    coordy);

        /* Merge the (coordx, gridy) and (gridx, coordy) */
        trim_coords(ngridx, ngridy, coordx, coordy, gridx, gridy, &asize, ax,
                    ay, &bsize, bx, by);

        /*
          Sort the array of intersection points (ax, ay) and
          (bx, by). The new sorted intersection points are
          stored in (coorx, coory). Total number of points
          are csize.
        */
        sort_intersections(quadrant, asize, ax, ay, bsize, bx, by, &csize,
                           coorx, coory);

        /*
          Calculate the distances (dist) between the
          intersection points (coorx, coory). Find the
          indices of the pixels on the reconstruction grid.
        */
        calc_dist(ngridx, ngridy, csize, coorx, coory, indi, dist);

        /* Update */
        ind_recon = s * ngridx * ngridy;
        ind_data = d + p * dx + s * dt * dx;
        for (n = 0; n < csize - 1; n++) {
          recon[indi[n] + ind_recon] += data[ind_data] * dist[n];
        }
      }
    }
  }

  free(gridx);
  free(gridy);
  free(coordx);
  free(coordy);
  free(ax);
  free(ay);
  free(bx);
  free(by);
  free(coorx);
  free(coory);
  free(dist);
  free(indi);
}
Beispiel #6
0
void
art(const float* data, int dy, int dt, int dx, const float* center, const float* theta,
    float* recon, int ngridx, int ngridy, int num_iter)
{
    if(dy == 0 || dt == 0 || dx == 0)
        return;

    float* gridx   = (float*) malloc((ngridx + 1) * sizeof(float));
    float* gridy   = (float*) malloc((ngridy + 1) * sizeof(float));
    float* coordx  = (float*) malloc((ngridy + 1) * sizeof(float));
    float* coordy  = (float*) malloc((ngridx + 1) * sizeof(float));
    float* ax      = (float*) malloc((ngridx + ngridy) * sizeof(float));
    float* ay      = (float*) malloc((ngridx + ngridy) * sizeof(float));
    float* bx      = (float*) malloc((ngridx + ngridy) * sizeof(float));
    float* by      = (float*) malloc((ngridx + ngridy) * sizeof(float));
    float* coorx   = (float*) malloc((ngridx + ngridy) * sizeof(float));
    float* coory   = (float*) malloc((ngridx + ngridy) * sizeof(float));
    float* dist    = (float*) malloc((ngridx + ngridy) * sizeof(float));
    int*   indi    = (int*) malloc((ngridx + ngridy) * sizeof(int));
    float* simdata = (float*) malloc((dy * dt * dx) * sizeof(float));

    assert(coordx != NULL && coordy != NULL && ax != NULL && ay != NULL && by != NULL &&
           bx != NULL && coorx != NULL && coory != NULL && dist != NULL && indi != NULL &&
           simdata != NULL);

    int   s, p, d, i, n;
    int   quadrant;
    float theta_p, sin_p, cos_p;
    float mov, xi, yi;
    int   asize, bsize, csize;
    float upd;
    int   ind_data, ind_recon;

    for(i = 0; i < num_iter; i++)
    {
        // initialize simdata to zero
        memset(simdata, 0, dy * dt * dx * sizeof(float));

        preprocessing(ngridx, ngridy, dx, center[0], &mov, gridx,
                      gridy);  // Outputs: mov, gridx, gridy

        // For each projection angle
        for(p = 0; p < dt; p++)
        {
            // Calculate the sin and cos values
            // of the projection angle and find
            // at which quadrant on the cartesian grid.
            theta_p  = fmodf(theta[p], 2.0f * (float) M_PI);
            quadrant = calc_quadrant(theta_p);
            sin_p    = sinf(theta_p);
            cos_p    = cosf(theta_p);

            // For each detector pixel
            for(d = 0; d < dx; d++)
            {
                // Calculate coordinates
                xi = -ngridx - ngridy;
                yi = 0.5f * (1 - dx) + d + mov;
                calc_coords(ngridx, ngridy, xi, yi, sin_p, cos_p, gridx, gridy, coordx,
                            coordy);

                // Merge the (coordx, gridy) and (gridx, coordy)
                trim_coords(ngridx, ngridy, coordx, coordy, gridx, gridy, &asize, ax, ay,
                            &bsize, bx, by);

                // Sort the array of intersection points (ax, ay) and
                // (bx, by). The new sorted intersection points are
                // stored in (coorx, coory). Total number of points
                // are csize.
                sort_intersections(quadrant, asize, ax, ay, bsize, bx, by, &csize, coorx,
                                   coory);

                // Calculate the distances (dist) between the
                // intersection points (coorx, coory). Find the
                // indices of the pixels on the reconstruction grid.
                calc_dist(ngridx, ngridy, csize, coorx, coory, indi, dist);

                // Calculate dist*dist
                float sum_dist2 = 0.0f;
                for(n = 0; n < csize - 1; n++)
                {
                    sum_dist2 += dist[n] * dist[n];
                }

                if(sum_dist2 != 0.0f)
                {
                    // For each slice
                    for(s = 0; s < dy; s++)
                    {
                        // Calculate simdata
                        calc_simdata(s, p, d, ngridx, ngridy, dt, dx, csize, indi, dist,
                                     recon,
                                     simdata);  // Output: simdata

                        // Update
                        ind_data  = d + p * dx + s * dt * dx;
                        ind_recon = s * ngridx * ngridy;
                        upd       = (data[ind_data] - simdata[ind_data]) / sum_dist2;
                        for(n = 0; n < csize - 1; n++)
                        {
                            recon[indi[n] + ind_recon] += upd * dist[n];
                        }
                    }
                }
            }
        }
    }
    free(gridx);
    free(gridy);
    free(coordx);
    free(coordy);
    free(ax);
    free(ay);
    free(bx);
    free(by);
    free(coorx);
    free(coory);
    free(dist);
    free(indi);
    free(simdata);
}