EMAN::PawelProjector Class Reference

Pawel Penczek's optimized projection routine. More...

#include <projector.h>

Inheritance diagram for EMAN::PawelProjector:

Inheritance graph
[legend]
Collaboration diagram for EMAN::PawelProjector:

Collaboration graph
[legend]
List of all members.

Public Member Functions

EMDataproject3d (EMData *image) const
 Project an 3D image into a 2D image.
EMDatabackproject3d (EMData *image) const
 Back-project a 2D image into a 3D image.
string get_name () const
 Get the projector's name.
string get_desc () const
TypeDict get_param_types () const
 Get processor parameter information in a dictionary.

Static Public Member Functions

static ProjectorNEW ()

Static Public Attributes

static const string NAME = "pawel"

Private Member Functions

void prepcubes (int nx, int ny, int nz, int ri, Vec3i origin, int &nn, IPCube *ipcube=NULL) const

Classes

struct  IPCube

Detailed Description

Pawel Penczek's optimized projection routine.

Definition at line 248 of file projector.h.


Member Function Documentation

EMData * PawelProjector::backproject3d ( EMData image  )  const [virtual]

Back-project a 2D image into a 3D image.

Returns:
A 3D image from the backprojection.

Implements EMAN::Projector.

Definition at line 1967 of file projector.cpp.

References anglelist, EMAN::Transform::at(), EMDeleteArray(), EMAN::PawelProjector::IPCube::end, EMAN::EMData::get_data(), EMAN::Util::get_min(), EMAN::Transform::get_rotation(), EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::Dict::has_key(), images, EMAN::PawelProjector::IPCube::loc, LOGERR, nn(), NullPointerException, nx, ny, EMAN::Projector::params, phi, prepcubes(), EMAN::EMData::set_size(), EMAN::Dict::size(), EMAN::PawelProjector::IPCube::start, theta, EMAN::EMData::to_zero(), and EMAN::EMData::update().

