39 #define M_PI 3.14159265358979323846f
42#ifdef EMAN2_USING_CUDA
50const string GaussFFTProjector::NAME =
"gauss_fft";
51const string FourierGriddingProjector::NAME =
"fourier_gridding";
52const string PawelProjector::NAME =
"pawel";
53const string StandardProjector::NAME =
"standard";
54const string MaxValProjector::NAME =
"maxval";
55const string ChaoProjector::NAME =
"chao";
59 force_add<GaussFFTProjector>();
60 force_add<PawelProjector>();
61 force_add<StandardProjector>();
62 force_add<MaxValProjector>();
63 force_add<FourierGriddingProjector>();
64 force_add<ChaoProjector>();
72 if ( t3d == NULL )
throw NullPointerException(
"The transform object (required for projection), was not specified");
76 if (!image->is_complex()) {
77 image->process_inplace(
"xform.phaseorigin.tocorner");
79 f->process_inplace(
"xform.fourierorigin.tocenter");
80 image->process_inplace(
"xform.phaseorigin.tocenter");
83 int f_nx = f->get_xsize();
84 int f_ny = f->get_ysize();
85 int f_nz = f->get_zsize();
87 if (!f->is_complex() || f_nz != f_ny || f_nx != f_ny + 2) {
88 LOGERR(
"Cannot project this image");
95 tmp->set_size(f_nx, f_ny, 1);
96 tmp->set_complex(
true);
99 float *data = tmp->get_data();
105 int mode =
params[
"mode"];
106 float gauss_width = 1;
111 else if (mode == 3) {
114 else if (mode == 4) {
117 else if (mode == 6 || mode == 7) {
121 for (
int y = 0;
y < f_ny;
y++) {
122 for (
int x = 0;
x < f_nx / 2;
x++) {
123 int ii =
x * 2 +
y * f_nx;
124 if (hypot(
x,
y - f_ny / 2) >= f_ny / 2 - 1) {
129 Vec3f coord(
x,(
y - f_ny / 2),0);
130 Vec3f soln = r*coord;
152 if (yy < 0 || xx < 0 || zz < 0) {
158 if (
interp_ft_3d(mode, f, xx, yy, zz, data + ii, gauss_width)) {
171 int returnfft=
params[
"returnfft"];
178 ret->process_inplace(
"xform.fourierorigin.tocorner");
179 ret->process_inplace(
"xform",
Dict(
"tx", (
float)trans[0],
"ty", (
float)trans[1]));
186 tmp->process_inplace(
"xform.fourierorigin.tocorner");
188 ret->process_inplace(
"xform.phaseorigin.tocenter");
192 if (t3d->
get_mirror() ) ret->process_inplace(
"xform.flip",
Dict(
"axis",
"x"));
195 filter_d[
"gauss_width"] = gauss_width;
197 ret->process_inplace(
"math.gausskernelfix", filter_d);
206 ret->set_attr(
"xform.projection",t3d);
209 if(t3d) {
delete t3d; t3d=0;}
217 float z,
float *data,
float gw)
const
219 float *
rdata = image->get_data();
220 int nx = image->get_xsize();
221 int ny = image->get_ysize();
222 int nz = image->get_zsize();
225 int x0 = (int) floor(
x);
226 int y0 = (int) floor(
y);
227 int z0 = (int) floor(z);
231 for (
int ix=x0; ix<=x0+1; ix++){
232 for (
int iy=y0; iy<=y0+1; iy++){
233 for (
int iz=z0; iz<=z0+1; iz++){
234 float w=(1.0-fabs(ix-
x))*(1.0-fabs(iy-
y))*(1.0-fabs(iz-z));
235 d0 += w *
rdata[2*ix + iy * nx + iz * nx * ny];
236 d1 += w *
rdata[2*ix + iy * nx + iz * nx * ny + 1];
245 int x0 = 2 * (int) floor(
x + 0.5f);
246 int y0 = (int) floor(
y + 0.5f);
247 int z0 = (int) floor(z + 0.5f);
249 data[0] =
rdata[x0 + y0 * nx + z0 * nx * ny];
250 data[1] =
rdata[x0 + y0 * nx + z0 * nx * ny + 1];
253 else if (mode == 2) {
254 int x0 = (int) floor(
x);
255 int y0 = (int) floor(
y);
256 int z0 = (int) floor(z);
262 if (x0 <= nx/2- 2 && y0 <= ny - 1 && z0 <= nz - 1) {
263 int i = (int) (x0 * 2 + y0 * nx + z0 * nx * ny);
296 else if (mode == 3) {
297 int x0 = 2 * (int) floor(
x + .5);
298 int y0 = (int) floor(
y + .5);
299 int z0 = (int) floor(z + .5);
303 if (x0 < nx - 4 && y0 <= ny - 3 && z0 <= nz - 3 && y0 >= 2 && z0 >= 2) {
310 for (
int k = z0 - 1; k <= z0 + 1; k++) {
311 for (
int j = y0 - 1; j <= y0 + 1; j++) {
312 for (
int i = x0 - 2; i <= x0 + 2; i += 2) {
316 idx = i + j * 12 + (size_t)k * 12 * ny;
317 data[0] += supp[idx] * g;
318 data[1] += supp[idx + 1] * g;
326 for (
int k = z0 - 1; k <= z0 + 1; k++) {
327 for (
int j = y0 - 1; j <= y0 + 1; j++) {
328 for (
int i = x0 - 2; i <= x0 + 2; i += 2) {
332 idx = i + j * nx + (size_t)k * nx * ny;
333 data[0] +=
rdata[idx] * g;
334 data[1] +=
rdata[idx + 1] * g;
346 else if (mode == 4) {
347 int x0 = 2 * (int) floor(
x);
348 int y0 = (int) floor(
y);
349 int z0 = (int) floor(z);
353 if (x0 < nx - 4 && y0 <= ny - 3 && z0 <= nz - 3 && y0 >= 2 && z0 >= 2) {
360 for (
int k = z0 - 1; k <= z0 + 2; k++) {
361 for (
int j = y0 - 1; j <= y0 + 2; j++) {
362 for (
int i = x0 - 2; i <= x0 + 4; i += 2) {
366 idx = i + j * 12 + (size_t)k * 12 * ny;
367 data[0] += supp[idx] * g;
368 data[1] += supp[idx + 1] * g;
376 for (
int k = z0 - 1; k <= z0 + 2; k++) {
377 for (
int j = y0 - 1; j <= y0 + 2; j++) {
378 for (
int i = x0 - 2; i <= x0 + 4; i += 2) {
382 idx = i + j * nx + (size_t)k * nx * ny;
383 data[0] +=
rdata[idx] * g;
384 data[1] +=
rdata[idx + 1] * g;
395 else if (mode == 5) {
396 int x0 = 2 * (int) floor(
x + .5);
397 int y0 = (int) floor(
y + .5);
398 int z0 = (int) floor(z + .5);
403 if (x0 < nx - 4 && y0 <= ny - 3 && z0 <= nz - 3 && y0 >= 2 && z0 >= 2) {
404 int mx0 = -(int) floor((
x - x0 / 2) * 39.0 + .5) - 78;
405 int my0 = -(int) floor((
y - y0) * 39.0 + .5) - 78;
406 int mz0 = -(int) floor((z - z0) * 39.0 + .5) - 78;
418 for (
int k = z0 - 2; k <= z0 + 2; k++, mmz += 39) {
419 for (
int j = y0 - 2; j <= y0 + 2; j++, mmy += 39) {
420 for (
int i = x0 - 4; i <= x0 + 4; i += 2, mmx += 39) {
421 g = gimx[abs(mmx) + abs(mmy) * 100 + abs(mmz) * 10000];
423 idx = i + j * 12 + (size_t)k * 12 * ny;
424 data[0] += supp[idx] * g;
425 data[1] += supp[idx + 1] * g;
433 for (
int k = z0 - 2; k <= z0 + 2; k++, mmz += 39) {
434 for (
int j = y0 - 2; j <= y0 + 2; j++, mmy += 39) {
435 for (
int i = x0 - 4; i <= x0 + 4; i += 2, mmx += 39) {
436 ii = i + j * nx + (size_t)k * nx * ny;
437 g = gimx[abs(mmx) + abs(mmy) * 100 + abs(mmz) * 10000];
439 data[0] +=
rdata[ii] * g;
440 data[1] +=
rdata[ii + 1] * g;
452 else if (mode == 6) {
454 int x0 = 2 * (int) floor(
x + .5);
455 int y0 = (int) floor(
y + .5);
456 int z0 = (int) floor(z + .5);
460 if (x0 < nx - 4 && y0 <= ny - 3 && z0 <= nz - 3 && y0 >= 2 && z0 >= 2) {
467 for (
int k = z0 - 2; k <= z0 + 2; k++) {
468 for (
int j = y0 - 2; j <= y0 + 2; j++) {
469 for (
int i = x0 - 4; i <= x0 + 4; i += 2) {
473 idx = i + j * 12 + (size_t)k * 12 * ny;
474 data[0] += supp[idx] * g;
475 data[1] += supp[idx + 1] * g;
483 for (
int k = z0 - 2; k <= z0 + 2; k++) {
484 for (
int j = y0 - 2; j <= y0 + 2; j++) {
485 for (
int i = x0 - 4; i <= x0 + 4; i += 2) {
489 idx = i + j * nx + (size_t)k * nx * ny;
490 data[0] +=
rdata[idx] * g;
491 data[1] +=
rdata[idx + 1] * g;
505 else if (mode == 7) {
506 int x0 = 2 * (int) floor(
x + .5);
507 int y0 = (int) floor(
y + .5);
508 int z0 = (int) floor(z + .5);
512 if (x0 < nx - 4 && y0 <= ny - 3 && z0 <= nz - 3 && y0 >= 2 && z0 >= 2) {
518 for (
int k = z0 - 2; k <= z0 + 2; k++) {
519 for (
int j = y0 - 2; j <= y0 + 2; j++) {
520 for (
int i = x0 - 4; i <= x0 + 4; i += 2) {
524 idx = i + j * 12 + (size_t)k * 12 * ny;
525 data[0] += supp[idx] * g;
526 data[1] += supp[idx + 1] * g;
534 for (
int k = z0 - 2; k <= z0 + 2; k++) {
535 for (
int j = y0 - 2; j <= y0 + 2; j++) {
536 for (
int i = x0 - 4; i <= x0 + 4; i += 2) {
540 idx = i + j * nx + (size_t)k * nx * ny;
541 data[0] +=
rdata[idx] * g;
542 data[1] +=
rdata[idx + 1] * g;
560 int& nn,
IPCube* ipcube)
const {
561 const float r = float(ri)*float(ri);
562 const int ldpx = origin[0];
563 const int ldpy = origin[1];
564 const int ldpz = origin[2];
568 for (
int i1 = 0; i1 < nz; i1++) {
569 t = float(i1 - ldpz);
570 const float xx = t*t;
571 for (
int i2 = 0; i2 < ny; i2++) {
572 t = float(i2 - ldpy);
573 const float yy = t*t + xx;
575 for (
int i3 = 0; i3 < nx; i3++) {
576 t = float(i3 - ldpx);
577 const float rc = t*t + yy;
580 if (rc > r)
continue;
583 if (ipcube != NULL) {
584 ipcube[nn].
start = i3;
586 ipcube[nn].
loc[0] = i3 - ldpx;
587 ipcube[nn].
loc[1] = i2 - ldpy;
588 ipcube[nn].
loc[2] = i1 - ldpz;
593 if (ipcube != NULL) {
594 if (rc <= r) ipcube[nn].
end = i3;
604 if (!image)
return 0;
606 int nx = image->get_xsize();
607 int ny = image->get_ysize();
608 int nz = image->get_zsize();
612 LOGERR(
"The PawelProjector needs a volume!");
619 else {ri = dim/2 - 1;}
654 if (2*(ri+1)+1 > dim) {
656 ret->set_size(dim, dim, nangles);
661 Vec3i loc(-dimc,0,0);
662 Vec3i vorg(nx/2,ny/2,nz/2);
664 for (
int l = 0 ; l < dim; l++) {
666 for (
int k = 0 ; k < dim; k++) {
668 Vec3f vb = loc*(*rotation) + vorg;
669 for (
int j = 0; j < dim; j++) {
672 int iox = int(vb[0]);
673 if ((iox >= 0) && (iox < nx-1)) {
674 int ioy = int(vb[1]);
675 if ((ioy >= 0) && (ioy < ny-1)) {
676 int ioz = int(vb[2]);
677 if ((ioz >= 0) && (ioz < nz-1)) {
681 float dx = vb[0] - iox;
682 float dy = vb[1] - ioy;
683 float dz = vb[2] - ioz;
684 float a1 = (*image)(iox,ioy,ioz);
685 float a2 = (*image)(iox+1,ioy,ioz) - a1;
686 float a3 = (*image)(iox,ioy+1,ioz) - a1;
687 float a4 = (*image)(iox,ioy,ioz+1) - a1;
688 float a5 = -a2 -(*image)(iox,ioy+1,ioz)
689 + (*image)(iox+1,ioy+1,ioz);
690 float a61 = -(*image)(iox,ioy,ioz+1)
691 + (*image)(iox+1,ioy,ioz+1);
692 float a6 = -a2 + a61;
693 float a7 = -a3 - (*image)(iox,ioy,ioz+1)
694 + (*image)(iox,ioy+1,ioz+1);
695 float a8 = -a5 - a61 - (*image)(iox,ioy+1,ioz+1)
696 + (*image)(iox+1,ioy+1,ioz+1);
697 (*ret)(j,k,ia) += a1 + dz*(a4 + a6*dx
699 + a3*dy + dx*(a2 + a5*dy);
712 else {origin[0] = nx/2;}
714 else {origin[1] = ny/2;}
716 else {origin[2] = nz/2;}
723 prepcubes(nx, ny, nz, ri, origin, nn, ipcube);
725 ret->set_size(nx, ny, nangles);
728 for (
int i = 0 ; i <= nn; i++) {
729 int k = ipcube[i].
loc[1] + origin[1];
730 Vec3f vb = ipcube[i].
loc*(*rotation) + origin;
731 for (
int j = ipcube[i].start; j <= ipcube[i].
end; j++) {
732 int iox = int(vb[0]);
733 int ioy = int(vb[1]);
734 int ioz = int(vb[2]);
735 float dx = vb[0] - iox;
736 float dy = vb[1] - ioy;
737 float dz = vb[2] - ioz;
738 float a1 = (*image)(iox,ioy,ioz);
739 float a2 = (*image)(iox+1,ioy,ioz) - a1;
740 float a3 = (*image)(iox,ioy+1,ioz) - a1;
741 float a4 = (*image)(iox,ioy,ioz+1) - a1;
742 float a5 = -a2 -(*image)(iox,ioy+1,ioz)
743 + (*image)(iox+1,ioy+1,ioz);
744 float a61 = -(*image)(iox,ioy,ioz+1)
745 + (*image)(iox+1,ioy,ioz+1);
746 float a6 = -a2 + a61;
747 float a7 = -a3 - (*image)(iox,ioy,ioz+1)
748 + (*image)(iox,ioy+1,ioz+1);
749 float a8 = -a5 - a61 - (*image)(iox,ioy+1,ioz+1)
750 + (*image)(iox+1,ioy+1,ioz+1);
751 (*ret)(j,k,ia) += a1 + dz*(a4 + a6*dx
753 + a3*dy + dx*(a2 + a5*dy);
761 if(rotation) {
delete rotation; rotation=0;}
768 if ( t3d == NULL )
throw NullPointerException(
"The transform object containing the angles(required for projection), was not specified");
770 if ( image->get_ndim() == 3 )
773#ifdef EMAN2_USING_CUDA
774 if(EMData::usecuda == 1) {
775 if(!image->isrodataongpu()) image->copy_to_cudaro();
778 if ( t3d == NULL )
throw NullPointerException(
"The transform object containing the angles(required for projection), was not specified");
779 float * m =
new float[12];
781 image->bindcudaarrayA(
true);
784 e->set_size_cuda(image->get_xsize(), image->get_ysize(), 1);
787 image->unbindcudaarryA();
791 e->set_attr(
"xform.projection",t3d);
792 e->set_attr(
"apix_x",(
float)image->get_attr(
"apix_x"));
793 e->set_attr(
"apix_y",(
float)image->get_attr(
"apix_y"));
794 e->set_attr(
"apix_z",(
float)image->get_attr(
"apix_z"));
796 if(t3d) {
delete t3d; t3d=0;}
800 int nx = image->get_xsize();
801 int ny = image->get_ysize();
802 int nz = image->get_zsize();
809 proj->set_size(nx, ny, 1);
811 Vec3i offset(nx/2,ny/2,nz/2);
813 float *sdata = image->get_data();
814 float *ddata = proj->get_data();
815 for (
int k = -nz / 2; k < nz - nz / 2; k++) {
817 for (
int j = -ny / 2; j < ny - ny / 2; j++) {
819 for (
int i = -nx / 2; i < nx - nx / 2; i++,l++) {
822 Vec3f soln = r*coord;
842 size_t ii = (size_t) ((
size_t)
x + (size_t)
y * nx + (
size_t)z * xy);
844 if (x2 < 0 || y2 < 0 || z2 < 0 )
continue;
845 if (x2 > (nx-1) || y2 > (ny-1) || z2 > (nz-1) )
continue;
847 if (x2 < (nx - 1) && y2 < (ny - 1) && z2 < (nz - 1)) {
850 sdata[ii + nx + 1], sdata[ii + xy], sdata[ii + xy + 1], sdata[ii + xy + nx],
851 sdata[ii + xy + nx + 1], t, u, v);
853 else if ( x2 == (nx - 1) && y2 == (ny - 1) && z2 == (nz - 1) ) {
854 ddata[l] += sdata[ii];
856 else if ( x2 == (nx - 1) && y2 == (ny - 1) ) {
859 else if ( x2 == (nx - 1) && z2 == (nz - 1) ) {
862 else if ( y2 == (ny - 1) && z2 == (nz - 1) ) {
865 else if ( x2 == (nx - 1) ) {
868 else if ( y2 == (ny - 1) ) {
871 else if ( z2 == (nz - 1) ) {
878 proj->set_attr(
"xform.projection",t3d);
879 proj->set_attr(
"apix_x",(
float)image->get_attr(
"apix_x"));
880 proj->set_attr(
"apix_y",(
float)image->get_attr(
"apix_y"));
881 proj->set_attr(
"apix_z",(
float)image->get_attr(
"apix_z"));
883 if(t3d) {
delete t3d; t3d=0;}
886 else if ( image->get_ndim() == 2 ) {
890 int nx = image->get_xsize();
891 int ny = image->get_ysize();
894 proj->set_size(nx, 1, 1);
897 float *sdata = image->get_data();
898 float *ddata = proj->get_data();
900 Vec2f offset(nx/2,ny/2);
901 for (
int j = -ny / 2; j < ny - ny / 2; j++) {
903 for (
int i = -nx / 2; i < nx - nx / 2; i++,l++) {
906 Vec2f soln = r*coord;
915 int ii = (int) (
x +
y * nx);
919 if (x2 < 0 || y2 < 0 )
continue;
920 if (x2 > (nx-1) || y2 > (ny-1) )
continue;
922 if ( x2 < (nx - 1) && y2 < (ny - 1) ) {
925 else if (x2 == (nx-1) && y2 == (ny-1) ) {
926 ddata[l] += sdata[ii];
928 else if (x2 == (nx-1) ) {
931 else if (y2 == (ny-1) ) {
936 proj->set_attr(
"xform.projection",t3d);
938 if(t3d) {
delete t3d; t3d=0;}
947 if ( t3d == NULL )
throw NullPointerException(
"The transform object containing the angles(required for projection), was not specified");
949 if ( image->get_ndim() == 3 )
952 int nx = image->get_xsize();
953 int ny = image->get_ysize();
954 int nz = image->get_zsize();
961 proj->set_size(nx, ny, 1);
963 Vec3i offset(nx/2,ny/2,nz/2);
965 float *sdata = image->get_data();
966 float *ddata = proj->get_data();
967 for (
int k = -nz / 2; k < nz - nz / 2; k++) {
969 for (
int j = -ny / 2; j < ny - ny / 2; j++) {
971 for (
int i = -nx / 2; i < nx - nx / 2; i++,l++) {
974 Vec3f soln = r*coord;
994 size_t ii = (size_t) ((
size_t)
x + (size_t)
y * nx + (
size_t)z * xy);
996 if (x2 < 0 || y2 < 0 || z2 < 0 )
continue;
997 if (x2 > (nx-1) || y2 > (ny-1) || z2 > (nz-1) )
continue;
999 if (x2 < (nx - 1) && y2 < (ny - 1) && z2 < (nz - 1)) {
1002 sdata[ii + nx + 1], sdata[ii + xy], sdata[ii + xy + 1], sdata[ii + xy + nx],
1003 sdata[ii + xy + nx + 1], t, u, v));
1005 else if ( x2 == (nx - 1) && y2 == (ny - 1) && z2 == (nz - 1) ) {
1008 else if ( x2 == (nx - 1) && y2 == (ny - 1) ) {
1011 else if ( x2 == (nx - 1) && z2 == (nz - 1) ) {
1014 else if ( y2 == (ny - 1) && z2 == (nz - 1) ) {
1017 else if ( x2 == (nx - 1) ) {
1020 else if ( y2 == (ny - 1) ) {
1023 else if ( z2 == (nz - 1) ) {
1030 proj->set_attr(
"xform.projection",t3d);
1031 proj->set_attr(
"apix_x",(
float)image->get_attr(
"apix_x"));
1032 proj->set_attr(
"apix_y",(
float)image->get_attr(
"apix_y"));
1033 proj->set_attr(
"apix_z",(
float)image->get_attr(
"apix_z"));
1035 if(t3d) {
delete t3d; t3d=0;}
1038 else if ( image->get_ndim() == 2 ) {
1042 int nx = image->get_xsize();
1043 int ny = image->get_ysize();
1046 proj->set_size(nx, 1, 1);
1049 float *sdata = image->get_data();
1050 float *ddata = proj->get_data();
1052 Vec2f offset(nx/2,ny/2);
1053 for (
int j = -ny / 2; j < ny - ny / 2; j++) {
1055 for (
int i = -nx / 2; i < nx - nx / 2; i++,l++) {
1058 Vec2f soln = r*coord;
1067 int ii = (int) (
x +
y * nx);
1071 if (x2 < 0 || y2 < 0 )
continue;
1072 if (x2 > (nx-1) || y2 > (ny-1) )
continue;
1074 if ( x2 < (nx - 1) && y2 < (ny - 1) ) {
1077 else if (x2 == (nx-1) && y2 == (ny-1) ) {
1080 else if (x2 == (nx-1) ) {
1083 else if (y2 == (ny-1) ) {
1088 proj->set_attr(
"xform.projection",t3d);
1090 if(t3d) {
delete t3d; t3d=0;}
1195 if (3 != image->get_ndim())
1197 "FourierGriddingProjector needs a 3-D volume");
1198 if (image->is_complex())
1200 "FourierGriddingProjector requires a real volume");
1202 const int nx = image->get_xsize();
1203 const int ny = image->get_ysize();
1204 const int nz = image->get_zsize();
1205 if (nx != ny || nx != nz)
1207 "FourierGriddingProjector requires nx==ny==nz");
1209 const int n = m*npad;
1212 if ( K == 0 ) K = 6;
1213 float alpha =
params[
"kb_alpha"];
1214 if ( alpha == 0 ) alpha = 1.25;
1215 Util::KaiserBessel kb(alpha, K, (
float)(m/2), K/(2.0f*n), n);
1218 EMData* tmpImage = image->copy();
1219 tmpImage->divkbsinh(kb);
1223 EMData* imgft = tmpImage->norm_pad(
false, npad);
1224 imgft->do_fft_inplace();
1225 imgft->center_origin_fft();
1226 imgft->fft_shuffle();
1242 if ( t3d == NULL )
throw NullPointerException(
"The transform object (required for projection), was not specified");
1245 string angletype =
"SPIDER";
1246 float phi = p[
"phi"];
1247 float theta = p[
"theta"];
1248 float psi = p[
"psi"];
1253 if(t3d) {
delete t3d; t3d=0;}
1260 ret->set_size(nx, ny, nangles);
1263 for (
int ia = 0; ia < nangles; ia++) {
1267 EMData* proj = imgft->extract_plane(tf, kb);
1268 if (proj->is_shuffled()) proj->fft_shuffle();
1269 proj->center_origin_fft();
1270 proj->do_ift_inplace();
1273 for (
int iy=0; iy < ny; iy++)
1274 for (
int ix=0; ix < nx; ix++)
1275 (*ret)(ix,iy,ia) = (*winproj)(ix,iy);
1282 ret->set_attr(
"xform.projection",t3d);
1283 if(t3d) {
delete t3d; t3d=0;}
1305 int ix, iy, iz, rs, r2, xs, ys, zs, xx, yy, zz;
1306 int ftm=0, status = 0;
1311 int nx = (int)volsize[0];
1312 int ny = (int)volsize[1];
1313 int nz = (int)volsize[2];
1315 int xcent = (int)origin[0];
1316 int ycent = (int)origin[1];
1317 int zcent = (int)origin[2];
1320 for (ix = 1; ix <=nx; ix++) {
1323 for (iy = 1; iy <= ny; iy++) {
1327 for (iz = 1; iz <= nz; iz++) {
1344#define cube(i,j,k) cube[ ((k-1)*ny + j-1)*nx + i-1 ]
1345#define sphere(i) sphere[(i)-1]
1346#define cord(i,j) cord[((j)-1)*3 + (i) -1]
1347#define ptrs(i) ptrs[(i)-1]
1348#define dm(i) dm[(i)-1]
1353 int xs, ys, zs, xx, yy, zz, rs, r2;
1354 int ix, iy, iz, jnz, nnz, nrays;
1355 int ftm = 0, status = 0;
1357 int xcent = (int)origin[0];
1358 int ycent = (int)origin[1];
1359 int zcent = (int)origin[2];
1361 int nx = (int)volsize[0];
1362 int ny = (int)volsize[1];
1363 int nz = (int)volsize[2];
1370 for (ix = 1; ix <= nx; ix++) {
1373 for ( iy = 1; iy <= ny; iy++ ) {
1380 for (iz = 1; iz <= nz; iz++) {
1404 if (nnz != nnz0) status = -1;
1413 int r2, i, j, ix, iy, iz, nnz;
1415 int nx = (int)volsize[0];
1416 int ny = (int)volsize[1];
1427 for (j = 1; j <= nrays; j++) {
1431 for (i =
ptrs(j); i<=
ptrs(j+1)-1; i++, iz++) {
1436 if (nnz != nnz0) status = -1;
1440#define x(i) x[(i)-1]
1441#define y(i,j) y[(j-1)*nx + i - 1]
1446 float *
x,
float *
y)
const
1464 int iqx, iqy, i, j, xc, yc, zc;
1465 float ct, dipx, dipy, dipx1m, dipy1m, xb, yb, dm1, dm4;
1468 int xcent = origin[0];
1469 int ycent = origin[1];
1470 int zcent = origin[2];
1472 int nx = volsize[0];
1478 for (i = 1; i <= nrays; i++) {
1479 zc =
cord(1,i)-zcent;
1480 yc =
cord(2,i)-ycent;
1481 xc =
cord(3,i)-xcent;
1483 xb = zc*
dm(1)+yc*
dm(2)+xc*
dm(3) + xcent;
1484 yb = zc*
dm(4)+yc*
dm(5)+xc*
dm(6) + ycent;
1486 for (j =
ptrs(i); j<
ptrs(i+1); j++) {
1491 dipx = xb - (float)(iqx);
1492 dipy = (yb - (float)(iqy)) * ct;
1495 dipx1m = 1.0f - dipx;
1497 y(iqx ,iqy) =
y(iqx ,iqy) + dipx1m*dipy1m;
1498 y(iqx+1,iqy) =
y(iqx+1,iqy) + dipx*dipy1m;
1499 y(iqx+1,iqy+1) =
y(iqx+1,iqy+1) + dipx*dipy;
1500 y(iqx ,iqy+1) =
y(iqx ,iqy+1) + dipx1m*dipy;
1508 fprintf(stderr,
" nx must be greater than 2*ri\n");
1516#define y(i) y[(i)-1]
1517#define x(i,j) x[((j)-1)*nx + (i) - 1]
1522 float *
x,
float *
y)
const
1524 int i, j, iqx,iqy, xc, yc, zc;
1525 float xb, yb, dx, dy, dx1m, dy1m, dxdy;
1528 int xcent = origin[0];
1529 int ycent = origin[1];
1530 int zcent = origin[2];
1532 int nx = volsize[0];
1535 for (i = 1; i <= nrays; i++) {
1536 zc =
cord(1,i) - zcent;
1537 yc =
cord(2,i) - ycent;
1538 xc =
cord(3,i) - xcent;
1540 xb = zc*
dm(1)+yc*
dm(2)+xc*
dm(3) + xcent;
1541 yb = zc*
dm(4)+yc*
dm(5)+xc*
dm(6) + ycent;
1543 for (j =
ptrs(i); j <
ptrs(i+1); j++) {
1544 iqx =
ifix((
float)(xb));
1545 iqy =
ifix((
float)(yb));
1547 dx = xb - (float)(iqx);
1548 dy = yb - (float)(iqy);
1571 + dx*(-
x(iqx,iqy)+
x(iqx+1,iqy))
1572 + dy*(-
x(iqx,iqy)+
x(iqx,iqy+1))
1573 + dxdy*(
x(iqx,iqy) -
x(iqx,iqy+1)
1574 -
x(iqx+1,iqy) +
x(iqx+1,iqy+1) );
1582 fprintf(stderr,
"bckpj3: nx must be greater than 2*ri\n");
1606#define dm(i,j) dm[((j)-1)*9 + (i) -1]
1607#define anglelist(i,j) anglelist[((j)-1)*3 + (i) - 1]
1613 float psi, theta, phi;
1614 double cthe, sthe, cpsi, spsi, cphi, sphi;
1620 for (j = 1; j <= nangles; j++) {
1621 phi =
static_cast<float>(
anglelist(1,j)*dgr_to_rad);
1622 theta =
static_cast<float>(
anglelist(2,j)*dgr_to_rad);
1623 psi =
static_cast<float>(
anglelist(3,j)*dgr_to_rad);
1633 dm(1,j)=
static_cast<float>(cphi*cthe*cpsi-sphi*spsi);
1634 dm(2,j)=
static_cast<float>(sphi*cthe*cpsi+cphi*spsi);
1635 dm(3,j)=
static_cast<float>(-sthe*cpsi);
1636 dm(4,j)=
static_cast<float>(-cphi*cthe*spsi-sphi*cpsi);
1637 dm(5,j)=
static_cast<float>(-sphi*cthe*spsi+cphi*cpsi);
1638 dm(6,j)=
static_cast<float>(sthe*spsi);
1639 dm(7,j)=
static_cast<float>(sthe*cphi);
1640 dm(8,j)=
static_cast<float>(sthe*sphi);
1641 dm(9,j)=
static_cast<float>(cthe);
1646#define images(i,j,k) images[ ((k-1)*nyvol + j-1)*nxvol + i-1 ]
1651 int nrays, nnz, status, j;
1656 int nxvol = vol->get_xsize();
1657 int nyvol = vol->get_ysize();
1658 int nzvol = vol->get_zsize();
1659 Vec3i volsize(nxvol,nyvol,nzvol);
1663 LOGERR(
"The ChaoProjector needs a volume!");
1666 Vec3i origin(0,0,0);
1670 else {origin[0] = nxvol/2+1;}
1672 else {origin[1] = nyvol/2+1;}
1674 else {origin[2] = nzvol/2+1;}
1678 else {ri = dim/2 - 1;}
1681 float *
cube = vol->get_data();
1685 status =
getnnz(volsize, ri, origin, &nrays, &nnz);
1690 ptrs =
new int[nrays+1];
1691 cord =
new int[3*nrays];
1693 fprintf(stderr,
"ChaoProjector::project3d, failed to allocate!\n");
1696 for (
int i = 0; i<nnz; i++)
sphere[i] = 0.0;
1697 for (
int i = 0; i<nrays+1; i++)
ptrs[i] = 0;
1698 for (
int i = 0; i<3*nrays; i++)
cord[i] = 0;
1705 string angletype =
"SPIDER";
1712 if ( t3d == NULL )
throw NullPointerException(
"The transform object (required for projection), was not specified");
1718 if(t3d) {
delete t3d; t3d=0;}
1720 float phi = p[
"phi"];
1721 float theta = p[
"theta"];
1722 float psi = p[
"psi"];
1730 dm =
new float[nangles*9];
1735 ret->set_size(nxvol, nyvol, nangles);
1736 ret->set_complex(
false);
1739 images = ret->get_data();
1741 for (j = 1; j <= nangles; j++) {
1742 status =
fwdpj3(volsize, nrays, nnz , &
dm(1,j), origin, ri,
1755 ret->set_attr(
"xform.projection",t3d);
1756 if(t3d) {
delete t3d; t3d=0;}
1765#define images(i,j,k) images[ ((k)-1)*nximg*nyimg + ((j)-1)*nximg + (i)-1 ]
1769 int nrays, nnz, status, j;
1774 int nximg = imagestack->get_xsize();
1775 int nyimg = imagestack->get_ysize();
1776 int nslices = imagestack->get_zsize();
1779 Vec3i volsize(nximg,nyimg,dim);
1781 Vec3i origin(0,0,0);
1785 else {origin[0] = nximg/2+1;}
1787 else {origin[1] = nyimg/2+1;}
1789 else {origin[2] = dim/2+1;}
1793 else {ri = dim/2 - 1;}
1796 images = imagestack->get_data();
1800 status =
getnnz(volsize, ri, origin, &nrays, &nnz);
1805 ptrs =
new int[nrays+1];
1806 cord =
new int[3*nrays];
1808 fprintf(stderr,
"ChaoProjector::backproject3d, failed to allocate!\n");
1811 for (
int i = 0; i<nnz; i++)
sphere[i] = 0.0;
1812 for (
int i = 0; i<nrays+1; i++)
ptrs[i] = 0;
1813 for (
int i = 0; i<3*nrays; i++)
cord[i] = 0;
1817 string angletype =
"SPIDER";
1824 if ( t3d == NULL )
throw NullPointerException(
"The transform object (required for projection), was not specified");
1831 if(t3d) {
delete t3d; t3d=0;}
1833 float phi = p[
"phi"];
1834 float theta = p[
"theta"];
1835 float psi = p[
"psi"];
1844 if (nslices != nangles) {
1845 LOGERR(
"the number of images does not match the number of angles");
1849 dm =
new float[nangles*9];
1854 ret->set_size(nximg, nyimg, dim);
1855 ret->set_complex(
false);
1859 cube = ret->get_data();
1864 for (j = 1; j <= nangles; j++) {
1865 status =
bckpj3(volsize, nrays, nnz, &
dm(1,j), origin, ri,
1897#define images(i,j,k) images[ (k)*nx*ny + ((j)-1)*nx + (i)-1 ]
2022 int nx = imagestack->get_xsize();
2023 int ny = imagestack->get_ysize();
2026 images = imagestack->get_data();
2028 Vec3i origin(0,0,0);
2032 else {origin[0] = nx/2;}
2034 else {origin[1] = ny/2;}
2036 else {origin[2] = dim/2;}
2039 else {ri = dim/2 - 1;}
2047 prepcubes(nx, ny, dim, ri, origin, nn, ipcube);
2057 if ( t3d == NULL )
throw NullPointerException(
"The transform object (required for projection), was not specified");
2063 if(t3d) {
delete t3d; t3d=0;}
2065 string angletype =
"SPIDER";
2066 float phi = p[
"phi"];
2067 float theta = p[
"theta"];
2068 float psi = p[
"psi"];
2079 ret->set_size(nx, ny, dim);
2083 for (
int ia = 0; ia < nangles; ia++) {
2087 float dm1 = rotation.
at(0,0);
2088 float dm4 = rotation.
at(1,0);
2090 if (2*(ri+1)+1 > dim) {
2092 LOGERR(
"backproject3d, pawel, 2*(ri+1)+1 > dim\n");
2096 for (
int i = 0 ; i <= nn; i++) {
2097 int iox = (int)ipcube[i].loc[0]+origin[0];
2098 int ioy = (int)ipcube[i].loc[1]+origin[1];
2099 int ioz = (int)ipcube[i].loc[2]+origin[2];
2101 Vec3f vb = rotation*ipcube[i].
loc + origin;
2102 for (
int j = ipcube[i].start; j <= ipcube[i].
end; j++) {
2103 float xbb = (j-ipcube[i].
start)*dm1 + vb[0];
2104 int iqx = (int)floor(xbb);
2106 float ybb = (j-ipcube[i].
start)*dm4 + vb[1];
2107 int iqy = (int)floor(ybb);
2109 float dipx = xbb - iqx;
2110 float dipy = ybb - iqy;
2112 (*ret)(iox,ioy,ioz) +=
images(iqx,iqy,ia)
2155 dump_factory < Projector > ();
2160 return dump_factory_list < Projector > ();
int cb2sph(float *cube, Vec3i volsize, int ri, Vec3i origin, int nnz0, int *ptrs, int *cord, float *sphere) const
EMData * backproject3d(EMData *imagestack) const
Back-project a 2D image into a 3D image.
void setdm(vector< float > anglelist, string const angletype, float *dm) const
int sph2cb(float *sphere, Vec3i volsize, int nray, int ri, int nnz0, int *ptrs, int *cord, float *cube) const
EMData * project3d(EMData *vol) const
Project an 3D image into a 2D image.
int fwdpj3(Vec3i volsize, int nray, int nnz, float *dm, Vec3i origin, int ri, int *ptrs, int *cord, float *x, float *y) const
int bckpj3(Vec3i volsize, int nray, int nnz, float *dm, Vec3i origin, int ri, int *ptrs, int *cord, float *x, float *y) const
int getnnz(Vec3i volsize, int ri, Vec3i origin, int *nray, int *nnz) const
Dict is a dictionary to store <string, EMObject> pair.
bool has_key(const string &key) const
Ask the Dictionary if it as a particular key.
EMData stores an image's data and defines core image processing routines.
void translate(float dx, float dy, float dz)
Translate this image.
EMData * window_center(int l)
Window the center of an image.
float * setup4slice(bool redo=true)
Set up for fftslice operations.
Factory is used to store objects to create new instances.
EMData * project3d(EMData *image) const
Project an 3D image into a 2D image.
EMData * backproject3d(EMData *image) const
Back-project a 2D image into a 3D image.
bool interp_ft_3d(int mode, EMData *image, float x, float y, float z, float *data, float gauss_width) const
EMData * backproject3d(EMData *image) const
Back-project a 2D image into a 3D image.
static float hyperg(float v)
static float * get_gimx()
EMData * project3d(EMData *image) const
Project an 3D image into a 2D image.
EMData * backproject3d(EMData *image) const
Back-project a 2D image into a 3D image.
EMData * backproject3d(EMData *image) const
Back-project a 2D image into a 3D image.
EMData * project3d(EMData *image) const
Project an 3D image into a 2D image.
void prepcubes(int nx, int ny, int nz, int ri, Vec3i origin, int &nn, IPCube *ipcube=NULL) const
EMData * project3d(EMData *image) const
Project an 3D image into a 2D image.
EMData * backproject3d(EMData *image) const
Back-project a 2D image into a 3D image.
static int hypot3sq(int x, int y, int z)
Euclidean distance function squared in 3D: f(x,y,z) = (x*x + y*y + z*z);.
static float agauss(float a, float dx, float dy, float dz, float d)
Calculate Gaussian value.
static float linear_interpolate(float p1, float p2, float t)
Calculate linear interpolation.
static int fast_floor(float x)
A fast way to calculate a floor, which is largest integral value not greater than argument.
static float trilinear_interpolate(float p1, float p2, float p3, float p4, float p5, float p6, float p7, float p8, float t, float u, float v)
Calculate trilinear interpolation.
static int get_min(int f1, int f2)
Get the minimum of 2 numbers.
static float bilinear_interpolate(float p1, float p2, float p3, float p4, float t, float u)
Calculate bilinear interpolation.
static float get_max(float f1, float f2)
Get the maximum of 2 numbers.
The Vec2 is precisely the same as Vec3 except it works exclusively in 2D Note there are convenient ty...
void standard_project(const float *const matrix, float *data, const int nx, const int ny)
EMData * sqrt() const
return square root of current image
#define ImageFormatException(desc)
#define ImageDimensionException(desc)
#define NullPointerException(desc)
map< string, vector< string > > dump_projectors_list()