a function or class that is CUDA enabled


Classes

class  EMAN::TranslationalAligner
 Translational 2D Alignment using cross correlation. More...
class  EMAN::RotationalAligner
 rotational alignment using angular correlation More...
class  EMAN::RotateTranslateAligner
 rotational, translational alignment More...
class  EMAN::RotateFlipAligner
 rotational and flip alignment More...
class  EMAN::Refine3DAlignerGrid
 Refine alignment. More...
class  EMAN::Refine3DAlignerQuaternion
 Refine alignment. More...
class  EMAN::RT3DGridAligner
 rotational and translational alignment using a square qrid of Altitude and Azimuth values (the phi range is specifiable) This aligner is ported from the original tomohunter.py - it is less efficient than searching on the sphere (RT3DSphereAligner). More...
class  EMAN::RT3DSphereAligner
 3D rotational and translational alignment using spherical sampling, can reduce the search space based on symmetry. More...
class  EMAN::RT3DSymmetryAligner
 3D rotational symmetry aligner. More...
class  EMAN::CccCmp
 Compute the cross-correlation coefficient between two images. More...
class  EMAN::DotCmp
 Use dot product of 2 same-size images to do the comparison. More...
class  EMAN::TomoCccCmp
 This implements the technique of Mike Schmid where by the cross correlation is normalized in an effort to remove the effects of the missing wedge. More...
class  EMAN::TomoFscCmp
 This is a FSC comparitor for tomography. More...
class  EMAN::Rotate180Processor
 Rotate by 180 using pixel swapping, works for 2D only. More...
class  EMAN::TransformProcessor
 Transform the image using a Transform object. More...
class  EMAN::IntTranslateProcessor
 Translate the image an integer amount Uses EMData::clip_inplace (inplace) and EMData::get_clip (out of place) to do the translation. More...
class  EMAN::StandardProjector
 Fast real-space 3D projection. More...
class  EMAN::FourierReconstructor
 Fourier space 3D reconstruction The Fourier reconstructor is designed to work in an iterative fashion, where similarity ("quality") metrics are used to determine if a slice should be inserted into the 3D in each subsequent iteration. More...
class  EMAN::FourierPlaneReconstructor
 Fourier space 3D reconstruction The Fourier reconstructor is designed to work in an iterative fashion, where similarity ("quality") metrics are used to determine if a slice should be inserted into the 3D in each subsequent iteration. More...

Functions

void EMAN::EMData::insert_clip (const EMData *const block, const IntPoint &origin)
 Insert a clip into this image.
 EMAN::EMData::EMData (int nx, int ny, int nz=1, bool is_real=true)
 # makes an image of the specified size, either real or complex.
 EMAN::EMData::EMData (float *data, float *cudadata, const int nx, const int ny, const int nz, const Dict &attr_dict=Dict())
 Construction from a data pointer for usage in cuda, dimensions must be supplied.
 EMAN::EMData::EMData (const EMData &that)
 Construct from an EMData (copy constructor).
EMDataEMAN::EMData::operator= (const EMData &that)
 EMData assignment operator Performs a deep copy.
EMDataEMAN::EMData::calc_ccf (EMData *with=0, fp_flag fpflag=CIRCULANT, bool center=false)
 Calculate Cross-Correlation Function (CCF).
EMDataEMAN::EMData::calc_ccfx (EMData *const with, int y0=0, int y1=-1, bool nosum=false, bool flip=false)
 Calculate Cross-Correlation Function (CCF) in the x-direction and adds them up, result in 1D.
EMDataEMAN::EMData::make_rotational_footprint (bool unwrap=true)
 Makes a 'rotational footprint', which is an 'unwound' autocorrelation function.
EMDataEMAN::EMData::unwrap (int r1=-1, int r2=-1, int xs=-1, int dx=0, int dy=0, bool do360=false, bool weight_radial=true) const
 Maps to polar coordinates from Cartesian coordinates.
void insert_clip (const EMData *const block, const IntPoint &origin)
 Insert a clip into this image.

Function Documentation

EMData * EMData::calc_ccf ( EMData with = 0,
fp_flag  fpflag = CIRCULANT,
bool  center = false 
) [inherited]

Calculate Cross-Correlation Function (CCF).

Calculate the correlation of two 1-, 2-, or 3-dimensional images. Note: this method internally just calls the correlation function from fundamentals.h.

Parameters:
[in] with The image used to calculate the CCF. If 'with' is NULL, the autocorrelation function is computed instead.
[in] fpflag Specify how periodicity (or normalization) should be handled. See fundamentals.h The default is "CIRCULANT". for specific flags.
center whether or not to center the image (bring bottom left corner to center)
Returns:
Real-space image.
Exceptions:
ImageDimensionException if nx > 1 and nx < 2*radius + 1

Definition at line 1468 of file emdata.cpp.