01968 {
01969 
01970         float *images;
01971 
01972         if (!imagestack) {
01973                 return 0;
01974         }
01975         int ri;
01976         int nx      = imagestack->get_xsize();
01977         int ny      = imagestack->get_ysize();
01978 //     int nslices = imagestack->get_zsize();
01979         int dim = Util::get_min(nx,ny);
01980         images  = imagestack->get_data();
01981 
01982         Vec3i origin(0,0,0);
01983     // If a sensible origin isn't passed in, choose the middle of
01984     // the cube.
01985         if (params.has_key("origin_x")) {origin[0] = params["origin_x"];}
01986         else {origin[0] = nx/2;}
01987         if (params.has_key("origin_y")) {origin[1] = params["origin_y"];}
01988         else {origin[1] = ny/2;}
01989         if (params.has_key("origin_z")) {origin[1] = params["origin_z"];}
01990         else {origin[2] = dim/2;}
01991 
01992         if (params.has_key("radius")) {ri = params["radius"];}
01993         else {ri = dim/2 - 1;}
01994 
01995     // Determine the number of rows (x-lines) within the radius
01996         int nn = -1;
01997         prepcubes(nx, ny, dim, ri, origin, nn);
01998     // nn is now the number of rows-1 within the radius
01999     // so we can create and fill the ipcubes
02000         IPCube* ipcube = new IPCube[nn+1];
02001         prepcubes(nx, ny, dim, ri, origin, nn, ipcube);
02002 
02003         int nangles = 0;
02004         vector<float> anglelist;
02005         // Do we have a list of angles?
02006         if (params.has_key("anglelist")) {
02007                 anglelist = params["anglelist"];
02008                 nangles = anglelist.size() / 3;
02009         } else {
02010                 Transform* t3d = params["transform"];
02011                 if ( t3d == NULL ) throw NullPointerException("The transform object (required for projection), was not specified");
02012                 // This part was modified by David Woolford -
02013                 // Before this the code worked only for SPIDER and EMAN angles,
02014                 // but the framework of the Transform3D allows for a generic implementation
02015                 // as specified here.
02016                 Dict p = t3d->get_rotation("spider");
02017                 if(t3d) {delete t3d; t3d=0;}
02018 
02019                 string angletype = "SPIDER";
02020                 float phi = p["phi"];
02021                 float theta = p["theta"];
02022                 float psi = p["psi"];
02023                 anglelist.push_back(phi);
02024                 anglelist.push_back(theta);
02025                 anglelist.push_back(psi);
02026                 nangles = 1;
02027         }
02028 
02029         // End David Woolford modifications
02030 
02031     // initialize return object
02032         EMData* ret = new EMData();
02033         ret->set_size(nx, ny, dim);
02034         ret->to_zero();
02035 
02036     // loop over sets of angles
02037         for (int ia = 0; ia < nangles; ia++) {
02038                 int indx = 3*ia;
02039                 Dict d("type","spider","phi",anglelist[indx],"theta",anglelist[indx+1],"psi",anglelist[indx+2]);
02040                 Transform rotation(d);
02041                 float dm1 = rotation.at(0,0);
02042                 float dm4 = rotation.at(1,0);
02043 
02044                 if (2*(ri+1)+1 > dim) {
02045           // Must check x and y boundaries
02046                         LOGERR("backproject3d, pawel, 2*(ri+1)+1 > dim\n");
02047                         return 0;
02048                 } else {
02049           // No need to check x and y boundaries
02050                         for (int i = 0 ; i <= nn; i++) {
02051                                 int iox = (int)ipcube[i].loc[0]+origin[0];
02052                                 int ioy = (int)ipcube[i].loc[1]+origin[1];
02053                                 int ioz = (int)ipcube[i].loc[2]+origin[2];
02054 
02055                                 Vec3f vb = rotation*ipcube[i].loc + origin;
02056                                 for (int j = ipcube[i].start; j <= ipcube[i].end; j++) {
02057                                         float xbb = (j-ipcube[i].start)*dm1 + vb[0];
02058                                         int   iqx = (int)floor(xbb);
02059 
02060                                         float ybb = (j-ipcube[i].start)*dm4 + vb[1];
02061                                         int   iqy = (int)floor(ybb);
02062 
02063                                         float dipx = xbb - iqx;
02064                                         float dipy = ybb - iqy;
02065 
02066                                         (*ret)(iox,ioy,ioz) += images(iqx,iqy,ia)
02067                                                         + dipy*(images(iqx,iqy+1,ia)-images(iqx,iqy,ia))
02068                                                         + dipx*(images(iqx+1,iqy,ia)-images(iqx,iqy,ia)
02069                                                                         + dipy*(images(iqx+1,iqy+1,ia)-images(iqx+1,iqy,ia)
02070                                                                                         - images(iqx,iqy+1,ia)+images(iqx,iqy,ia)));
02071                                         iox++;
02072                                 } // end for j
02073                         } // end for i
02074                 } // end if
02075         } // end for ia
02076 
02077         ret->update();
02078         EMDeleteArray(ipcube);
02079         return ret;
02080 }

string EMAN::PawelProjector::get_desc (  )  const [inline, virtual]

Implements EMAN::Projector.

Definition at line 259 of file projector.h.

00260                 {
00261                         return "Pawel Penczek's optimized real-space projection generation. Minor interpolation artifacts.";
00262                 }

string EMAN::PawelProjector::get_name (  )  const [inline, virtual]

Get the projector's name.

Each projector is indentified by unique name.

Returns:
The projector's name.

Implements EMAN::Projector.

Definition at line 254 of file projector.h.

References NAME.

00255                 {
00256                         return NAME;
00257                 }

TypeDict EMAN::PawelProjector::get_param_types (  )  const [inline, virtual]

Get processor parameter information in a dictionary.

