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 }
|
1.3.9.1