References calc_ccf_cuda(), calc_conv_cuda(), EMAN::EMData::clip_inplace(), EMAN::convolution(), EMAN::correlation(), ENTERFUNC, EXITFUNC, EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::EMData::get_zsize(), EMAN::EMData::is_complex(), EMAN::EMData::nx, EMAN::EMData::ny, EMAN::EMData::nz, and EMAN::EMData::update().

Referenced by EMAN::Refine3DAlignerGrid::align(), EMAN::TranslationalAligner::align(), EMAN::EMData::calc_flcf(), EMAN::TomoCccCmp::cmp(), EMAN::EMData::make_rotational_footprint(), EMAN::RT3DSphereAligner::xform_align_nbest(), and EMAN::RT3DGridAligner::xform_align_nbest().

01469 {
01470         ENTERFUNC;
01471 
01472         if( with == 0 ) {
01473 #ifdef EMAN2_USING_CUDA //CUDA 
01474         if(EMData::usecuda == 1 && cudarwdata) {
01475                 //cout << "calc ccf" << endl;
01476                 EMData* ifft = 0;
01477                 bool delifft = false;
01478                 int offset = 0;
01479                 
01480                 //do fft if not alreay done
01481                 if(!is_complex()){
01482                         ifft = do_fft_cuda();
01483                         delifft = true;
01484                         offset = 2 - nx%2;
01485                 }else{
01486                         ifft = this;
01487                 }
01488                 calc_conv_cuda(ifft->cudarwdata,ifft->cudarwdata,nx + offset, ny, nz); //this is the business end, results go in afft
01489                 
01490                 EMData * conv = ifft->do_ift_cuda();
01491                 if(delifft) delete ifft;
01492                 conv->update();
01493                         
01494                 return conv;
01495         }
01496 #endif
01497                 EXITFUNC;
01498                 return convolution(this,this,fpflag, center);
01499         }
01500         else if ( with == this ){ // this if statement is not necessary, the correlation function tests to see if with == this
01501                 EXITFUNC;
01502                 return correlation(this, this, fpflag,center);
01503         }
01504         else {
01505 
01506 #ifdef EMAN2_USING_CUDA //CUDA 
01507                 // assume always get rw data (makes life a lot easier!!! 
01508                 // also assume that both images are the same size. When using CUDA we are only interested in speed, not flexibility!!
01509                 // P.S. (I feel like I am pounding square pegs into a round holes with CUDA)
01510                 if(EMData::usecuda == 1 && cudarwdata && with->cudarwdata) {
01511                         //cout << "using CUDA for ccf" << endl;
01512                         EMData* afft = 0;
01513                         EMData* bfft = 0;
01514                         bool delafft = false, delbfft = false;
01515                         int offset = 0;
01516                         
01517                         //do ffts if not alreay done
01518                         if(!is_complex()){
01519                                 afft = do_fft_cuda();
01520                                 delafft = true;
01521                                 offset = 2 - nx%2;
01522                                 //cout << "Do cuda FFT A" << endl;
01523                         }else{
01524                                 afft = this;
01525                         }
01526                         if(!with->is_complex()){
01527                                 bfft = with->do_fft_cuda();
01528                                 //cout << "Do cuda FFT B" << endl;
01529                                 delbfft = true;
01530                         }else{
01531                                 bfft = with;
01532                         }
01533 
01534                         calc_ccf_cuda(afft->cudarwdata,bfft->cudarwdata,nx + offset, ny, nz); //this is the business end, results go in afft
01535                         
01536                         if(delbfft) delete bfft;
01537                         
01538                         EMData * corr = afft->do_ift_cuda();
01539                         if(delafft) delete afft;
01540                         //cor->do_ift_inplace_cuda();//a bit faster, but I'll alos need to rearrnage the mem structure for it to work, BUT this is very SLOW.
01541                         corr->update();
01542                         
01543                         return corr;
01544                 }
01545 #endif
01546                 
01547                 // If the argument EMData pointer is not the same size we automatically resize it
01548                 bool undoresize = false;
01549                 int wnx = with->get_xsize(); int wny = with->get_ysize(); int wnz = with->get_zsize();
01550                 if (!(is_complex()^with->is_complex()) && (wnx != nx || wny != ny || wnz != nz) ) {
01551                         Region r((wnx-nx)/2, (wny-ny)/2, (wnz-nz)/2,nx,ny,nz);
01552                         with->clip_inplace(r);
01553                         undoresize = true;
01554                 }
01555 
01556                 EMData* cor = correlation(this, with, fpflag, center);
01557 
01558                 // If the argument EMData pointer was resized, it is returned to its original dimensions
01559                 if ( undoresize ) {
01560                         Region r((nx-wnx)/2, (ny-wny)/2,(nz-wnz)/2,wnx,wny,wnz);
01561                         with->clip_inplace(r);
01562                 }
01563 
01564                 EXITFUNC;
01565                 return cor;
01566         }
01567 }

EMData * EMData::calc_ccfx ( EMData *const   with,
int  y0 = 0,
int  y1 = -1,
bool  nosum = false,
bool  flip = false 
) [inherited]

