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::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... | |
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). | |
EMData & | EMAN::EMData::operator= (const EMData &that) |
EMData assignment operator Performs a deep copy. | |
EMData * | EMAN::EMData::calc_ccf (EMData *with=0, fp_flag fpflag=CIRCULANT, bool center=false) |
Calculate Cross-Correlation Function (CCF). | |
EMData * | EMAN::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. | |
EMData * | EMAN::EMData::make_rotational_footprint (bool unwrap=true) |
Makes a 'rotational footprint', which is an 'unwound' autocorrelation function. | |
EMData * | EMAN::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. |
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.
[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) |
ImageDimensionException | if nx > 1 and nx < 2*radius + 1 |
Definition at line 1465 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().
01466 { 01467 ENTERFUNC; 01468 01469 if( with == 0 ) { 01470 #ifdef EMAN2_USING_CUDA //CUDA 01471 if(EMData::usecuda == 1 && cudarwdata) { 01472 //cout << "calc ccf" << endl; 01473 EMData* ifft = 0; 01474 bool delifft = false; 01475 int offset = 0; 01476 01477 //do fft if not alreay done 01478 if(!is_complex()){ 01479 ifft = do_fft_cuda(); 01480 delifft = true; 01481 offset = 2 - nx%2; 01482 }else{ 01483 ifft = this; 01484 } 01485 calc_conv_cuda(ifft->cudarwdata,ifft->cudarwdata,nx + offset, ny, nz); //this is the business end, results go in afft 01486 01487 EMData * conv = ifft->do_ift_cuda(); 01488 if(delifft) delete ifft; 01489 conv->update(); 01490 01491 return conv; 01492 } 01493 #endif 01494 EXITFUNC; 01495 return convolution(this,this,fpflag, center); 01496 } 01497 else if ( with == this ){ // this if statement is not necessary, the correlation function tests to see if with == this 01498 EXITFUNC; 01499 return correlation(this, this, fpflag,center); 01500 } 01501 else { 01502 01503 #ifdef EMAN2_USING_CUDA //CUDA 01504 // assume always get rw data (makes life a lot easier!!! 01505 // also assume that both images are the same size. When using CUDA we are only interested in speed, not flexibility!! 01506 // P.S. (I feel like I am pounding square pegs into a round holes with CUDA) 01507 if(EMData::usecuda == 1 && cudarwdata && with->cudarwdata) { 01508 //cout << "using CUDA for ccf" << endl; 01509 EMData* afft = 0; 01510 EMData* bfft = 0; 01511 bool delafft = false, delbfft = false; 01512 int offset = 0; 01513 01514 //do ffts if not alreay done 01515 if(!is_complex()){ 01516 afft = do_fft_cuda(); 01517 delafft = true; 01518 offset = 2 - nx%2; 01519 //cout << "Do cuda FFT A" << endl; 01520 }else{ 01521 afft = this; 01522 } 01523 if(!with->is_complex()){ 01524 bfft = with->do_fft_cuda(); 01525 //cout << "Do cuda FFT B" << endl; 01526 delbfft = true; 01527 }else{ 01528 bfft = with; 01529 } 01530 01531 calc_ccf_cuda(afft->cudarwdata,bfft->cudarwdata,nx + offset, ny, nz); //this is the business end, results go in afft 01532 01533 if(delbfft) delete bfft; 01534 01535 EMData * corr = afft->do_ift_cuda(); 01536 if(delafft) delete afft; 01537 //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. 01538 corr->update(); 01539 01540 return corr; 01541 } 01542 #endif 01543 01544 // If the argument EMData pointer is not the same size we automatically resize it 01545 bool undoresize = false; 01546 int wnx = with->get_xsize(); int wny = with->get_ysize(); int wnz = with->get_zsize(); // obviously is one image is complex and the other real they won't be the same size and we DONT! want to clip JFF 01547 if (!(is_complex() ^ with->is_complex()) && (wnx != nx || wny != ny || wnz != nz)) { 01548 cout << "Warning!!! resizing image before CCF calculation" << endl; 01549 Region r((wnx-nx)/2, (wny-ny)/2, (wnz-nz)/2,nx,ny,nz); 01550 with->clip_inplace(r); 01551 undoresize = true; 01552 } 01553 01554 EMData* cor = correlation(this, with, fpflag, center); 01555 01556 // If the argument EMData pointer was resized, it is returned to its original dimensions 01557 if ( undoresize ) { 01558 Region r((nx-wnx)/2, (ny-wny)/2,(nz-wnz)/2,wnx,wny,wnz); 01559 with->clip_inplace(r); 01560 } 01561 01562 EXITFUNC; 01563 return cor; 01564 } 01565 }
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.
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. |
NullPointerException | If input image 'with' is NULL. | |
ImageFormatException | If 'with' and 'this' are not same size. | |
ImageDimensionException | If 'this' image is 3D. |
Definition at line 1567 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().
01568 { 01569 ENTERFUNC; 01570 01571 if (!with) { 01572 LOGERR("NULL 'with' image. "); 01573 throw NullPointerException("NULL input image"); 01574 } 01575 01576 if (!EMUtil::is_same_size(this, with)) { 01577 LOGERR("images not same size: (%d,%d,%d) != (%d,%d,%d)", 01578 nx, ny, nz, 01579 with->get_xsize(), with->get_ysize(), with->get_zsize()); 01580 throw ImageFormatException("images not same size"); 01581 } 01582 if (get_ndim() > 2) { 01583 LOGERR("2D images only"); 01584 throw ImageDimensionException("2D images only"); 01585 } 01586 01587 if (y1 <= y0) { 01588 y1 = ny; 01589 } 01590 01591 if (y0 >= y1) { 01592 y0 = 0; 01593 } 01594 01595 if (y0 < 0) { 01596 y0 = 0; 01597 } 01598 01599 if (y1 > ny) { 01600 y1 = ny; 01601 } 01602 if (is_complex_x() || with->is_complex_x() ) throw; // Woops don't support this anymore! 01603 01604 static int nx_fft = 0; 01605 static int ny_fft = 0; 01606 static EMData f1; 01607 static EMData f2; 01608 static EMData rslt; 01609 01610 int height = y1-y0; 01611 int width = (nx+2-(nx%2)); 01612 if (width != nx_fft || height != ny_fft ) { 01613 f1.set_size(width,height); 01614 f2.set_size(width,height); 01615 rslt.set_size(nx,height); 01616 nx_fft = width; 01617 ny_fft = height; 01618 } 01619 01620 #ifdef EMAN2_USING_CUDA 01621 if (EMData::usecuda == 1 && cudarwdata && with->cudarwdata) { 01622 //cout << "calc_ccfx CUDA" << endl; 01623 if(!f1.cudarwdata) f1.rw_alloc(); 01624 if(!f2.cudarwdata) f2.rw_alloc(); 01625 if(!rslt.cudarwdata) rslt.rw_alloc(); 01626 cuda_dd_fft_real_to_complex_nd(cudarwdata, f1.cudarwdata, nx, 1, 1, height); 01627 cuda_dd_fft_real_to_complex_nd(with->cudarwdata, f2.cudarwdata, nx, 1, 1, height); 01628 calc_ccf_cuda(f1.cudarwdata, f2.cudarwdata, nx, ny, nz); 01629 cuda_dd_fft_complex_to_real_nd(f1.cudarwdata, rslt.cudarwdata, nx, 1, 1, height); 01630 if(no_sum){ 01631 EMData* result = new EMData(rslt); 01632 return result; 01633 } 01634 EMData* cf = new EMData(0,0,nx,1,1); //cuda constructor 01635 cf->runcuda(emdata_column_sum(rslt.cudarwdata, nx, ny)); 01636 cf->update(); 01637 01638 EXITFUNC; 01639 return cf; 01640 } 01641 #endif 01642 01643 float *d1 = get_data(); 01644 float *d2 = with->get_data(); 01645 float *f1d = f1.get_data(); 01646 float *f2d = f2.get_data(); 01647 for (int j = 0; j < height; j++) { 01648 EMfft::real_to_complex_1d(d1 + j * nx, f1d+j*width, nx); 01649 EMfft::real_to_complex_1d(d2 + j * nx, f2d+j*width, nx); 01650 } 01651 01652 if(flip == false) { 01653 for (int j = 0; j < height; j++) { 01654 float *f1a = f1d + j * width; 01655 float *f2a = f2d + j * width; 01656 01657 for (int i = 0; i < width / 2; i++) { 01658 float re1 = f1a[2*i]; 01659 float re2 = f2a[2*i]; 01660 float im1 = f1a[2*i+1]; 01661 float im2 = f2a[2*i+1]; 01662 01663 f1d[j*width+i*2] = re1 * re2 + im1 * im2; 01664 f1d[j*width+i*2+1] = im1 * re2 - re1 * im2; 01665 } 01666 } 01667 } else { 01668 for (int j = 0; j < height; j++) { 01669 float *f1a = f1d + j * width; 01670 float *f2a = f2d + j * width; 01671 01672 for (int i = 0; i < width / 2; i++) { 01673 float re1 = f1a[2*i]; 01674 float re2 = f2a[2*i]; 01675 float im1 = f1a[2*i+1]; 01676 float im2 = f2a[2*i+1]; 01677 01678 f1d[j*width+i*2] = re1 * re2 - im1 * im2; 01679 f1d[j*width+i*2+1] = im1 * re2 + re1 * im2; 01680 } 01681 } 01682 } 01683 01684 float* rd = rslt.get_data(); 01685 for (int j = y0; j < y1; j++) { 01686 EMfft::complex_to_real_1d(f1d+j*width, rd+j*nx, nx); 01687 } 01688 01689 if (no_sum) { 01690 rslt.update(); // This is important in terms of the copy - the returned object won't have the correct flags unless we do this 01691 EXITFUNC; 01692 return new EMData(rslt); 01693 } else { 01694 EMData *cf = new EMData(nx,1,1); 01695 cf->to_zero(); 01696 float *c = cf->get_data(); 01697 for (int j = 0; j < height; j++) { 01698 for(int i = 0; i < nx; ++i) { 01699 c[i] += rd[i+j*nx]; 01700 } 01701 } 01702 cf->update(); 01703 EXITFUNC; 01704 return cf; 01705 } 01706 }
EMData::EMData | ( | const EMData & | that | ) | [inherited] |
Construct from an EMData (copy constructor).
Performs a deep copy
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), 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!
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.
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 216 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().
00216 : 00217 #ifdef EMAN2_USING_CUDA 00218 cudarwdata(0), cudarodata(0), num_bytes(0), nextlistitem(0), prevlistitem(0), roneedsupdate(0), 00219 #endif //EMAN2_USING_CUDA 00220 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), 00221 all_translation(), path(""), pathnum(0), rot_fp(0) 00222 { 00223 ENTERFUNC; 00224 00225 // used to replace cube 'pixel' 00226 attr_dict["apix_x"] = 1.0f; 00227 attr_dict["apix_y"] = 1.0f; 00228 attr_dict["apix_z"] = 1.0f; 00229 00230 if(is_real) { // create a real image [nx, ny, nz] 00231 attr_dict["is_complex"] = int(0); 00232 attr_dict["is_complex_x"] = int(0); 00233 attr_dict["is_complex_ri"] = int(1); 00234 set_size(nx, ny, nz); 00235 } 00236 else { //create a complex image which real dimension is [ny, ny, nz] 00237 int new_nx = nx + 2 - nx%2; 00238 set_size(new_nx, ny, nz); 00239 00240 attr_dict["is_complex"] = int(1); 00241 00242 if(ny==1 && nz ==1) { 00243 attr_dict["is_complex_x"] = int(1); 00244 } 00245 else { 00246 attr_dict["is_complex_x"] = int(0); 00247 } 00248 00249 attr_dict["is_complex_ri"] = int(1); 00250 attr_dict["is_fftpad"] = int(1); 00251 00252 if(nx%2 == 1) { 00253 attr_dict["is_fftodd"] = 1; 00254 } 00255 } 00256 00257 this->to_zero(); 00258 update(); 00259 EMData::totalalloc++; 00260 #ifdef MEMDEBUG2 00261 printf("EMDATA+ %4d %p\n",EMData::totalalloc,this); 00262 #endif 00263 00264 EXITFUNC; 00265 }
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
block | An image block. | |
origin | The origin location to insert the clip. ( ) |
Insert a clip into this image.
Very robust clip insertion code works in all way you might think possible
block | An image block. | |
origin | The origin location to insert the clip. ( ) |
Definition at line 1787 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().
01787 { 01788 int nx1 = block->get_xsize(); 01789 int ny1 = block->get_ysize(); 01790 int nz1 = block->get_zsize(); 01791 01792 Region area(origin[0], origin[1], origin[2],nx1, ny1, nz1); 01793 01794 //make sure the block fits in EMData 01795 int x0 = (int) area.origin[0]; 01796 x0 = x0 < 0 ? 0 : x0; 01797 01798 int y0 = (int) area.origin[1]; 01799 y0 = y0 < 0 ? 0 : y0; 01800 01801 int z0 = (int) area.origin[2]; 01802 z0 = z0 < 0 ? 0 : z0; 01803 01804 int x1 = (int) (area.origin[0] + area.size[0]); 01805 x1 = x1 > nx ? nx : x1; 01806 01807 int y1 = (int) (area.origin[1] + area.size[1]); 01808 y1 = y1 > ny ? ny : y1; 01809 01810 int z1 = (int) (area.origin[2] + area.size[2]); 01811 z1 = z1 > nz ? nz : z1; 01812 if (z1 <= 0) { 01813 z1 = 1; 01814 } 01815 01816 int xd0 = (int) (area.origin[0] < 0 ? -area.origin[0] : 0); 01817 int yd0 = (int) (area.origin[1] < 0 ? -area.origin[1] : 0); 01818 int zd0 = (int) (area.origin[2] < 0 ? -area.origin[2] : 0); 01819 01820 if (x1 < x0 || y1 < y0 || z1 < z0) return; // out of bounds, this is fine, nothing happens 01821 01822 size_t clipped_row_size = (x1-x0) * sizeof(float); 01823 int src_secsize = nx1 * ny1; 01824 int dst_secsize = nx * ny; 01825 01826 /* 01827 #ifdef EMAN2_USING_CUDA 01828 if(block->cudarwdata){ 01829 // this is VERY slow..... 01830 float *cudasrc = block->cudarwdata + zd0 * src_secsize + yd0 * nx1 + xd0; 01831 if(!cudarwdata) rw_alloc(); 01832 float *cudadst = cudarwdata + z0 * dst_secsize + y0 * nx + x0; 01833 for (int i = z0; i < z1; i++) { 01834 for (int j = y0; j < y1; j++) { 01835 //printf("%x %x %d\n", cudadst, cudasrc, clipped_row_size); 01836 cudaMemcpy(cudadst,cudasrc,clipped_row_size,cudaMemcpyDeviceToDevice); 01837 cudasrc += nx1; 01838 cudadst += nx; 01839 } 01840 cudasrc += src_gap; 01841 cudadst += dst_gap; 01842 } 01843 return; 01844 } 01845 #endif 01846 */ 01847 float *src = block->get_data() + zd0 * src_secsize + yd0 * nx1 + xd0; 01848 float *dst = get_data() + z0 * dst_secsize + y0 * nx + x0; 01849 01850 int src_gap = src_secsize - (y1-y0) * nx1; 01851 int dst_gap = dst_secsize - (y1-y0) * nx; 01852 01853 for (int i = z0; i < z1; i++) { 01854 for (int j = y0; j < y1; j++) { 01855 EMUtil::em_memcpy(dst, src, clipped_row_size); 01856 src += nx1; 01857 dst += nx; 01858 } 01859 src += src_gap; 01860 dst += dst_gap; 01861 } 01862 01863 #ifdef EMAN2_USING_CUDA 01864 if(block->cudarwdata){ 01865 copy_to_cuda(); // copy back to device as padding is faster on the host 01866 } 01867 #endif 01868 01869 update(); 01870 EXITFUNC; 01871 }
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.
unwrap | RFP undergoes polar->cartesian x-form |
ImageFormatException | If image size is not even. |
Definition at line 1760 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().
01760 { 01761 ENTERFUNC; 01762 update_stat(); 01763 // Note that rotational_footprint caching saves a large amount of time 01764 // but this is at the expense of memory. Note that a policy is hardcoded here, 01765 // that is that caching is only employed when premasked is false and unwrap 01766 // is true - this is probably going to be what is used in most scenarios 01767 // as advised by Steve Ludtke - In terms of performance this caching doubles the metric 01768 // generated by e2speedtest. 01769 if ( rot_fp != 0 && unwrap == true) { 01770 return new EMData(*rot_fp); 01771 } 01772 01773 EMData* ccf = this->calc_ccf(this,CIRCULANT,true); 01774 ccf->sub(ccf->get_edge_mean()); 01775 //ccf->process_inplace("xform.phaseorigin.tocenter"); ccf did the centering 01776 EMData *result = ccf->unwrap(); 01777 delete ccf; ccf = 0; 01778 01779 EXITFUNC; 01780 if ( unwrap == true) 01781 { // this if statement reflects a strict policy of caching in only one scenario see comments at beginning of function block 01782 01783 // Note that the if statement at the beginning of this function ensures that rot_fp is not zero, so there is no need 01784 // to throw any exception 01785 // if ( rot_fp != 0 ) throw UnexpectedBehaviorException("The rotational foot print is only expected to be cached if it is not NULL"); 01786 01787 // Here is where the caching occurs - the rot_fp takes ownsherhip of the pointer, and a deep copied EMData object is returned. 01788 // The deep copy invokes a cost in terms of CPU cycles and memory, but prevents the need for complicated memory management (reference counting) 01789 rot_fp = result; 01790 return new EMData(*rot_fp); 01791 } 01792 else return result; 01793 }
EMData assignment operator Performs a deep copy.
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 } 00205 #endif //EMAN2_USING_CUDA 00206 00207 changecount = that.changecount; 00208 00209 if (that.rot_fp != 0) rot_fp = new EMData(*(that.rot_fp)); 00210 else rot_fp = 0; 00211 } 00212 EXITFUNC; 00213 return *this; 00214 }
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.
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 |
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. |
Definition at line 2482 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().
02483 { 02484 ENTERFUNC; 02485 02486 if (get_ndim() != 2) { 02487 throw ImageDimensionException("2D image only"); 02488 } 02489 02490 int p = 1; 02491 if (do360) { 02492 p = 2; 02493 } 02494 02495 if (xs < 1) { 02496 xs = (int) Util::fast_floor(p * M_PI * ny / 4); 02497 xs -= xs % 8; 02498 if (xs<=8) xs=16; 02499 } 02500 02501 if (r1 < 0) { 02502 r1 = 4; 02503 } 02504 02505 #ifdef _WIN32 02506 int rr = ny / 2 - 2 - (int) Util::fast_floor(static_cast<float>(_hypot(dx, dy))); 02507 #else 02508 int rr = ny / 2 - 2 - (int) Util::fast_floor(static_cast<float>(hypot(dx, dy))); 02509 #endif //_WIN32 02510 rr-=rr%2; 02511 if (r2 <= r1 || r2 > rr) { 02512 r2 = rr; 02513 } 02514 02515 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"); 02516 02517 #ifdef EMAN2_USING_CUDA 02518 if (EMData::usecuda == 1 && isrodataongpu()){ 02519 //cout << " CUDA unwrap" << endl; 02520 EMData* result = new EMData(0,0,xs,(r2-r1),1); 02521 if(!result->rw_alloc()) throw UnexpectedBehaviorException("Bad alloc"); 02522 bindcudaarrayA(true); 02523 emdata_unwrap(result->cudarwdata, r1, r2, xs, p, dx, dy, weight_radial, nx, ny); 02524 unbindcudaarryA(); 02525 result->update(); 02526 return result; 02527 } 02528 #endif 02529 02530 EMData *ret = new EMData(); 02531 ret->set_size(xs, r2 - r1, 1); 02532 const float *const d = get_const_data(); 02533 float *dd = ret->get_data(); 02534 float pfac = (float)p/(float)xs; 02535 02536 int nxon2 = nx/2; 02537 int nyon2 = ny/2; 02538 for (int x = 0; x < xs; x++) { 02539 float ang = x * M_PI * pfac; 02540 float si = sin(ang); 02541 float co = cos(ang); 02542 02543 for (int y = 0; y < r2 - r1; y++) { 02544 float ypr1 = (float)y + r1; 02545 float xx = ypr1 * co + nxon2 + dx; 02546 float yy = ypr1 * si + nyon2 + dy; 02547 // float t = xx - Util::fast_floor(xx); 02548 // float u = yy - Util::fast_floor(yy); 02549 float t = xx - (int)xx; 02550 float u = yy - (int)yy; 02551 // int k = (int) Util::fast_floor(xx) + (int) (Util::fast_floor(yy)) * nx; 02552 int k = (int) xx + ((int) yy) * nx; 02553 float val = Util::bilinear_interpolate(d[k], d[k + 1], d[k + nx], d[k + nx+1], t,u); 02554 if (weight_radial) val *= ypr1; 02555 dd[x + y * xs] = val; 02556 } 02557 02558 } 02559 ret->update(); 02560 02561 EXITFUNC; 02562 return ret; 02563 }