Each parameter has one record in the dictionary. Each record contains its name, data-type, and description.

Returns:
A dictionary containing the parameter info.

Reimplemented from EMAN::Projector.

Definition at line 269 of file projector.h.

References EMAN::EMObject::FLOAT, EMAN::EMObject::FLOATARRAY, EMAN::EMObject::INT, EMAN::TypeDict::put(), EMAN::EMObject::STRING, and EMAN::EMObject::TRANSFORM.

00270                 {
00271                         TypeDict d;
00272                         d.put("transform", EMObject::TRANSFORM);
00273                         d.put("origin_x", EMObject::INT);
00274                         d.put("origin_y", EMObject::INT);
00275                         d.put("origin_z", EMObject::INT);
00276                         d.put("radius", EMObject::INT);
00277                         d.put("anglelist", EMObject::FLOATARRAY);
00278                         d.put("angletype", EMObject::STRING);
00279                         d.put("theta", EMObject::FLOAT);
00280                         d.put("psi", EMObject::FLOAT);
00281                         return d;
00282                 }

static Projector* EMAN::PawelProjector::NEW (  )  [inline, static]

Definition at line 264 of file projector.h.

00265                 {
00266                         return new PawelProjector();
00267                 }

void PawelProjector::prepcubes ( int  nx,
int  ny,
int  nz,
int  ri,
Vec3i  origin,
int &  nn,
IPCube ipcube = NULL 
) const [private]

Definition at line 531 of file projector.cpp.

References EMAN::PawelProjector::IPCube::end, EMAN::PawelProjector::IPCube::loc, and t.

Referenced by backproject3d(), and project3d().

00532                                                                       {
00533         const float r = float(ri*ri);
00534         const int ldpx = origin[0];
00535         const int ldpy = origin[1];
00536         const int ldpz = origin[2];
00537         float t;
00538         nn = -1;
00539         for (int i1 = 0; i1 < nz; i1++) {
00540                 t = float(i1 - ldpz);
00541                 const float xx = t*t;
00542                 for (int i2 = 0; i2 < ny; i2++) {
00543                         t = float(i2 - ldpy);
00544                         const float yy = t*t + xx;
00545                         bool first = true;
00546                         for (int i3 = 0; i3 < nz; i3++) {
00547                                 t = float(i3 - ldpx);
00548                                 const float rc = t*t + yy;
00549                                 if (first) {
00550                                         // first pixel on this line
00551                                         if (rc > r) continue;
00552                                         first = false;
00553                                         nn++;
00554                                         if (ipcube != NULL) {
00555                                                 ipcube[nn].start = i3;
00556                                                 ipcube[nn].end = i3;
00557                                                 ipcube[nn].loc[0] = i3 - ldpx;
00558                                                 ipcube[nn].loc[1] = i2 - ldpy;
00559                                                 ipcube[nn].loc[2] = i1 - ldpz;
00560                                         }
00561                                 } else {
00562                                         // second or later pixel on this line
00563                                         if (ipcube != NULL) {
00564                                                 if (rc <= r) ipcube[nn].end = i3;
00565                                         }
00566                                 }
00567                         }
00568                 }
00569         }
00570 }

EMData * PawelProjector::project3d ( EMData image  )  const [virtual]

Project an 3D image into a 2D image.

Returns:
A 2D image from the projection.

Implements EMAN::Projector.

Definition at line 723 of file projector.cpp.

References anglelist, EMDeleteArray(), EMAN::PawelProjector::IPCube::end, EMAN::Transform::get_matrix3_row(), EMAN::Util::get_min(), EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::EMData::get_zsize(), EMAN::Dict::has_key(), EMAN::PawelProjector::IPCube::loc, LOGERR, nn(), NullPointerException, nx, ny, EMAN::Projector::params, prepcubes(), EMAN::EMData::set_size(), EMAN::EMData::to_zero(), and EMAN::EMData::update().