Calculate Cross-Correlation Function (CCF) in the x-direction and adds them up, result in 1D.

WARNING: this routine will modify the 'this' and 'with' to contain 1D fft's without setting some flags. This is an optimization for rotational alignment.

Parameters:
with The image used to calculate CCF.
y0 Starting position in x-direction.
y1 Ending position in x-direction. '-1' means the end of the row.
nosum If true, returns an image y1-y0+1 pixels high.
See also:
calc_ccf()
Exceptions:
NullPointerException If input image 'with' is NULL.
ImageFormatException If 'with' and 'this' are not same size.
ImageDimensionException If 'this' image is 3D.
Returns:
The result image containing the CCF.

Definition at line 1569 of file emdata.cpp.

References calc_ccf_cuda(), cuda_dd_fft_complex_to_real_nd(), cuda_dd_fft_real_to_complex_nd(), EMAN::EMData::EMData(), emdata_column_sum(), ENTERFUNC, EXITFUNC, EMAN::EMData::get_data(), EMAN::EMData::get_ndim(), EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::EMData::get_zsize(), ImageDimensionException, ImageFormatException, EMAN::EMData::is_complex_x(), EMAN::EMUtil::is_same_size(), LOGERR, NullPointerException, EMAN::EMData::nx, EMAN::EMData::ny, EMAN::EMData::nz, EMAN::EMData::set_size(), EMAN::EMData::to_zero(), and EMAN::EMData::update().

Referenced by EMAN::RTFExhaustiveAligner::align(), EMAN::RotateTranslateFlipAlignerPawel::align(), EMAN::RotateTranslateAlignerPawel::align(), EMAN::RotationalAlignerIterative::align(), EMAN::RotatePrecenterAligner::align(), EMAN::RotationalAligner::align_180_ambiguous(), and EMAN::EMData::make_footprint().

01570 {
01571         ENTERFUNC;
01572 
01573         if (!with) {
01574                 LOGERR("NULL 'with' image. ");
01575                 throw NullPointerException("NULL input image");
01576         }
01577 
01578         if (!EMUtil::is_same_size(this, with)) {
01579                 LOGERR("images not same size: (%d,%d,%d) != (%d,%d,%d)",
01580                            nx, ny, nz,
01581                            with->get_xsize(), with->get_ysize(), with->get_zsize());
01582                 throw ImageFormatException("images not same size");
01583         }
01584         if (get_ndim() > 2) {
01585                 LOGERR("2D images only");
01586                 throw ImageDimensionException("2D images only");
01587         }
01588 
01589         if (y1 <= y0) {
01590                 y1 = ny;
01591         }
01592 
01593         if (y0 >= y1) {
01594                 y0 = 0;
01595         }
01596 
01597         if (y0 < 0) {
01598                 y0 = 0;
01599         }
01600 
01601         if (y1 > ny) {
01602                 y1 = ny;
01603         }
01604         if (is_complex_x() || with->is_complex_x() ) throw; // Woops don't support this anymore!
01605 
01606         static int nx_fft = 0;
01607         static int ny_fft = 0;
01608         static EMData f1;
01609         static EMData f2;
01610         static EMData rslt;
01611 
01612         int height = y1-y0;
01613         int width = (nx+2-(nx%2));
01614         if (width != nx_fft || height != ny_fft ) {
01615                 f1.set_size(width,height);
01616                 f2.set_size(width,height);
01617                 rslt.set_size(nx,height);
01618                 nx_fft = width;
01619                 ny_fft = height;
01620         }
01621 
01622 #ifdef EMAN2_USING_CUDA
01623         if (EMData::usecuda == 1 && cudarwdata && with->cudarwdata) {
01624                 //cout << "calc_ccfx CUDA" << endl;
01625                 if(!f1.cudarwdata) f1.rw_alloc();
01626                 if(!f2.cudarwdata) f2.rw_alloc();
01627                 if(!rslt.cudarwdata) rslt.rw_alloc();
01628                 cuda_dd_fft_real_to_complex_nd(cudarwdata, f1.cudarwdata, nx, 1, 1, height);
01629                 cuda_dd_fft_real_to_complex_nd(with->cudarwdata, f2.cudarwdata, nx, 1, 1, height);
01630                 calc_ccf_cuda(f1.cudarwdata, f2.cudarwdata, nx, ny, nz);
01631                 cuda_dd_fft_complex_to_real_nd(f1.cudarwdata, rslt.cudarwdata, nx, 1, 1, height);
01632                 if(no_sum){
01633                         EMData* result = new EMData(rslt);
01634                         return result;
01635                 }
01636                 EMData* cf = new EMData(0,0,nx,1,1); //cuda constructor
01637                 cf->runcuda(emdata_column_sum(rslt.cudarwdata, nx, ny));
01638                 cf->update();
01639                 
01640                 EXITFUNC;
01641                 return cf;
01642         }
01643 #endif
01644 
01645         float *d1 = get_data();
01646         float *d2 = with->get_data();
01647         float *f1d = f1.get_data();
01648         float *f2d = f2.get_data();
01649         for (int j = 0; j < height; j++) {
01650                 EMfft::real_to_complex_1d(d1 + j * nx, f1d+j*width, nx);
01651                 EMfft::real_to_complex_1d(d2 + j * nx, f2d+j*width, nx);
01652         }
01653 
01654         if(flip == false) {
01655                 for (int j = 0; j < height; j++) {
01656                         float *f1a = f1d + j * width;
01657                         float *f2a = f2d + j * width;
01658 
01659                         for (int i = 0; i < width / 2; i++) {
01660                                 float re1 = f1a[2*i];
01661                                 float re2 = f2a[2*i];
01662                                 float im1 = f1a[2*i+1];
01663                                 float im2 = f2a[2*i+1];
01664 
01665                                 f1d[j*width+i*2] = re1 * re2 + im1 * im2;
01666                                 f1d[j*width+i*2+1] = im1 * re2 - re1 * im2;
01667                         }
01668                 }
01669         } else {
01670                 for (int j = 0; j < height; j++) {
01671                         float *f1a = f1d + j * width;
01672                         float *f2a = f2d + j * width;
01673 
01674                         for (int i = 0; i < width / 2; i++) {
01675                                 float re1 = f1a[2*i];
01676                                 float re2 = f2a[2*i];
01677                                 float im1 = f1a[2*i+1];
01678                                 float im2 = f2a[2*i+1];
01679 
01680                                 f1d[j*width+i*2] = re1 * re2 - im1 * im2;
01681                                 f1d[j*width+i*2+1] = im1 * re2 + re1 * im2;
01682                         }
01683                 }
01684         }
01685 
01686         float* rd = rslt.get_data();
01687         for (int j = y0; j < y1; j++) {
01688                 EMfft::complex_to_real_1d(f1d+j*width, rd+j*nx, nx);
01689         }
01690 
01691         if (no_sum) {
01692                 rslt.update(); // This is important in terms of the copy - the returned object won't have the correct flags unless we do this
01693                 EXITFUNC;
01694                 return new EMData(rslt);
01695         } else {
01696                 EMData *cf = new EMData(nx,1,1);
01697                 cf->to_zero();
01698                 float *c = cf->get_data();
01699                 for (int j = 0; j < height; j++) {
01700                         for(int i = 0; i < nx; ++i) {
01701                                 c[i] += rd[i+j*nx];
01702                         }
01703                 }
01704                 cf->update();
01705                 EXITFUNC;
01706                 return cf;
01707         }
01708 }

