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). | |
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, bool usez=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 1469 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().
01470 { 01471 ENTERFUNC; 01472 01473 if( with == 0 ) { 01474 #ifdef EMAN2_USING_CUDA //CUDA 01475 if(EMData::usecuda == 1 && cudarwdata) { 01476 //cout << "calc ccf" << endl; 01477 EMData* ifft = 0; 01478 bool delifft = false; 01479 int offset = 0; 01480 01481 //do fft if not alreay done 01482 if(!is_complex()){ 01483 ifft = do_fft_cuda(); 01484 delifft = true; 01485 offset = 2 - nx%2; 01486 }else{ 01487 ifft = this; 01488 } 01489 calc_conv_cuda(ifft->cudarwdata,ifft->cudarwdata,nx + offset, ny, nz); //this is the business end, results go in afft 01490 01491 EMData * conv = ifft->do_ift_cuda(); 01492 if(delifft) delete ifft; 01493 conv->update(); 01494 01495 return conv; 01496 } 01497 #endif 01498 EXITFUNC; 01499 return convolution(this,this,fpflag, center); 01500 } 01501 else if ( with == this ){ // this if statement is not necessary, the correlation function tests to see if with == this 01502 EXITFUNC; 01503 return correlation(this, this, fpflag,center); 01504 } 01505 else { 01506 01507 #ifdef EMAN2_USING_CUDA //CUDA 01508 // assume always get rw data (makes life a lot easier!!! 01509 // also assume that both images are the same size. When using CUDA we are only interested in speed, not flexibility!! 01510 // P.S. (I feel like I am pounding square pegs into a round holes with CUDA) 01511 if(EMData::usecuda == 1 && cudarwdata && with->cudarwdata) { 01512 //cout << "using CUDA for ccf" << endl; 01513 EMData* afft = 0; 01514 EMData* bfft = 0; 01515 bool delafft = false, delbfft = false; 01516 int offset = 0; 01517 01518 //do ffts if not alreay done 01519 if(!is_complex()){ 01520 afft = do_fft_cuda(); 01521 delafft = true; 01522 offset = 2 - nx%2; 01523 //cout << "Do cuda FFT A" << endl; 01524 }else{ 01525 afft = this; 01526 } 01527 if(!with->is_complex()){ 01528 bfft = with->do_fft_cuda(); 01529 //cout << "Do cuda FFT B" << endl; 01530 delbfft = true; 01531 }else{ 01532 bfft = with; 01533 } 01534 01535 calc_ccf_cuda(afft->cudarwdata,bfft->cudarwdata,nx + offset, ny, nz); //this is the business end, results go in afft 01536 01537 if(delbfft) delete bfft; 01538 01539 EMData * corr = afft->do_ift_cuda(); 01540 if(delafft) delete afft; 01541 //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. 01542 corr->update(); 01543 01544 return corr; 01545 } 01546 #endif 01547 01548 // If the argument EMData pointer is not the same size we automatically resize it 01549 bool undoresize = false; 01550 int wnx = with->get_xsize(); int wny = with->get_ysize(); int wnz = with->get_zsize(); 01551 if (!(is_complex()^with->is_complex()) && (wnx != nx || wny != ny || wnz != nz) ) { 01552 Region r((wnx-nx)/2, (wny-ny)/2, (wnz-nz)/2,nx,ny,nz); 01553 with->clip_inplace(r); 01554 undoresize = true; 01555 } 01556 01557 EMData* cor = correlation(this, with, fpflag, center); 01558 01559 // If the argument EMData pointer was resized, it is returned to its original dimensions 01560 if ( undoresize ) { 01561 Region r((nx-wnx)/2, (ny-wny)/2,(nz-wnz)/2,wnx,wny,wnz); 01562 with->clip_inplace(r); 01563 } 01564 01565 EXITFUNC; 01566 return cor; 01567 } 01568 }
EMData * EMData::calc_ccfx | ( | EMData *const | with, | |
int | y0 = 0 , |
|||
int | y1 = -1 , |
|||
bool | nosum = false , |
|||
bool | flip = false , |
|||
bool | usez = 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. | |
usez | If true, will convert each line in the CCF stack to a Z value, indicating its relative strength as a predictor of alignment |
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 1570 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(), sqrt(), EMAN::EMData::to_zero(), EMAN::EMData::update(), x, and y.
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().
01571 { 01572 ENTERFUNC; 01573 01574 if (!with) { 01575 LOGERR("NULL 'with' image. "); 01576 throw NullPointerException("NULL input image"); 01577 } 01578 01579 if (!EMUtil::is_same_size(this, with)) { 01580 LOGERR("images not same size: (%d,%d,%d) != (%d,%d,%d)", 01581 nx, ny, nz, 01582 with->get_xsize(), with->get_ysize(), with->get_zsize()); 01583 throw ImageFormatException("images not same size"); 01584 } 01585 if (get_ndim() > 2) { 01586 LOGERR("2D images only"); 01587 throw ImageDimensionException("2D images only"); 01588 } 01589 01590 if (y1 <= y0) { 01591 y1 = ny; 01592 } 01593 01594 if (y0 >= y1) { 01595 y0 = 0; 01596 } 01597 01598 if (y0 < 0) { 01599 y0 = 0; 01600 } 01601 01602 if (y1 > ny) { 01603 y1 = ny; 01604 } 01605 if (is_complex_x() || with->is_complex_x() ) throw; // Woops don't support this anymore! 01606 01607 static int nx_fft = 0; 01608 static int ny_fft = 0; 01609 static EMData f1; 01610 static EMData f2; 01611 static EMData rslt; 01612 01613 int height = y1-y0; 01614 int width = (nx+2-(nx%2)); 01615 int wpad = ((width+3)/4)*4; // This is for 128 bit alignment of rows to prevent SSE crashes 01616 if (wpad != nx_fft || height != ny_fft ) { // Seems meaningless, but due to static definitions above. f1,f2 are cached to prevent multiple reallocations 01617 f1.set_size(wpad,height); 01618 f2.set_size(wpad,height); 01619 rslt.set_size(nx,height); 01620 nx_fft = wpad; 01621 ny_fft = height; 01622 } 01623 01624 #ifdef EMAN2_USING_CUDA 01625 // FIXME : Not tested with new wpad change 01626 if (EMData::usecuda == 1 && cudarwdata && with->cudarwdata) { 01627 //cout << "calc_ccfx CUDA" << endl; 01628 if(!f1.cudarwdata) f1.rw_alloc(); 01629 if(!f2.cudarwdata) f2.rw_alloc(); 01630 if(!rslt.cudarwdata) rslt.rw_alloc(); 01631 cuda_dd_fft_real_to_complex_nd(cudarwdata, f1.cudarwdata, nx, 1, 1, height); 01632 cuda_dd_fft_real_to_complex_nd(with->cudarwdata, f2.cudarwdata, nx, 1, 1, height); 01633 calc_ccf_cuda(f1.cudarwdata, f2.cudarwdata, nx, ny, nz); 01634 cuda_dd_fft_complex_to_real_nd(f1.cudarwdata, rslt.cudarwdata, nx, 1, 1, height); 01635 if(no_sum){ 01636 EMData* result = new EMData(rslt); 01637 return result; 01638 } 01639 EMData* cf = new EMData(0,0,nx,1,1); //cuda constructor 01640 cf->runcuda(emdata_column_sum(rslt.cudarwdata, nx, ny)); 01641 cf->update(); 01642 01643 EXITFUNC; 01644 return cf; 01645 } 01646 #endif 01647 01648 // printf("%d %d %d\n",(int)get_attr("nx"),(int)f2.get_attr("nx"),width); 01649 01650 float *d1 = get_data(); 01651 float *d2 = with->get_data(); 01652 float *f1d = f1.get_data(); 01653 float *f2d = f2.get_data(); 01654 for (int j = 0; j < height; j++) { 01655 EMfft::real_to_complex_1d(d1 + j * nx, f1d+j*wpad, nx); 01656 EMfft::real_to_complex_1d(d2 + j * nx, f2d+j*wpad, nx); 01657 } 01658 01659 if(flip == false) { 01660 for (int j = 0; j < height; j++) { 01661 float *f1a = f1d + j * wpad; 01662 float *f2a = f2d + j * wpad; 01663 01664 for (int i = 0; i < width / 2; i++) { 01665 float re1 = f1a[2*i]; 01666 float re2 = f2a[2*i]; 01667 float im1 = f1a[2*i+1]; 01668 float im2 = f2a[2*i+1]; 01669 01670 f1d[j*wpad+i*2] = re1 * re2 + im1 * im2; 01671 f1d[j*wpad+i*2+1] = im1 * re2 - re1 * im2; 01672 } 01673 } 01674 } else { 01675 for (int j = 0; j < height; j++) { 01676 float *f1a = f1d + j * wpad; 01677 float *f2a = f2d + j * wpad; 01678 01679 for (int i = 0; i < width / 2; i++) { 01680 float re1 = f1a[2*i]; 01681 float re2 = f2a[2*i]; 01682 float im1 = f1a[2*i+1]; 01683 float im2 = f2a[2*i+1]; 01684 01685 f1d[j*wpad+i*2] = re1 * re2 - im1 * im2; 01686 f1d[j*wpad+i*2+1] = im1 * re2 + re1 * im2; 01687 } 01688 } 01689 } 01690 01691 float* rd = rslt.get_data(); 01692 for (int j = y0; j < y1; j++) { 01693 EMfft::complex_to_real_1d(f1d+j*wpad, rd+j*nx, nx); 01694 } 01695 01696 // This converts the CCF values to Z values (in terms of standard deviations above the mean), on a per-row basis 01697 // The theory is that this should better weight the radii that contribute most strongly to the orientation determination 01698 if (usez) { 01699 for (int y=0; y<height; y++) { 01700 float mn=0,sg=0; 01701 for (int x=0; x<nx; x++) { 01702 mn+=rd[x+y*nx]; 01703 sg+=rd[x+y*nx]*rd[x+y*nx]; 01704 } 01705 mn/=(float)nx; //mean 01706 sg=std::sqrt(sg/(float)nx-mn*mn); //sigma 01707 01708 for (int x=0; x<nx; x++) rd[x+y*nx]=(rd[x+y*nx]-mn)/sg; 01709 } 01710 } 01711 01712 if (no_sum) { 01713 rslt.update(); // This is important in terms of the copy - the returned object won't have the correct flags unless we do this 01714 EXITFUNC; 01715 return new EMData(rslt); 01716 } else { 01717 EMData *cf = new EMData(nx,1,1); 01718 cf->to_zero(); 01719 float *c = cf->get_data(); 01720 for (int j = 0; j < height; j++) { 01721 for(int i = 0; i < nx; ++i) { 01722 c[i] += rd[i+j*nx]; 01723 } 01724 } 01725 cf->update(); 01726 EXITFUNC; 01727 return cf; 01728 } 01729 }
EMData::EMData | ( | const EMData & | that | ) | [inherited] |
Construct from an EMData (copy constructor).
Performs a deep copy
that | the EMData to copy |
Definition at line 132 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.
00132 : 00133 #ifdef EMAN2_USING_CUDA 00134 cudarwdata(0), cudarodata(0), num_bytes(0), nextlistitem(0), prevlistitem(0), roneedsupdate(0), cudadirtybit(0), 00135 #endif //EMAN2_USING_CUDA 00136 attr_dict(that.attr_dict), rdata(0), supp(0), flags(that.flags), changecount(that.changecount), nx(that.nx), ny(that.ny), nz(that.nz), 00137 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), 00138 pathnum(that.pathnum), rot_fp(0) 00139 { 00140 ENTERFUNC; 00141 00142 float* data = that.rdata; 00143 size_t num_bytes = (size_t)nx*ny*nz*sizeof(float); 00144 if (data && num_bytes != 0) 00145 { 00146 rdata = (float*)EMUtil::em_malloc(num_bytes); 00147 EMUtil::em_memcpy(rdata, data, num_bytes); 00148 } 00149 #ifdef EMAN2_USING_CUDA 00150 if (EMData::usecuda == 1 && num_bytes != 0 && that.cudarwdata != 0) { 00151 //cout << "That copy constructor" << endl; 00152 if(!rw_alloc()) throw UnexpectedBehaviorException("Bad alloc"); 00153 cudaError_t error = cudaMemcpy(cudarwdata,that.cudarwdata,num_bytes,cudaMemcpyDeviceToDevice); 00154 if ( error != cudaSuccess ) throw UnexpectedBehaviorException("cudaMemcpy failed in EMData copy construction with error: " + string(cudaGetErrorString(error))); 00155 } 00156 #endif //EMAN2_USING_CUDA 00157 00158 if (that.rot_fp != 0) rot_fp = new EMData(*(that.rot_fp)); 00159 00160 EMData::totalalloc++; 00161 #ifdef MEMDEBUG2 00162 printf("EMDATA+ %4d %p\n",EMData::totalalloc,this); 00163 #endif 00164 00165 ENTERFUNC; 00166 }
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), cudadirtybit(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 1755 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().
01755 { 01756 int nx1 = block->get_xsize(); 01757 int ny1 = block->get_ysize(); 01758 int nz1 = block->get_zsize(); 01759 01760 Region area(origin[0], origin[1], origin[2],nx1, ny1, nz1); 01761 01762 //make sure the block fits in EMData 01763 int x0 = (int) area.origin[0]; 01764 x0 = x0 < 0 ? 0 : x0; 01765 01766 int y0 = (int) area.origin[1]; 01767 y0 = y0 < 0 ? 0 : y0; 01768 01769 int z0 = (int) area.origin[2]; 01770 z0 = z0 < 0 ? 0 : z0; 01771 01772 int x1 = (int) (area.origin[0] + area.size[0]); 01773 x1 = x1 > nx ? nx : x1; 01774 01775 int y1 = (int) (area.origin[1] + area.size[1]); 01776 y1 = y1 > ny ? ny : y1; 01777 01778 int z1 = (int) (area.origin[2] + area.size[2]); 01779 z1 = z1 > nz ? nz : z1; 01780 if (z1 <= 0) { 01781 z1 = 1; 01782 } 01783 01784 int xd0 = (int) (area.origin[0] < 0 ? -area.origin[0] : 0); 01785 int yd0 = (int) (area.origin[1] < 0 ? -area.origin[1] : 0); 01786 int zd0 = (int) (area.origin[2] < 0 ? -area.origin[2] : 0); 01787 01788 if (x1 < x0 || y1 < y0 || z1 < z0) return; // out of bounds, this is fine, nothing happens 01789 01790 size_t clipped_row_size = (x1-x0) * sizeof(float); 01791 size_t src_secsize = (size_t)(nx1 * ny1); 01792 size_t dst_secsize = (size_t)(nx * ny); 01793 01794 /* 01795 #ifdef EMAN2_USING_CUDA 01796 if(block->cudarwdata){ 01797 // this is VERY slow..... 01798 float *cudasrc = block->cudarwdata + zd0 * src_secsize + yd0 * nx1 + xd0; 01799 if(!cudarwdata) rw_alloc(); 01800 float *cudadst = cudarwdata + z0 * dst_secsize + y0 * nx + x0; 01801 for (int i = z0; i < z1; i++) { 01802 for (int j = y0; j < y1; j++) { 01803 //printf("%x %x %d\n", cudadst, cudasrc, clipped_row_size); 01804 cudaMemcpy(cudadst,cudasrc,clipped_row_size,cudaMemcpyDeviceToDevice); 01805 cudasrc += nx1; 01806 cudadst += nx; 01807 } 01808 cudasrc += src_gap; 01809 cudadst += dst_gap; 01810 } 01811 return; 01812 } 01813 #endif 01814 */ 01815 float *src = block->get_data() + zd0 * src_secsize + yd0 * nx1 + xd0; 01816 float *dst = get_data() + z0 * dst_secsize + y0 * nx + x0; 01817 01818 size_t src_gap = src_secsize - (y1-y0) * nx1; 01819 size_t dst_gap = dst_secsize - (y1-y0) * nx; 01820 01821 for (int i = z0; i < z1; i++) { 01822 for (int j = y0; j < y1; j++) { 01823 EMUtil::em_memcpy(dst, src, clipped_row_size); 01824 src += nx1; 01825 dst += nx; 01826 } 01827 src += src_gap; 01828 dst += dst_gap; 01829 } 01830 01831 #ifdef EMAN2_USING_CUDA 01832 if(block->cudarwdata){ 01833 copy_to_cuda(); // copy back to device as padding is faster on the host 01834 } 01835 #endif 01836 01837 update(); 01838 EXITFUNC; 01839 }
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 1783 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().
01783 { 01784 ENTERFUNC; 01785 update_stat(); 01786 // Note that rotational_footprint caching saves a large amount of time 01787 // but this is at the expense of memory. Note that a policy is hardcoded here, 01788 // that is that caching is only employed when premasked is false and unwrap 01789 // is true - this is probably going to be what is used in most scenarios 01790 // as advised by Steve Ludtke - In terms of performance this caching doubles the metric 01791 // generated by e2speedtest. 01792 if ( rot_fp != 0 && unwrap == true) { 01793 return new EMData(*rot_fp); 01794 } 01795 01796 EMData* ccf = this->calc_ccf(this,CIRCULANT,true); 01797 // EMData* ccf = this->calc_ccf(this,PADDED,true); # this would probably be a bit better, but takes 4x longer :^/ 01798 ccf->sub(ccf->get_edge_mean()); 01799 //ccf->process_inplace("xform.phaseorigin.tocenter"); ccf did the centering 01800 EMData *result = ccf->unwrap(); 01801 delete ccf; ccf = 0; 01802 01803 EXITFUNC; 01804 if ( unwrap == true) 01805 { // this if statement reflects a strict policy of caching in only one scenario see comments at beginning of function block 01806 01807 // Note that the if statement at the beginning of this function ensures that rot_fp is not zero, so there is no need 01808 // to throw any exception 01809 // if ( rot_fp != 0 ) throw UnexpectedBehaviorException("The rotational foot print is only expected to be cached if it is not NULL"); 01810 01811 // Here is where the caching occurs - the rot_fp takes ownsherhip of the pointer, and a deep copied EMData object is returned. 01812 // The deep copy invokes a cost in terms of CPU cycles and memory, but prevents the need for complicated memory management (reference counting) 01813 rot_fp = result; 01814 return new EMData(*rot_fp); 01815 } 01816 else return result; 01817 }
EMData assignment operator Performs a deep copy.
that | the EMData to copy |
Definition at line 168 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.
00169 { 00170 ENTERFUNC; 00171 00172 if ( this != &that ) 00173 { 00174 free_memory(); // Free memory sets nx,ny and nz to 0 00175 00176 // Only copy the rdata if it exists, we could be in a scenario where only the header has been read 00177 float* data = that.rdata; 00178 size_t num_bytes = that.nx*that.ny*that.nz*sizeof(float); 00179 if (data && num_bytes != 0) 00180 { 00181 nx = 1; // This prevents a memset in set_size 00182 set_size(that.nx,that.ny,that.nz); 00183 EMUtil::em_memcpy(rdata, data, num_bytes); 00184 } 00185 00186 flags = that.flags; 00187 00188 all_translation = that.all_translation; 00189 00190 path = that.path; 00191 pathnum = that.pathnum; 00192 attr_dict = that.attr_dict; 00193 00194 xoff = that.xoff; 00195 yoff = that.yoff; 00196 zoff = that.zoff; 00197 00198 #ifdef EMAN2_USING_CUDA 00199 if (EMData::usecuda == 1 && num_bytes != 0 && that.cudarwdata != 0) { 00200 if(cudarwdata){rw_free();} 00201 if(!rw_alloc()) throw UnexpectedBehaviorException("Bad alloc");; 00202 cudaError_t error = cudaMemcpy(cudarwdata,that.cudarwdata,num_bytes,cudaMemcpyDeviceToDevice); 00203 if ( error != cudaSuccess ) throw UnexpectedBehaviorException("cudaMemcpy failed in EMData copy construction with error: " + string(cudaGetErrorString(error))); 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 roughly 1 pixel accuracy at 50% 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 2510 of file emdata.cpp.
References EMAN::Util::bilinear_interpolate(), EMAN::Util::calc_best_fft_size(), 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().
02511 { 02512 ENTERFUNC; 02513 02514 if (get_ndim() != 2) { 02515 throw ImageDimensionException("2D image only"); 02516 } 02517 02518 int p = 1; 02519 if (do360) { 02520 p = 2; 02521 } 02522 02523 if (xs < 1) { 02524 xs = (int) Util::fast_floor(p * M_PI * ny / 3.0); 02525 xs-=xs%4; // 128 bit alignment, though best_fft_size may override 02526 xs = Util::calc_best_fft_size(xs); 02527 if (xs<=8) xs=16; 02528 } 02529 02530 if (r1 < 0) { 02531 r1 = 4; 02532 } 02533 02534 #ifdef _WIN32 02535 int rr = ny / 2 - 2 - (int) Util::fast_floor(static_cast<float>(_hypot(dx, dy))); 02536 #else 02537 int rr = ny / 2 - 2 - (int) Util::fast_floor(static_cast<float>(hypot(dx, dy))); 02538 #endif //_WIN32 02539 rr-=rr%2; 02540 if (r2 <= r1 || r2 > rr) { 02541 r2 = rr; 02542 } 02543 02544 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"); 02545 02546 #ifdef EMAN2_USING_CUDA 02547 if (EMData::usecuda == 1 && isrodataongpu()){ 02548 //cout << " CUDA unwrap" << endl; 02549 EMData* result = new EMData(0,0,xs,(r2-r1),1); 02550 if(!result->rw_alloc()) throw UnexpectedBehaviorException("Bad alloc"); 02551 bindcudaarrayA(true); 02552 emdata_unwrap(result->cudarwdata, r1, r2, xs, p, dx, dy, weight_radial, nx, ny); 02553 unbindcudaarryA(); 02554 result->update(); 02555 return result; 02556 } 02557 #endif 02558 02559 EMData *ret = new EMData(); 02560 ret->set_size(xs, r2 - r1, 1); 02561 const float *const d = get_const_data(); 02562 float *dd = ret->get_data(); 02563 float pfac = (float)p/(float)xs; 02564 02565 int nxon2 = nx/2; 02566 int nyon2 = ny/2; 02567 for (int x = 0; x < xs; x++) { 02568 float ang = x * M_PI * pfac; 02569 float si = sin(ang); 02570 float co = cos(ang); 02571 02572 for (int y = 0; y < r2 - r1; y++) { 02573 float ypr1 = (float)y + r1; 02574 float xx = ypr1 * co + nxon2 + dx; 02575 float yy = ypr1 * si + nyon2 + dy; 02576 // float t = xx - Util::fast_floor(xx); 02577 // float u = yy - Util::fast_floor(yy); 02578 float t = xx - (int)xx; 02579 float u = yy - (int)yy; 02580 // int k = (int) Util::fast_floor(xx) + (int) (Util::fast_floor(yy)) * nx; 02581 int k = (int) xx + ((int) yy) * nx; 02582 float val = Util::bilinear_interpolate(d[k], d[k + 1], d[k + nx], d[k + nx+1], t,u); 02583 if (weight_radial) val *= ypr1; 02584 dd[x + y * xs] = val; 02585 } 02586 02587 } 02588 ret->update(); 02589 02590 EXITFUNC; 02591 return ret; 02592 }