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