EMData::EMData ( const EMData that  )  [inherited]

Construct from an EMData (copy constructor).

Performs a deep copy

Parameters:
that the EMData to copy

Definition at line 131 of file emdata.cpp.

References data, EMAN::EMUtil::em_malloc(), EMAN::EMUtil::em_memcpy(), EMAN::EMData::EMData(), ENTERFUNC, EMAN::EMData::nx, EMAN::EMData::ny, EMAN::EMData::nz, EMAN::EMData::rdata, EMAN::EMData::rot_fp, EMAN::EMData::totalalloc, and UnexpectedBehaviorException.

00131                                  :
00132 #ifdef EMAN2_USING_CUDA
00133                 cudarwdata(0), cudarodata(0), num_bytes(0), nextlistitem(0), prevlistitem(0), roneedsupdate(0), cudadirtybit(0),
00134 #endif //EMAN2_USING_CUDA
00135                 attr_dict(that.attr_dict), rdata(0), supp(0), flags(that.flags), changecount(that.changecount), nx(that.nx), ny(that.ny), nz(that.nz),
00136                 nxy(that.nx*that.ny), nxyz((size_t)that.nx*that.ny*that.nz), xoff(that.xoff), yoff(that.yoff), zoff(that.zoff),all_translation(that.all_translation),   path(that.path),
00137                 pathnum(that.pathnum), rot_fp(0)
00138 {
00139         ENTERFUNC;
00140         
00141         float* data = that.rdata;
00142         size_t num_bytes = (size_t)nx*ny*nz*sizeof(float);
00143         if (data && num_bytes != 0)
00144         {
00145                 rdata = (float*)EMUtil::em_malloc(num_bytes);
00146                 EMUtil::em_memcpy(rdata, data, num_bytes);
00147         }
00148 #ifdef EMAN2_USING_CUDA
00149         if (EMData::usecuda == 1 && num_bytes != 0 && that.cudarwdata != 0) {
00150                 //cout << "That copy constructor" << endl;
00151                 if(!rw_alloc()) throw UnexpectedBehaviorException("Bad alloc");
00152                 cudaError_t error = cudaMemcpy(cudarwdata,that.cudarwdata,num_bytes,cudaMemcpyDeviceToDevice);
00153                 if ( error != cudaSuccess ) throw UnexpectedBehaviorException("cudaMemcpy failed in EMData copy construction with error: " + string(cudaGetErrorString(error)));
00154         }
00155 #endif //EMAN2_USING_CUDA
00156 
00157         if (that.rot_fp != 0) rot_fp = new EMData(*(that.rot_fp));
00158 
00159         EMData::totalalloc++;
00160 #ifdef MEMDEBUG2
00161         printf("EMDATA+  %4d    %p\n",EMData::totalalloc,this);
00162 #endif
00163 
00164         ENTERFUNC;
00165 }