00724 {
00725         if (!image) {
00726                 return 0;
00727         }
00728         int ri;
00729         int nx = image->get_xsize();
00730         int ny = image->get_ysize();
00731         int nz = image->get_zsize();
00732         int dim = Util::get_min(nx,ny,nz);
00733         if (nz == 1) {
00734                 LOGERR("The PawelProjector needs a volume!");
00735                 return 0;
00736         }
00737         Vec3i origin(0,0,0);
00738         // If a sensible origin isn't passed in, choose the middle of
00739         // the cube.
00740         if (params.has_key("origin_x")) {origin[0] = params["origin_x"];}
00741         else {origin[0] = nx/2;}
00742         if (params.has_key("origin_y")) {origin[1] = params["origin_y"];}
00743         else {origin[1] = ny/2;}
00744         if (params.has_key("origin_z")) {origin[2] = params["origin_z"];}
00745         else {origin[2] = nz/2;}
00746 
00747         if (params.has_key("radius")) {ri = params["radius"];}
00748         else {ri = dim/2 - 1;}
00749 
00750         // Determine the number of rows (x-lines) within the radius
00751         int nn = -1;
00752         prepcubes(nx, ny, nz, ri, origin, nn);
00753         // nn is now the number of rows-1 within the radius
00754         // so we can create and fill the ipcubes
00755         IPCube* ipcube = new IPCube[nn+1];
00756         prepcubes(nx, ny, nz, ri, origin, nn, ipcube);
00757 
00758         Transform* rotation = params["transform"];
00759         int nangles = 0;
00760         vector<float> anglelist;
00761         // Do we have a list of angles?
00762         /*
00763         if (params.has_key("anglelist")) {
00764                 anglelist = params["anglelist"];
00765                 nangles = anglelist.size() / 3;
00766         } else {*/
00767 
00768                 if ( rotation == NULL ) throw NullPointerException("The transform object (required for projection), was not specified");
00769                 /*
00770                 Dict p = t3d->get_rotation("spider");
00771 
00772                 string angletype = "SPIDER";
00773                 float phi = p["phi"];
00774                 float theta = p["theta"];
00775                 float psi = p["psi"];
00776                 anglelist.push_back(phi);
00777                 anglelist.push_back(theta);
00778                 anglelist.push_back(psi);
00779                 */
00780                 nangles = 1;
00781         //}
00782 
00783         // initialize return object
00784         EMData* ret = new EMData();
00785         ret->set_size(nx, ny, nangles);
00786         ret->to_zero();
00787 
00788         // loop over sets of angles
00789         for (int ia = 0; ia < nangles; ia++) {
00790                 //int indx = 3*ia;
00791                 //Dict d("type","spider","phi",anglelist[indx],"theta",anglelist[indx+1],"psi",anglelist[indx+2]);
00792                 //Transform rotation(d);
00793                 if (2*(ri+1)+1 > dim) {
00794                         // Must check x and y boundaries
00795                         for (int i = 0 ; i <= nn; i++) {
00796                                 int k = ipcube[i].loc[1] + origin[1];
00797                                 Vec3f vb = ipcube[i].loc*(*rotation) + origin;
00798                                 for (int j = ipcube[i].start; j <= ipcube[i].end; j++) {
00799                                         // check for pixels out-of-bounds
00800                                         int iox = int(vb[0]);
00801                                         if ((iox >= 0) && (iox < nx-1)) {
00802                                                 int ioy = int(vb[1]);
00803                                                 if ((ioy >= 0) && (ioy < ny-1)) {
00804                                                         int ioz = int(vb[2]);
00805                                                         if ((ioz >= 0) && (ioz < nz-1)) {
00806                                                                 // real work for pixels in bounds
00807                                                                 float dx = vb[0] - iox;
00808                                                                 float dy = vb[1] - ioy;
00809                                                                 float dz = vb[2] - ioz;
00810                                                                 float a1 = (*image)(iox,ioy,ioz);
00811                                                                 float a2 = (*image)(iox+1,ioy,ioz) - a1;
00812                                                                 float a3 = (*image)(iox,ioy+1,ioz) - a1;
00813                                                                 float a4 = (*image)(iox,ioy,ioz+1) - a1;
00814                                                                 float a5 = -a2 -(*image)(iox,ioy+1,ioz)
00815                                                                                 + (*image)(iox+1,ioy+1,ioz);
00816                                                                 float a61 = -(*image)(iox,ioy,ioz+1)
00817                                                                                 + (*image)(iox+1,ioy,ioz+1);
00818                                                                 float a6 = -a2 + a61;
00819                                                                 float a7 = -a3 - (*image)(iox,ioy,ioz+1)
00820                                                                                 + (*image)(iox,ioy+1,ioz+1);
00821                                                                 float a8 = -a5 - a61 - (*image)(iox,ioy+1,ioz+1)
00822                                                                                 + (*image)(iox+1,ioy+1,ioz+1);
00823                                                                 (*ret)(j,k,ia) += a1 + dz*(a4 + a6*dx
00824                                                                                 + (a7 + a8*dx)*dy)
00825                                                                                 + a3*dy + dx*(a2 + a5*dy);
00826                                                         }
00827                                                 }
00828                                         }
00829                                         vb += rotation->get_matrix3_row(0);
00830                                 }
00831                         }
00832 
00833                 } else {
00834                         // No need to check x and y boundaries
00835                         for (int i = 0 ; i <= nn; i++) {
00836                                 int k = ipcube[i].loc[1] + origin[1];
00837                                 Vec3f vb = ipcube[i].loc*(*rotation) + origin;
00838                                 for (int j = ipcube[i].start; j <= ipcube[i].end; j++) {
00839                                         int iox = int(vb[0]);
00840                                         int ioy = int(vb[1]);
00841                                         int ioz = int(vb[2]);
00842                                         float dx = vb[0] - iox;
00843                                         float dy = vb[1] - ioy;
00844                                         float dz = vb[2] - ioz;
00845                                         float a1 = (*image)(iox,ioy,ioz);
00846                                         float a2 = (*image)(iox+1,ioy,ioz) - a1;
00847                                         float a3 = (*image)(iox,ioy+1,ioz) - a1;
00848                                         float a4 = (*image)(iox,ioy,ioz+1) - a1;
00849                                         float a5 = -a2 -(*image)(iox,ioy+1,ioz)
00850                                                         + (*image)(iox+1,ioy+1,ioz);
00851                                         float a61 = -(*image)(iox,ioy,ioz+1)
00852                                                         + (*image)(iox+1,ioy,ioz+1);
00853                                         float a6 = -a2 + a61;
00854                                         float a7 = -a3 - (*image)(iox,ioy,ioz+1)
00855                                                         + (*image)(iox,ioy+1,ioz+1);
00856                                         float a8 = -a5 - a61 - (*image)(iox,ioy+1,ioz+1)
00857                                                         + (*image)(iox+1,ioy+1,ioz+1);
00858                                         (*ret)(j,k,ia) += a1 + dz*(a4 + a6*dx
00859                                                         + (a7 + a8*dx)*dy)
00860                                                         + a3*dy + dx*(a2 + a5*dy);
00861                                         vb += rotation->get_matrix3_row(0);
00862                                 }
00863                         }
00864                 }
00865         }
00866         ret->update();
00867         EMDeleteArray(ipcube);
00868         if(rotation) {delete rotation; rotation=0;}
00869         return ret;
00870 }


Member Data Documentation

const string PawelProjector::NAME = "pawel" [static]

Definition at line 284 of file projector.h.

Referenced by get_name().


The documentation for this class was generated from the following files:
Generated on Thu Nov 17 12:47:09 2011 for EMAN2 by  doxygen 1.4.7