EMAN::EMData::EMData ( float *  data,
float *  cudadata,
const int  nx,
const int  ny,
const int  nz,
const Dict attr_dict = Dict() 
) [inherited]

Construction from a data pointer for usage in cuda, dimensions must be supplied.

Takes possession of the pointer. data pointer must be allocated using malloc!

Parameters:
data a pointer to the pixel data which is stored in memory. Takes possession
cudadata a pointer to the pixel data which is stored in cudamemory. Takes possession
nx the number of pixels in the x direction
ny the number of pixels in the y direction
nz the number of pixels in the z direction

EMData::EMData ( int  nx,
int  ny,
int  nz = 1,
bool  is_real = true 
) [inherited]

# makes an image of the specified size, either real or complex.

For complex image, the user would specify the real-space dimensions.

Parameters:
nx size for x dimension
ny size for y dimension
nz size for z dimension, default 1
is_real boolean to specify real(true) or complex(false) image, default real

Definition at line 215 of file emdata.cpp.

References EMAN::EMData::attr_dict, ENTERFUNC, EXITFUNC, EMAN::EMData::set_size(), EMAN::EMData::to_zero(), EMAN::EMData::totalalloc, and EMAN::EMData::update().

00215                                                    :
00216 #ifdef EMAN2_USING_CUDA
00217                 cudarwdata(0), cudarodata(0), num_bytes(0), nextlistitem(0), prevlistitem(0), roneedsupdate(0), cudadirtybit(0),
00218 #endif //EMAN2_USING_CUDA
00219                 attr_dict(), rdata(0), supp(0), flags(0), changecount(0), nx(0), ny(0), nz(0), nxy(0), nxyz(0), xoff(0), yoff(0), zoff(0),
00220                 all_translation(),      path(""), pathnum(0), rot_fp(0)
00221 {
00222         ENTERFUNC;
00223 
00224         // used to replace cube 'pixel'
00225         attr_dict["apix_x"] = 1.0f;
00226         attr_dict["apix_y"] = 1.0f;
00227         attr_dict["apix_z"] = 1.0f;
00228 
00229         if(is_real) {   // create a real image [nx, ny, nz]
00230                 attr_dict["is_complex"] = int(0);
00231                 attr_dict["is_complex_x"] = int(0);
00232                 attr_dict["is_complex_ri"] = int(1);
00233                 set_size(nx, ny, nz);
00234         }
00235         else {  //create a complex image which real dimension is [ny, ny, nz]
00236                 int new_nx = nx + 2 - nx%2;
00237                 set_size(new_nx, ny, nz);
00238 
00239                 attr_dict["is_complex"] = int(1);
00240 
00241                 if(ny==1 && nz ==1)     {
00242                         attr_dict["is_complex_x"] = int(1);
00243                 }
00244                 else {
00245                         attr_dict["is_complex_x"] = int(0);
00246                 }
00247 
00248                 attr_dict["is_complex_ri"] = int(1);
00249                 attr_dict["is_fftpad"] = int(1);
00250 
00251                 if(nx%2 == 1) {
00252                         attr_dict["is_fftodd"] = 1;
00253                 }
00254         }
00255 
00256         this->to_zero();
00257         update();
00258         EMData::totalalloc++;
00259 #ifdef MEMDEBUG2
00260         printf("EMDATA+  %4d    %p\n",EMData::totalalloc,this);
00261 #endif
00262 
00263         EXITFUNC;
00264 }

void insert_clip ( const EMData *const   block,
const IntPoint &  origin 
)

Insert a clip into this image.

Very robust clip insertion code works in all way you might think possible

Parameters:
block An image block.
origin The origin location to insert the clip. ( )

void EMData::insert_clip ( const EMData *const   block,
const IntPoint origin 
) [inherited]

Insert a clip into this image.

Very robust clip insertion code works in all way you might think possible

Parameters:
block An image block.
origin The origin location to insert the clip. ( )

Definition at line 1758 of file emdata_transform.cpp.

References EMAN::EMUtil::em_memcpy(), EMAN::EMData::get_data(), EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::EMData::get_zsize(), EMAN::EMData::nx, EMAN::EMData::ny, EMAN::EMData::nz, EMAN::Region::origin, and EMAN::Region::size.

Referenced by EMAN::EMData::get_clip(), and EMAN::EMData::make_rotational_footprint_e1().

01758                                                                            {
01759         int nx1 = block->get_xsize();
01760         int ny1 = block->get_ysize();
01761         int nz1 = block->get_zsize();
01762 
01763         Region area(origin[0], origin[1], origin[2],nx1, ny1, nz1);
01764 
01765         //make sure the block fits in EMData 
01766         int x0 = (int) area.origin[0];
01767         x0 = x0 < 0 ? 0 : x0;
01768 
01769         int y0 = (int) area.origin[1];
01770         y0 = y0 < 0 ? 0 : y0;
01771 
01772         int z0 = (int) area.origin[2];
01773         z0 = z0 < 0 ? 0 : z0;
01774 
01775         int x1 = (int) (area.origin[0] + area.size[0]);
01776         x1 = x1 > nx ? nx : x1;
01777 
01778         int y1 = (int) (area.origin[1] + area.size[1]);
01779         y1 = y1 > ny ? ny : y1;
01780 
01781         int z1 = (int) (area.origin[2] + area.size[2]);
01782         z1 = z1 > nz ? nz : z1;
01783         if (z1 <= 0) {
01784                 z1 = 1;
01785         }
01786 
01787         int xd0 = (int) (area.origin[0] < 0 ? -area.origin[0] : 0);
01788         int yd0 = (int) (area.origin[1] < 0 ? -area.origin[1] : 0);
01789         int zd0 = (int) (area.origin[2] < 0 ? -area.origin[2] : 0);
01790 
01791         if (x1 < x0 || y1 < y0 || z1 < z0) return; // out of bounds, this is fine, nothing happens
01792 
01793         size_t clipped_row_size = (x1-x0) * sizeof(float);
01794         size_t src_secsize =  (size_t)(nx1 * ny1);
01795         size_t dst_secsize = (size_t)(nx * ny);
01796 
01797 /*
01798 #ifdef EMAN2_USING_CUDA
01799         if(block->cudarwdata){
01800                 // this is VERY slow.....
01801                 float *cudasrc = block->cudarwdata + zd0 * src_secsize + yd0 * nx1 + xd0;
01802                 if(!cudarwdata) rw_alloc();
01803                 float *cudadst = cudarwdata + z0 * dst_secsize + y0 * nx + x0;
01804                 for (int i = z0; i < z1; i++) {
01805                         for (int j = y0; j < y1; j++) {
01806                                 //printf("%x %x %d\n", cudadst, cudasrc, clipped_row_size);
01807                                 cudaMemcpy(cudadst,cudasrc,clipped_row_size,cudaMemcpyDeviceToDevice);
01808                                 cudasrc += nx1;
01809                                 cudadst += nx;
01810                         }
01811                         cudasrc += src_gap;
01812                         cudadst += dst_gap;
01813                 }
01814                 return;
01815         }
01816 #endif
01817 */
01818         float *src = block->get_data() + zd0 * src_secsize + yd0 * nx1 + xd0;
01819         float *dst = get_data() + z0 * dst_secsize + y0 * nx + x0;
01820         
01821         size_t src_gap = src_secsize - (y1-y0) * nx1;
01822         size_t dst_gap = dst_secsize - (y1-y0) * nx;
01823         
01824         for (int i = z0; i < z1; i++) {
01825                 for (int j = y0; j < y1; j++) {
01826                         EMUtil::em_memcpy(dst, src, clipped_row_size);
01827                         src += nx1;
01828                         dst += nx;
01829                 }
01830                 src += src_gap;
01831                 dst += dst_gap;
01832         }
01833         
01834 #ifdef EMAN2_USING_CUDA 
01835         if(block->cudarwdata){
01836                 copy_to_cuda(); // copy back to device as padding is faster on the host
01837         }
01838 #endif
01839 
01840         update();
01841         EXITFUNC;
01842 }

EMData * EMData::make_rotational_footprint ( bool  unwrap = true  )  [inherited]

Makes a 'rotational footprint', which is an 'unwound' autocorrelation function.

generally the image should be edge-normalized and masked before using this.

Parameters:
unwrap RFP undergoes polar->cartesian x-form
Exceptions:
ImageFormatException If image size is not even.
Returns:
The rotaional footprint image.

Definition at line 1762 of file emdata.cpp.

References EMAN::EMData::calc_ccf(), EMAN::CIRCULANT, EMAN::EMData::EMData(), ENTERFUNC, EXITFUNC, EMAN::EMData::get_edge_mean(), EMAN::EMData::rot_fp, EMAN::EMData::sub(), EMAN::EMData::unwrap(), and EMAN::EMData::update_stat().

Referenced by EMAN::RotationalAligner::align_180_ambiguous().

01762                                                       {
01763         ENTERFUNC;
01764         update_stat();
01765         // Note that rotational_footprint caching saves a large amount of time
01766         // but this is at the expense of memory. Note that a policy is hardcoded here,
01767         // that is that caching is only employed when premasked is false and unwrap
01768         // is true - this is probably going to be what is used in most scenarios
01769         // as advised by Steve Ludtke - In terms of performance this caching doubles the metric
01770         // generated by e2speedtest.
01771         if ( rot_fp != 0 && unwrap == true) {
01772                 return new EMData(*rot_fp);
01773         }
01774 
01775         EMData* ccf = this->calc_ccf(this,CIRCULANT,true);
01776         ccf->sub(ccf->get_edge_mean());
01777         //ccf->process_inplace("xform.phaseorigin.tocenter"); ccf did the centering
01778         EMData *result = ccf->unwrap();
01779         delete ccf; ccf = 0;
01780 
01781         EXITFUNC;
01782         if ( unwrap == true)
01783         { // this if statement reflects a strict policy of caching in only one scenario see comments at beginning of function block
01784 
01785 // Note that the if statement at the beginning of this function ensures that rot_fp is not zero, so there is no need
01786 // to throw any exception
01787 // if ( rot_fp != 0 ) throw UnexpectedBehaviorException("The rotational foot print is only expected to be cached if it is not NULL");
01788 
01789 // Here is where the caching occurs - the rot_fp takes ownsherhip of the pointer, and a deep copied EMData object is returned.
01790 // The deep copy invokes a cost in terms of CPU cycles and memory, but prevents the need for complicated memory management (reference counting)
01791                 rot_fp = result;
01792                 return new EMData(*rot_fp);
01793         }
01794         else return result;
01795 }

EMData & EMData::operator= ( const EMData that  )  [inherited]

EMData assignment operator Performs a deep copy.

Parameters:
that the EMData to copy

Definition at line 167 of file emdata.cpp.

References EMAN::EMData::all_translation, EMAN::EMData::attr_dict, EMAN::EMData::changecount, data, EMAN::EMUtil::em_memcpy(), EMAN::EMData::EMData(), ENTERFUNC, EXITFUNC, EMAN::EMData::flags, EMAN::EMData::free_memory(), EMAN::EMData::nx, EMAN::EMData::ny, EMAN::EMData::nz, EMAN::EMData::path, EMAN::EMData::pathnum, EMAN::EMData::rdata, EMAN::EMData::rot_fp, EMAN::EMData::set_size(), UnexpectedBehaviorException, EMAN::EMData::xoff, EMAN::EMData::yoff, and EMAN::EMData::zoff.

00168 {
00169         ENTERFUNC;
00170 
00171         if ( this != &that )
00172         {
00173                 free_memory(); // Free memory sets nx,ny and nz to 0
00174 
00175                 // Only copy the rdata if it exists, we could be in a scenario where only the header has been read
00176                 float* data = that.rdata;
00177                 size_t num_bytes = that.nx*that.ny*that.nz*sizeof(float);
00178                 if (data && num_bytes != 0)
00179                 {
00180                         nx = 1; // This prevents a memset in set_size
00181                         set_size(that.nx,that.ny,that.nz);
00182                         EMUtil::em_memcpy(rdata, data, num_bytes);
00183                 }
00184 
00185                 flags = that.flags;
00186 
00187                 all_translation = that.all_translation;
00188 
00189                 path = that.path;
00190                 pathnum = that.pathnum;
00191                 attr_dict = that.attr_dict;
00192 
00193                 xoff = that.xoff;
00194                 yoff = that.yoff;
00195                 zoff = that.zoff;
00196 
00197 #ifdef EMAN2_USING_CUDA
00198                 if (EMData::usecuda == 1 && num_bytes != 0 && that.cudarwdata != 0) {
00199                         if(cudarwdata){rw_free();}
00200                         if(!rw_alloc()) throw UnexpectedBehaviorException("Bad alloc");;
00201                         cudaError_t error = cudaMemcpy(cudarwdata,that.cudarwdata,num_bytes,cudaMemcpyDeviceToDevice);
00202                         if ( error != cudaSuccess ) throw UnexpectedBehaviorException("cudaMemcpy failed in EMData copy construction with error: " + string(cudaGetErrorString(error)));
00203                 }
00204 #endif //EMAN2_USING_CUDA
00205 
00206                 changecount = that.changecount;
00207 
00208                 if (that.rot_fp != 0) rot_fp = new EMData(*(that.rot_fp));
00209                 else rot_fp = 0;
00210         }
00211         EXITFUNC;
00212         return *this;
00213 }

EMData * EMData::unwrap ( int  r1 = -1,
int  r2 = -1,
int  xs = -1,
int  dx = 0,
int  dy = 0,
bool  do360 = false,
bool  weight_radial = true 
) const [inherited]

Maps to polar coordinates from Cartesian coordinates.

Optionaly radially weighted. When used with RFP, this provides 1 pixel accuracy at 75% radius. 2D only.

Parameters:
r1 inner ring (all rings less than r1 are discarded) Default = 4
r2 outer ring (all rings > r2 are discarded) Default = ny/2 - 2 - floor(hyp(dx,dy))
xs Number of angular bins. Default = (2 if do360) PI * ny/4 - xs % 8
dx origin offset in x
dy origin offest in y
do360 If true, do 0-360 degree mapping. Otherwise, do 0-180 degree mapping.
weight_radial if true (default) reights the pixel value by its radius
Exceptions:
ImageDimensionException If 'this' image is not 2D.
UnexpectedBehaviorException if the dimension of this image and the function arguments are incompatibale - i.e. the return image is less than 0 in some dimension.
Returns:
The image in Cartesian coordinates.

Definition at line 2488 of file emdata.cpp.

References EMAN::Util::bilinear_interpolate(), EMAN::EMData::EMData(), emdata_unwrap(), ENTERFUNC, EXITFUNC, EMAN::Util::fast_floor(), EMAN::EMData::get_const_data(), EMAN::EMData::get_data(), EMAN::EMData::get_ndim(), ImageDimensionException, EMAN::EMData::nx, EMAN::EMData::ny, EMAN::EMData::set_size(), t, UnexpectedBehaviorException, EMAN::EMData::update(), x, and y.

Referenced by EMAN::RTFExhaustiveAligner::align(), EMAN::RotateTranslateFlipAlignerPawel::align(), EMAN::RotateTranslateAlignerPawel::align(), EMAN::RotationalAlignerIterative::align(), EMAN::RotatePrecenterAligner::align(), EMAN::EMData::make_rotational_footprint(), EMAN::EMData::make_rotational_footprint_cmc(), and EMAN::EMData::make_rotational_footprint_e1().

02489 {
02490         ENTERFUNC;
02491 
02492         if (get_ndim() != 2) {
02493                 throw ImageDimensionException("2D image only");
02494         }
02495 
02496         int p = 1;
02497         if (do360) {
02498                 p = 2;
02499         }
02500 
02501         if (xs < 1) {
02502                 xs = (int) Util::fast_floor(p * M_PI * ny / 4);
02503                 xs -= xs % 8;
02504                 if (xs<=8) xs=16;
02505         }
02506 
02507         if (r1 < 0) {
02508                 r1 = 4;
02509         }
02510 
02511 #ifdef  _WIN32
02512         int rr = ny / 2 - 2 - (int) Util::fast_floor(static_cast<float>(_hypot(dx, dy)));
02513 #else
02514         int rr = ny / 2 - 2 - (int) Util::fast_floor(static_cast<float>(hypot(dx, dy)));
02515 #endif  //_WIN32
02516         rr-=rr%2;
02517         if (r2 <= r1 || r2 > rr) {
02518                 r2 = rr;
02519         }
02520 
02521         if ( (r2-r1) < 0 ) throw UnexpectedBehaviorException("The combination of function the arguments and the image dimensions causes unexpected behavior internally. Use a larger image, or a smaller value of r1, or a combination of both");
02522 
02523 #ifdef EMAN2_USING_CUDA
02524         if (EMData::usecuda == 1 && isrodataongpu()){
02525                 //cout << " CUDA unwrap" << endl;
02526                 EMData* result = new EMData(0,0,xs,(r2-r1),1);
02527                 if(!result->rw_alloc()) throw UnexpectedBehaviorException("Bad alloc");
02528                 bindcudaarrayA(true);
02529                 emdata_unwrap(result->cudarwdata, r1, r2, xs, p, dx, dy, weight_radial, nx, ny);
02530                 unbindcudaarryA();
02531                 result->update();
02532                 return result;
02533         }
02534 #endif
02535 
02536         EMData *ret = new EMData();
02537         ret->set_size(xs, r2 - r1, 1);
02538         const float *const d = get_const_data();
02539         float *dd = ret->get_data();
02540         float pfac = (float)p/(float)xs;
02541 
02542         int nxon2 = nx/2;
02543         int nyon2 = ny/2;
02544         for (int x = 0; x < xs; x++) {
02545                 float ang = x * M_PI * pfac;
02546                 float si = sin(ang);
02547                 float co = cos(ang);
02548 
02549                 for (int y = 0; y < r2 - r1; y++) {
02550                         float ypr1 = (float)y + r1;
02551                         float xx = ypr1 * co + nxon2 + dx;
02552                         float yy = ypr1 * si + nyon2 + dy;
02553 //                      float t = xx - Util::fast_floor(xx);
02554 //                      float u = yy - Util::fast_floor(yy);
02555                         float t = xx - (int)xx;
02556                         float u = yy - (int)yy;
02557 //                      int k = (int) Util::fast_floor(xx) + (int) (Util::fast_floor(yy)) * nx;
02558                         int k = (int) xx + ((int) yy) * nx;
02559                         float val = Util::bilinear_interpolate(d[k], d[k + 1], d[k + nx], d[k + nx+1], t,u);
02560                         if (weight_radial) val *=  ypr1;
02561                         dd[x + y * xs] = val;
02562                 }
02563 
02564         }
02565         ret->update();
02566 
02567         EXITFUNC;
02568         return ret;
02569 }


Generated on Thu May 3 10:08:19 2012 for EMAN2 by  doxygen 1.4.7