Classes | |
class | EMAN::TranslationalAligner |
Translational 2D Alignment using cross correlation. More... | |
class | EMAN::RotationalAligner |
rotational alignment using angular correlation More... | |
class | EMAN::RotationalAlignerIterative |
rotational alignment using the iterative method More... | |
class | EMAN::RotateTranslateAligner |
rotational, translational alignment More... | |
class | EMAN::RotateTranslateAlignerIterative |
rotational, translational alignment SPIDER style More... | |
class | EMAN::RotateFlipAligner |
rotational and flip alignment More... | |
class | EMAN::RotateFlipAlignerIterative |
rotational and flip alignment, iterative style More... | |
class | EMAN::RotateTranslateFlipAligner |
rotational, translational and flip alignment More... | |
class | EMAN::RotateTranslateFlipAlignerIterative |
rotational, translational and flip alignment, iterative style 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... | |
Functions | |
EMData * | EMAN::EMData::do_fft () const |
return the fast fourier transform (FFT) image of the current image. | |
EMData * | EMAN::EMData::do_ift () |
return the inverse fourier transform (IFT) image of the current image. | |
void | EMAN::EMData::ri2ap () |
convert the complex image from real/imaginary to amplitude/phase | |
void | EMAN::EMData::ap2ri () |
convert the complex image from amplitude/phase to real/imaginary | |
void | EMAN::EMData::ri2inten () |
convert the complex image from real/imaginary to Intensity/0. | |
void | EMAN::EMData::insert_clip (const EMData *const block, const IntPoint &origin) |
Insert a clip into this image. | |
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::get_clip (const Region &area, const float fill=0) const |
Get an inclusive clip. | |
EMData * | EMAN::EMData::calc_ccf (EMData *with, 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) |
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. | |
EMData * | do_fft () const |
return the fast fourier transform (FFT) image of the current image. | |
EMData * | do_ift () |
return the inverse fourier transform (IFT) image of the current image. | |
void | ri2ap () |
convert the complex image from real/imaginary to amplitude/phase | |
void | ap2ri () |
convert the complex image from amplitude/phase to real/imaginary | |
void | ri2inten () |
convert the complex image from real/imaginary to Intensity/0. | |
void | insert_clip (const EMData *const block, const IntPoint &origin) |
Insert a clip into this image. |
void ap2ri | ( | ) |
convert the complex image from amplitude/phase to real/imaginary
Referenced by EMAN::EMData::ap2ri().
void EMData::ap2ri | ( | ) | [inherited] |
convert the complex image from amplitude/phase to real/imaginary
Definition at line 906 of file emdata_transform.cpp.
References ap2ri(), emdata_ap2ri(), ENTERFUNC, EXITFUNC, EMAN::EMData::get_data(), EMAN::EMData::is_complex(), EMAN::EMData::is_ri(), EMAN::EMData::nx, EMAN::EMData::ny, EMAN::EMData::nz, EMAN::EMData::set_ri(), and EMAN::EMData::update().
Referenced by EMAN::CtfAverager::add_image(), EMAN::EMData::apply_radial_func(), EMAN::EMData::calc_mutual_correlation(), EMAN::EMData::common_lines(), EMAN::EMData::convolute(), EMAN::EMData::do_ift(), EMAN::EMData::do_ift_inplace(), EMAN::EMData::mult(), EMAN::TestImageFourierNoiseProfile::process_inplace(), EMAN::CTFSNRWeightProcessor::process_inplace(), EMAN::TestImageFourierNoiseGaussian::process_inplace(), EMAN::AddRandomNoiseProcessor::process_inplace(), EMAN::BinarizeFourierProcessor::process_inplace(), EMAN::ComplexPixelProcessor::process_inplace(), EMAN::GaussFFTProjector::project3d(), and EMAN::EMData::ri2inten().
00907 { 00908 ENTERFUNC; 00909 00910 if (!is_complex() || is_ri()) { 00911 return; 00912 } 00913 00914 #ifdef EMAN2_USING_CUDA 00915 if (gpu_operation_preferred()) { 00916 EMDataForCuda tmp = get_data_struct_for_cuda(); 00917 emdata_ap2ri(&tmp); 00918 set_ri(true); 00919 gpu_update(); 00920 EXITFUNC; 00921 return; 00922 } 00923 #endif 00924 00925 Util::ap2ri(get_data(), nx * ny * nz); 00926 set_ri(true); 00927 update(); 00928 EXITFUNC; 00929 }
EMData * EMData::calc_ccf | ( | EMData * | with, | |
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 1426 of file emdata.cpp.
References EMAN::EMData::clip_inplace(), EMAN::convolution(), EMAN::correlation(), ENTERFUNC, EXITFUNC, EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::EMData::get_zsize(), EMAN::EMData::nx, EMAN::EMData::ny, and EMAN::EMData::nz.
Referenced by 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().
01427 { 01428 ENTERFUNC; 01429 if( with == 0 ) { 01430 EXITFUNC; 01431 return convolution(this,this,fpflag, center); 01432 } 01433 else if ( with == this ){ // this if statement is not necessary, the correlation function tests to see if with == this 01434 EXITFUNC; 01435 return correlation(this, this, fpflag,center); 01436 } 01437 else { 01438 01439 #ifdef EMAN2_USING_CUDA 01440 if (gpu_operation_preferred()) { 01441 EXITFUNC; 01442 return calc_ccf_cuda(with,false,center); 01443 } 01444 #endif 01445 01446 // If the argument EMData pointer is not the same size we automatically resize it 01447 bool undoresize = false; 01448 int wnx = with->get_xsize(); int wny = with->get_ysize(); int wnz = with->get_zsize(); 01449 if ( wnx != nx || wny != ny || wnz != nz ) { 01450 Region r((wnx-nx)/2, (wny-ny)/2, (wnz-nz)/2,nx,ny,nz); 01451 with->clip_inplace(r); 01452 undoresize = true; 01453 } 01454 01455 EMData* cor = correlation(this, with, fpflag, center); 01456 01457 // If the argument EMData pointer was resized, it is returned to its original dimensions 01458 if ( undoresize ) { 01459 Region r((nx-wnx)/2, (ny-wny)/2,(nz-wnz)/2,wnx,wny,wnz); 01460 with->clip_inplace(r); 01461 } 01462 01463 EXITFUNC; 01464 return cor; 01465 } 01466 }
EMData * EMData::calc_ccfx | ( | EMData *const | with, | |
int | y0 = 0 , |
|||
int | y1 = -1 , |
|||
bool | nosum = 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 1468 of file emdata.cpp.
References EMAN::EMData::EMData(), 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::RotationalAlignerIterative::align(), EMAN::RotatePrecenterAligner::align(), EMAN::RotationalAligner::align_180_ambiguous(), and EMAN::EMData::make_footprint().
01469 { 01470 ENTERFUNC; 01471 01472 #ifdef EMAN2_USING_CUDA 01473 if (gpu_operation_preferred() ) { 01474 EXITFUNC; 01475 return calc_ccfx_cuda(with,y0,y1,no_sum); 01476 } 01477 #endif 01478 01479 if (!with) { 01480 LOGERR("NULL 'with' image. "); 01481 throw NullPointerException("NULL input image"); 01482 } 01483 01484 if (!EMUtil::is_same_size(this, with)) { 01485 LOGERR("images not same size: (%d,%d,%d) != (%d,%d,%d)", 01486 nx, ny, nz, 01487 with->get_xsize(), with->get_ysize(), with->get_zsize()); 01488 throw ImageFormatException("images not same size"); 01489 } 01490 if (get_ndim() > 2) { 01491 LOGERR("2D images only"); 01492 throw ImageDimensionException("2D images only"); 01493 } 01494 01495 if (y1 <= y0) { 01496 y1 = ny; 01497 } 01498 01499 if (y0 >= y1) { 01500 y0 = 0; 01501 } 01502 01503 if (y0 < 0) { 01504 y0 = 0; 01505 } 01506 01507 if (y1 > ny) { 01508 y1 = ny; 01509 } 01510 if (is_complex_x() || with->is_complex_x() ) throw; // Woops don't support this anymore! 01511 01512 static int nx_fft = 0; 01513 static int ny_fft = 0; 01514 static EMData f1; 01515 static EMData f2; 01516 static EMData rslt; 01517 01518 int height = y1-y0; 01519 int width = (nx+2-(nx%2)); 01520 if (width != nx_fft || height != ny_fft ) { 01521 f1.set_size(width,height); 01522 f2.set_size(width,height); 01523 rslt.set_size(nx,height); 01524 nx_fft = width; 01525 ny_fft = height; 01526 } 01527 01528 float *d1 = get_data(); 01529 float *d2 = with->get_data(); 01530 float *f1d = f1.get_data(); 01531 float *f2d = f2.get_data(); 01532 for (int j = 0; j < height; j++) { 01533 EMfft::real_to_complex_1d(d1 + j * nx, f1d+j*width, nx); 01534 EMfft::real_to_complex_1d(d2 + j * nx, f2d+j*width, nx); 01535 } 01536 01537 for (int j = 0; j < height; j++) { 01538 float *f1a = f1d + j * width; 01539 float *f2a = f2d + j * width; 01540 01541 for (int i = 0; i < width / 2; i++) { 01542 float re1 = f1a[2*i]; 01543 float re2 = f2a[2*i]; 01544 float im1 = f1a[2*i+1]; 01545 float im2 = f2a[2*i+1]; 01546 01547 f1d[j*width+i*2] = re1 * re2 + im1 * im2; 01548 f1d[j*width+i*2+1] = im1 * re2 - re1 * im2; 01549 } 01550 } 01551 01552 float* rd = rslt.get_data(); 01553 for (int j = y0; j < y1; j++) { 01554 EMfft::complex_to_real_1d(f1d+j*width, rd+j*nx, nx); 01555 } 01556 01557 if (no_sum) { 01558 rslt.update(); // This is important in terms of the copy - the returned object won't have the correct flags unless we do this 01559 EXITFUNC; 01560 return new EMData(rslt); 01561 } else { 01562 EMData *cf = new EMData(nx,1,1); 01563 cf->to_zero(); 01564 float *c = cf->get_data(); 01565 for (int j = 0; j < height; j++) { 01566 for(int i = 0; i < nx; ++i) { 01567 c[i] += rd[i+j*nx]; 01568 } 01569 } 01570 cf->update(); 01571 EXITFUNC; 01572 return cf; 01573 } 01574 }
EMData* do_fft | ( | ) | const |
return the fast fourier transform (FFT) image of the current image.
the current image is not changed. The result is in real/imaginary format.
EMData * EMData::do_fft | ( | ) | const [inherited] |
return the fast fourier transform (FFT) image of the current image.
the current image is not changed. The result is in real/imaginary format.
Definition at line 153 of file emdata_transform.cpp.
References EMAN::EMData::copy(), EMAN::EMData::copy_head(), ENTERFUNC, EXITFUNC, EMAN::EMData::get_data(), EMAN::EMData::get_ysize(), EMAN::EMData::get_zsize(), ImageFormatException, EMAN::EMData::is_complex(), EMAN::EMData::is_fftodd(), EMAN::EMData::is_fftpadded(), LOGERR, EMAN::EMData::nx, EMAN::EMData::ny, EMAN::EMData::nz, EMAN::EMData::set_complex(), EMAN::EMData::set_complex_x(), EMAN::EMData::set_fftodd(), EMAN::EMData::set_fftpad(), EMAN::EMData::set_ri(), EMAN::EMData::set_size(), and EMAN::EMData::update().
Referenced by EMAN::CtfAverager::add_image(), EMAN::CtfCAutoAverager::add_image(), EMAN::CtfCWautoAverager::add_image(), EMAN::FRM2DAligner::align(), EMAN::EMData::bispecRotTransInvDirect(), EMAN::EMData::bispecRotTransInvN(), EMAN::EMData::calc_mutual_correlation(), EMAN::FRCCmp::cmp(), EMAN::PhaseCmp::cmp(), EMAN::OptVarianceCmp::cmp(), EMAN::EMData::common_lines(), EMAN::EMData::convolute(), EMAN::MatchSFProcessor::create_radial_func(), EMAN::EMData::FourInterpol(), EMAN::EMData::FourTruncate(), main(), EMAN::EMData::make_footprint(), EMAN::TestUtil::make_image_file_by_mode(), EMAN::FFTResampleProcessor::process(), EMAN::Wiener2DAutoAreaProcessor::process(), EMAN::FileFourierProcessor::process_inplace(), EMAN::SNRProcessor::process_inplace(), EMAN::RealToFFTProcessor::process_inplace(), EMAN::CutoffBlockProcessor::process_inplace(), EMAN::AmpweightFourierProcessor::process_inplace(), EMAN::FourierAnlProcessor::process_inplace(), EMAN::FourierProcessor::process_inplace(), EMAN::ImageProcessor::process_inplace(), EMAN::GaussFFTProjector::project3d(), EMAN::RT3DSphereAligner::xform_align_nbest(), and EMAN::RT3DGridAligner::xform_align_nbest().
00154 { 00155 ENTERFUNC; 00156 00157 #ifdef EMAN2_USING_CUDA 00158 if (gpu_operation_preferred()) { 00159 EXITFUNC; 00160 return do_fft_cuda(); 00161 } 00162 #endif 00163 00164 if (is_complex() ) { // ming add 08/17/2010 00165 #ifdef NATIVE_FFT 00166 LOGERR(" NATIVE_FFT not supported yet."); 00167 throw ImageFormatException("real image expected. Input image is complex image."); 00168 exit; 00169 #endif // NATIVE_FFT 00170 00171 EMData *temp_in=copy(); 00172 EMData *dat= copy_head(); 00173 int offset; 00174 if(is_fftpadded()) { 00175 offset = is_fftodd() ? 1 : 2; 00176 } 00177 else offset=0; 00178 //printf("offset=%d\n",offset); 00179 EMfft::complex_to_complex_nd(temp_in->get_data(),dat->get_data(),nx-offset,ny,nz); 00180 00181 if(dat->get_ysize()==1 && dat->get_zsize()==1) dat->set_complex_x(true); 00182 00183 dat->update(); 00184 delete temp_in; 00185 EXITFUNC; 00186 return dat; 00187 } 00188 00189 else{ 00190 int nxreal = nx; 00191 int offset = 2 - nx%2; 00192 int nx2 = nx + offset; 00193 EMData* dat = copy_head(); 00194 dat->set_size(nx2, ny, nz); 00195 //dat->to_zero(); // do not need it, real_to_complex will do it right anyway 00196 if (offset == 1) dat->set_fftodd(true); 00197 else dat->set_fftodd(false); 00198 00199 float *d = dat->get_data(); 00200 //std::cout<<" do_fft "<<rdata[5]<<" "<<d[5]<<std::endl; 00201 EMfft::real_to_complex_nd(get_data(), d, nxreal, ny, nz); 00202 00203 dat->update(); 00204 dat->set_fftpad(true); 00205 dat->set_complex(true); 00206 if(dat->get_ysize()==1 && dat->get_zsize()==1) dat->set_complex_x(true); 00207 dat->set_ri(true); 00208 00209 EXITFUNC; 00210 return dat; 00211 } 00212 }
EMData* do_ift | ( | ) |
return the inverse fourier transform (IFT) image of the current image.
the current image may be changed if it is in amplitude/phase format as opposed to real/imaginary format - if this change is performed it is not undone.
ImageFormatException | If the image is not a complex image. |
EMData * EMData::do_ift | ( | ) | [inherited] |
return the inverse fourier transform (IFT) image of the current image.
the current image may be changed if it is in amplitude/phase format as opposed to real/imaginary format - if this change is performed it is not undone.
ImageFormatException | If the image is not a complex image. |
Definition at line 262 of file emdata_transform.cpp.
References EMAN::EMData::ap2ri(), EMAN::EMData::copy_head(), ENTERFUNC, EXITFUNC, EMAN::EMData::get_data(), EMAN::EMData::get_ndim(), EMAN::EMData::get_ysize(), EMAN::EMData::get_zsize(), ImageFormatException, EMAN::EMData::is_complex(), EMAN::EMData::is_fftodd(), EMAN::EMData::is_ri(), LOGERR, LOGWARN, EMAN::EMData::mult(), EMAN::EMData::nx, EMAN::EMData::ny, EMAN::EMData::nz, EMAN::EMData::rdata, EMAN::EMData::set_complex(), EMAN::EMData::set_complex_x(), EMAN::EMData::set_fftodd(), EMAN::EMData::set_fftpad(), EMAN::EMData::set_ri(), EMAN::EMData::set_size(), and EMAN::EMData::update().
Referenced by EMAN::EMData::calc_mutual_correlation(), EMAN::EMData::convolute(), EMAN::EMData::FH2Real(), EMAN::CtfAverager::finish(), EMAN::CtfCAutoAverager::finish(), EMAN::CtfCWautoAverager::finish(), frm_2d_Align(), main(), EMAN::EMData::make_footprint(), EMAN::Wiener2DFourierProcessor::process(), EMAN::FileFourierProcessor::process_inplace(), EMAN::SNRProcessor::process_inplace(), EMAN::AmpweightFourierProcessor::process_inplace(), EMAN::FourierAnlProcessor::process_inplace(), EMAN::FourierProcessor::process_inplace(), EMAN::ImageProcessor::process_inplace(), and EMAN::GaussFFTProjector::project3d().
00263 { 00264 ENTERFUNC; 00265 00266 #ifdef EMAN2_USING_CUDA 00267 if (gpu_operation_preferred()) { 00268 EXITFUNC; 00269 return do_ift_cuda(); 00270 } 00271 #endif 00272 00273 if (!is_complex()) { 00274 LOGERR("complex image expected. Input image is real image."); 00275 throw ImageFormatException("complex image expected. Input image is real image."); 00276 } 00277 00278 if (!is_ri()) { 00279 LOGWARN("run IFT on AP data, only RI should be used. Converting."); 00280 } 00281 00282 get_data(); // Required call if GPU caching is being used. Otherwise harmless 00283 EMData* dat = copy_head(); 00284 dat->set_size(nx, ny, nz); 00285 ap2ri(); 00286 00287 float *d = dat->get_data(); 00288 int ndim = get_ndim(); 00289 00290 /* Do inplace IFT on a image copy, because the complex to real transform of 00291 * nd will destroy its input array even for out-of-place transforms. 00292 */ 00293 memcpy((char *) d, (char *) rdata, nx * ny * nz * sizeof(float)); 00294 00295 int offset = is_fftodd() ? 1 : 2; 00296 //cout << "Sending offset " << offset << " " << nx-offset << endl; 00297 if (ndim == 1) { 00298 EMfft::complex_to_real_nd(d, d, nx - offset, ny, nz); 00299 } else { 00300 EMfft::complex_to_real_nd(d, d, nx - offset, ny, nz); 00301 00302 #ifndef CUDA_FFT 00303 size_t row_size = (nx - offset) * sizeof(float); 00304 for (int i = 1; i < ny * nz; i++) { 00305 memmove((char *) &d[i * (nx - offset)], (char *) &d[i * nx], row_size); 00306 } 00307 #endif 00308 } 00309 00310 dat->set_size(nx - offset, ny, nz); //remove the padding 00311 #if defined FFTW2 || defined FFTW3 || defined CUDA_FFT //native fft and ACML already done normalization 00312 // SCALE the inverse FFT 00313 float scale = 1.0f / ((nx - offset) * ny * nz); 00314 dat->mult(scale); 00315 #endif //FFTW2 || FFTW3 00316 dat->set_fftodd(false); 00317 dat->set_fftpad(false); 00318 dat->set_complex(false); 00319 if(dat->get_ysize()==1 && dat->get_zsize()==1) dat->set_complex_x(false); 00320 dat->set_ri(false); 00321 dat->update(); 00322 00323 00324 EXITFUNC; 00325 return dat; 00326 }
EMData::EMData | ( | const EMData & | that | ) | [inherited] |
Construct from an EMData (copy constructor).
Performs a deep copy
that | the EMData to copy |
Definition at line 126 of file emdata.cpp.
References data, EMAN::EMUtil::em_malloc(), EMAN::EMUtil::em_memcpy(), EMAN::EMData::EMData(), EMAN::EMData::EMDATA_GPU_RO_NEEDS_UPDATE, ENTERFUNC, EMAN::EMData::flags, EMAN::EMData::nx, EMAN::EMData::ny, EMAN::EMData::nz, EMAN::EMData::rdata, EMAN::EMData::rot_fp, EMAN::EMData::totalalloc, and UnexpectedBehaviorException.
00126 : 00127 #ifdef EMAN2_USING_CUDA 00128 cuda_cache_handle(-1), 00129 #endif //EMAN2_USING_CUDA 00130 attr_dict(that.attr_dict), rdata(0), supp(0), flags(that.flags), changecount(that.changecount), nx(that.nx), ny(that.ny), nz(that.nz), 00131 nxy(that.nx*that.ny), nxyz(that.nx*that.ny*that.nz), xoff(that.xoff), yoff(that.yoff), zoff(that.zoff),all_translation(that.all_translation), path(that.path), 00132 pathnum(that.pathnum), rot_fp(0) 00133 { 00134 ENTERFUNC; 00135 00136 float* data = that.rdata; 00137 size_t num_bytes = nx*ny*nz*sizeof(float); 00138 if (data && num_bytes != 0) 00139 { 00140 rdata = (float*)EMUtil::em_malloc(num_bytes); 00141 EMUtil::em_memcpy(rdata, data, num_bytes); 00142 } 00143 #ifdef EMAN2_USING_CUDA 00144 if (num_bytes != 0 && that.cuda_cache_handle != -1 && that.gpu_rw_is_current()) { 00145 float * cuda_data = that.get_cuda_data(); 00146 CudaDataLock lock2(&that); 00147 set_size_cuda(nx,ny,nz); 00148 float *cd = get_cuda_data(); 00149 CudaDataLock lock1(this); 00150 cudaError_t error = cudaMemcpy(cd,cuda_data,num_bytes,cudaMemcpyDeviceToDevice); 00151 if ( error != cudaSuccess ) throw UnexpectedBehaviorException("cudaMemcpy failed in EMData copy construction with error: " + string(cudaGetErrorString(error))); 00152 } 00153 // This is a bit of hack 00154 flags |= EMDATA_GPU_RO_NEEDS_UPDATE; 00155 #endif //EMAN2_USING_CUDA 00156 if (that.rot_fp != 0) rot_fp = new EMData(*(that.rot_fp)); 00157 00158 EMData::totalalloc++; 00159 00160 ENTERFUNC; 00161 }
Get an inclusive clip.
Pads to fill if larger than this image.
area | The clip area, can be 2D/3D | |
fill | the value to assign new pixels outside the area of the original image |
ImageDimensionException | if any of the dimensions of the argument region are negative |
Definition at line 546 of file emdata.cpp.
References EMAN::EMData::attr_dict, EMAN::EMData::EMData(), ENTERFUNC, EXITFUNC, EMAN::Region::get_ndim(), EMAN::EMData::get_ndim(), EMAN::Dict::has_key(), ImageDimensionException, EMAN::EMData::insert_clip(), LOGERR, EMAN::EMData::nx, EMAN::EMData::ny, EMAN::EMData::nz, EMAN::Region::origin, EMAN::EMData::path, EMAN::EMData::pathnum, EMAN::EMData::set_path(), EMAN::EMData::set_pathnum(), EMAN::EMData::set_size(), EMAN::EMData::set_xyz_origin(), EMAN::Region::size, EMAN::EMData::to_value(), and EMAN::EMData::update().
Referenced by EMAN::EMData::calc_fast_sigma_image(), EMAN::EMData::make_footprint(), EMAN::ScaleTransformProcessor::process(), EMAN::IntTranslateProcessor::process(), EMAN::SNRProcessor::process_inplace(), EMAN::CutoffBlockProcessor::process_inplace(), and EMAN::EMData::window_center().
00547 { 00548 ENTERFUNC; 00549 if (get_ndim() != area.get_ndim()) { 00550 LOGERR("cannot get %dD clip out of %dD image", area.get_ndim(),get_ndim()); 00551 return 0; 00552 } 00553 00554 EMData *result = new EMData(); 00555 00556 // Ensure that all of the metadata of this is stored in the new object 00557 // Originally added to ensure that euler angles were retained when preprocessing (zero padding) images 00558 // prior to insertion into the 3D for volume in the reconstruction phase (see reconstructor.cpp/h). 00559 result->attr_dict = this->attr_dict; 00560 int zsize = (int)area.size[2]; 00561 if (zsize == 0 && nz <= 1) { 00562 zsize = 1; 00563 } 00564 int ysize = (ny<=1 && (int)area.size[1]==0 ? 1 : (int)area.size[1]); 00565 00566 if ( (int)area.size[0] < 0 || ysize < 0 || zsize < 0 ) 00567 { 00568 // Negative image dimensions not supported - added retrospectively by d.woolford (who didn't write get_clip but wrote clip_inplace) 00569 throw ImageDimensionException("New image dimensions are negative - this is not supported in the the get_clip operation"); 00570 } 00571 00572 #ifdef EMAN2_USING_CUDA 00573 // Strategy is always to prefer using the GPU if possible 00574 bool use_gpu = false; 00575 if ( gpu_operation_preferred() ) { 00576 result->set_size_cuda((int)area.size[0], ysize, zsize); 00577 //CudaDataLock lock(this); // Just so we never have to recopy this data to and from the GPU 00578 result->get_cuda_data(); // Force the allocation - set_size_cuda is lazy 00579 // Setting the value is necessary seeing as cuda data is not automatically zeroed 00580 result->to_value(fill); // This will automatically use the GPU. 00581 use_gpu = true; 00582 } else { // cpu == True 00583 result->set_size((int)area.size[0], ysize, zsize); 00584 if (fill != 0.0) { result->to_value(fill); }; 00585 } 00586 #else 00587 result->set_size((int)area.size[0], ysize, zsize); 00588 if (fill != 0.0) { result->to_value(fill); }; 00589 #endif //EMAN2_USING_CUDA 00590 00591 int x0 = (int) area.origin[0]; 00592 x0 = x0 < 0 ? 0 : x0; 00593 00594 int y0 = (int) area.origin[1]; 00595 y0 = y0 < 0 ? 0 : y0; 00596 00597 int z0 = (int) area.origin[2]; 00598 z0 = z0 < 0 ? 0 : z0; 00599 00600 int x1 = (int) (area.origin[0] + area.size[0]); 00601 x1 = x1 > nx ? nx : x1; 00602 00603 int y1 = (int) (area.origin[1] + area.size[1]); 00604 y1 = y1 > ny ? ny : y1; 00605 00606 int z1 = (int) (area.origin[2] + area.size[2]); 00607 z1 = z1 > nz ? nz : z1; 00608 if (z1 <= 0) { 00609 z1 = 1; 00610 } 00611 00612 result->insert_clip(this,-((IntPoint)area.origin)); 00613 00614 if( attr_dict.has_key("apix_x") && attr_dict.has_key("apix_y") && 00615 attr_dict.has_key("apix_z") ) 00616 { 00617 if( attr_dict.has_key("origin_x") && attr_dict.has_key("origin_y") && 00618 attr_dict.has_key("origin_z") ) 00619 { 00620 float xorigin = attr_dict["origin_x"]; 00621 float yorigin = attr_dict["origin_y"]; 00622 float zorigin = attr_dict["origin_z"]; 00623 00624 float apix_x = attr_dict["apix_x"]; 00625 float apix_y = attr_dict["apix_y"]; 00626 float apix_z = attr_dict["apix_z"]; 00627 00628 result->set_xyz_origin(xorigin + apix_x * area.origin[0], 00629 yorigin + apix_y * area.origin[1], 00630 zorigin + apix_z * area.origin[2]); 00631 } 00632 } 00633 00634 #ifdef EMAN2_USING_CUDA 00635 if (use_gpu) result->gpu_update(); 00636 else result->update(); 00637 #else 00638 result->update(); 00639 #endif // EMAN2_USING_CUDA 00640 00641 00642 result->set_path(path); 00643 result->set_pathnum(pathnum); 00644 00645 EXITFUNC; 00646 return result; 00647 }
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 1724 of file emdata_transform.cpp.
References EMAN::EMUtil::em_memcpy(), EXITFUNC, 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, UnexpectedBehaviorException, and EMAN::EMData::update().
Referenced by EMAN::EMData::get_clip(), and EMAN::EMData::make_rotational_footprint_e1().
01724 { 01725 int nx1 = block->get_xsize(); 01726 int ny1 = block->get_ysize(); 01727 int nz1 = block->get_zsize(); 01728 01729 Region area(origin[0], origin[1], origin[2],nx1, ny1, nz1); 01730 01731 int x0 = (int) area.origin[0]; 01732 x0 = x0 < 0 ? 0 : x0; 01733 01734 int y0 = (int) area.origin[1]; 01735 y0 = y0 < 0 ? 0 : y0; 01736 01737 int z0 = (int) area.origin[2]; 01738 z0 = z0 < 0 ? 0 : z0; 01739 01740 int x1 = (int) (area.origin[0] + area.size[0]); 01741 x1 = x1 > nx ? nx : x1; 01742 01743 int y1 = (int) (area.origin[1] + area.size[1]); 01744 y1 = y1 > ny ? ny : y1; 01745 01746 int z1 = (int) (area.origin[2] + area.size[2]); 01747 z1 = z1 > nz ? nz : z1; 01748 if (z1 <= 0) { 01749 z1 = 1; 01750 } 01751 01752 int xd0 = (int) (area.origin[0] < 0 ? -area.origin[0] : 0); 01753 int yd0 = (int) (area.origin[1] < 0 ? -area.origin[1] : 0); 01754 int zd0 = (int) (area.origin[2] < 0 ? -area.origin[2] : 0); 01755 01756 if (x1 < x0 || y1 < y0 || z1 < z0) return; // out of bounds, this is fine, nothing happens 01757 01758 size_t clipped_row_size = (x1-x0) * sizeof(float); 01759 int src_secsize = nx1 * ny1; 01760 int dst_secsize = nx * ny; 01761 01762 #ifdef EMAN2_USING_CUDA 01763 if (gpu_operation_preferred()) { 01764 // cudaMemcpy3DParms copyParams = {0}; 01765 // copyParams.srcPtr = make_cudaPitchedPtr((void*)get_cuda_data(), nx*sizeof(float), nx, ny); 01766 // cout << "Src pos is " << x0 << " " << y0 << " " << z0 << endl; 01767 // copyParams.srcPos = make_cudaPos(x0,y0,z0); 01768 // cout << "Extent is " << x1-x0 << " " << y1-y0 << " " << z1-z0 << endl; 01769 // cudaExtent extent = make_cudaExtent(x1-x0,y1-y0,z1-z0); 01770 // int rnx = result->get_xsize(); 01771 // int rny = result->get_ysize(); 01772 // copyParams.dstPtr = make_cudaPitchedPtr((void*)result->get_cuda_data(),rnx*sizeof(float),rnx,rny ); 01773 // cout << "Dest pos is " << xd0 << " " << yd0 << " " << zd0 << endl; 01774 // copyParams.dstPos = make_cudaPos(xd0,yd0,zd0); 01775 // copyParams.extent = extent; 01776 // copyParams.kind = cudaMemcpyDeviceToDevice; 01777 // cudaError_t error = cudaMemcpy3D(©Params); 01778 // if ( error != cudaSuccess) { 01779 // string e = cudaGetErrorString(error); 01780 // throw UnexpectedBehaviorException("CudaMemcpy3D failed with error: " + e); 01781 // } 01782 get_cuda_data(); 01783 CudaDataLock lock(this); 01784 block->get_cuda_data(); 01785 CudaDataLock lock2(block); 01786 for (int i = 0; i < (z1-z0); i++) { 01787 float* ldst = get_cuda_data() + (z0+i) * dst_secsize + y0 * nx + x0; 01788 float* lsrc = block->get_cuda_data() + (zd0+i) * src_secsize + yd0 * nx1 + xd0; 01789 01790 01791 // float* ldst = result->get_cuda_data() + (zd0+i) * dst_secsize + yd0 * (int)area.size[0] + xd0; 01792 // float* lsrc = get_cuda_data() + (z0+i) * src_secsize + y0 * nx + x0; 01793 cudaError_t error = cudaMemcpy2D( ldst, (nx)*sizeof(float), lsrc,nx1*sizeof(float), clipped_row_size, (y1-y0), cudaMemcpyDeviceToDevice ); 01794 if ( error != cudaSuccess) { 01795 string e = cudaGetErrorString(error); 01796 throw UnexpectedBehaviorException("cudaMemcpy2D failed in get_clip with error: " + e); 01797 } 01798 } 01799 gpu_update(); 01800 EXITFUNC; 01801 return; 01802 } 01803 #endif 01804 float *src = block->get_data() + zd0 * src_secsize + yd0 * nx1 + xd0; 01805 float *dst = get_data() + z0 * dst_secsize + y0 * nx + x0; 01806 01807 // float *src = get_data() + z0 * src_secsize + y0 * nx + x0; 01808 // float *dst = result->get_data(); 01809 // dst += zd0 * dst_secsize + yd0 * (int)area.size[0] + xd0; 01810 01811 int src_gap = src_secsize - (y1-y0) * nx1; 01812 int dst_gap = dst_secsize - (y1-y0) * nx; 01813 for (int i = z0; i < z1; i++) { 01814 for (int j = y0; j < y1; j++) { 01815 EMUtil::em_memcpy(dst, src, clipped_row_size); 01816 src += nx1; 01817 dst += nx; 01818 } 01819 src += src_gap; 01820 dst += dst_gap; 01821 } 01822 01823 update(); 01824 EXITFUNC; 01825 }
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 1628 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().
01628 { 01629 ENTERFUNC; 01630 update_stat(); 01631 // Note that rotational_footprint caching saves a large amount of time 01632 // but this is at the expense of memory. Note that a policy is hardcoded here, 01633 // that is that caching is only employed when premasked is false and unwrap 01634 // is true - this is probably going to be what is used in most scenarios 01635 // as advised by Steve Ludtke - In terms of performance this caching doubles the metric 01636 // generated by e2speedtest. 01637 if ( rot_fp != 0 && unwrap == true) { 01638 return new EMData(*rot_fp); 01639 } 01640 01641 EMData* ccf = this->calc_ccf(this,CIRCULANT,true); 01642 ccf->sub(ccf->get_edge_mean()); 01643 //ccf->process_inplace("xform.phaseorigin.tocenter"); ccf did the centering 01644 EMData *result = ccf->unwrap(); 01645 delete ccf; ccf = 0; 01646 01647 EXITFUNC; 01648 if ( unwrap == true) 01649 { // this if statement reflects a strict policy of caching in only one scenario see comments at beginning of function block 01650 01651 // Note that the if statement at the beginning of this function ensures that rot_fp is not zero, so there is no need 01652 // to throw any exception 01653 // if ( rot_fp != 0 ) throw UnexpectedBehaviorException("The rotational foot print is only expected to be cached if it is not NULL"); 01654 01655 // Here is where the caching occurs - the rot_fp takes ownsherhip of the pointer, and a deep copied EMData object is returned. 01656 // The deep copy invokes a cost in terms of CPU cycles and memory, but prevents the need for complicated memory management (reference counting) 01657 rot_fp = result; 01658 return new EMData(*rot_fp); 01659 } 01660 else return result; 01661 }
EMData assignment operator Performs a deep copy.
that | the EMData to copy |
Definition at line 163 of file emdata.cpp.
References EMAN::EMData::all_translation, EMAN::EMData::attr_dict, EMAN::EMData::changecount, data, EMAN::EMUtil::em_memcpy(), EMAN::EMData::EMData(), EMAN::EMData::EMDATA_GPU_RO_NEEDS_UPDATE, 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.
00164 { 00165 ENTERFUNC; 00166 00167 if ( this != &that ) 00168 { 00169 free_memory(); // Free memory sets nx,ny and nz to 0 00170 00171 // Only copy the rdata if it exists, we could be in a scenario where only the header has been read 00172 float* data = that.rdata; 00173 size_t num_bytes = that.nx*that.ny*that.nz*sizeof(float); 00174 if (data && num_bytes != 0) 00175 { 00176 nx = 1; // This prevents a memset in set_size 00177 set_size(that.nx,that.ny,that.nz); 00178 EMUtil::em_memcpy(rdata, data, num_bytes); 00179 } 00180 00181 flags = that.flags; 00182 00183 all_translation = that.all_translation; 00184 00185 path = that.path; 00186 pathnum = that.pathnum; 00187 attr_dict = that.attr_dict; 00188 00189 xoff = that.xoff; 00190 yoff = that.yoff; 00191 zoff = that.zoff; 00192 00193 #ifdef EMAN2_USING_CUDA 00194 free_cuda_memory(); 00195 // There should also be the case where we deal with ro data... 00196 if (num_bytes != 0 && that.cuda_cache_handle != -1 && that.gpu_rw_is_current()) { 00197 float * cuda_data = that.get_cuda_data(); 00198 CudaDataLock lock1(&that); 00199 set_size_cuda(that.nx, that.ny, that.nz); 00200 float *cd = get_cuda_data(); 00201 CudaDataLock lock2(this); 00202 cudaError_t error = cudaMemcpy(cd,cuda_data,num_bytes,cudaMemcpyDeviceToDevice); 00203 if ( error != cudaSuccess ) throw UnexpectedBehaviorException("cudaMemcpy failed in operator= with error: " + string(cudaGetErrorString(error))); 00204 } 00205 // This is a bit of hack 00206 flags &= EMDATA_GPU_RO_NEEDS_UPDATE; 00207 #endif //EMAN2_USING_CUDA 00208 00209 changecount = that.changecount; 00210 00211 if (that.rot_fp != 0) rot_fp = new EMData(*(that.rot_fp)); 00212 else rot_fp = 0; 00213 } 00214 EXITFUNC; 00215 return *this; 00216 }
void ri2ap | ( | ) |
convert the complex image from real/imaginary to amplitude/phase
void EMData::ri2ap | ( | ) | [inherited] |
convert the complex image from real/imaginary to amplitude/phase
Definition at line 962 of file emdata_transform.cpp.
References data, emdata_ri2ap(), ENTERFUNC, EXITFUNC, EMAN::EMData::get_data(), EMAN::EMData::is_complex(), EMAN::EMData::is_ri(), EMAN::EMData::nx, EMAN::EMData::ny, EMAN::EMData::nz, EMAN::EMData::set_ri(), and EMAN::EMData::update().
Referenced by EMAN::EMData::add_incoherent(), EMAN::OptVarianceCmp::cmp(), EMAN::EMData::get_fft_amplitude(), EMAN::EMData::get_fft_phase(), EMAN::TestImageFourierNoiseProfile::process_inplace(), EMAN::CTFSNRWeightProcessor::process_inplace(), EMAN::TestImageFourierNoiseGaussian::process_inplace(), EMAN::BinarizeFourierProcessor::process_inplace(), EMAN::RealToFFTProcessor::process_inplace(), EMAN::ComplexPixelProcessor::process_inplace(), EMAN::EMData::render_amp24(), and EMAN::EMData::render_ap24().
00963 { 00964 ENTERFUNC; 00965 00966 if (!is_complex() || !is_ri()) { 00967 return; 00968 } 00969 #ifdef EMAN2_USING_CUDA 00970 if (gpu_operation_preferred()) { 00971 EMDataForCuda tmp = get_data_struct_for_cuda(); 00972 emdata_ri2ap(&tmp); 00973 set_ri(false); 00974 gpu_update(); 00975 EXITFUNC; 00976 return; 00977 } 00978 #endif 00979 00980 float * data = get_data(); 00981 00982 size_t size = nx * ny * nz; 00983 for (size_t i = 0; i < size; i += 2) { 00984 #ifdef _WIN32 00985 float f = (float)_hypot(data[i], data[i + 1]); 00986 #else 00987 float f = (float)hypot(data[i], data[i + 1]); 00988 #endif 00989 if (data[i] == 0 && data[i + 1] == 0) { 00990 data[i + 1] = 0; 00991 } 00992 else { 00993 data[i + 1] = atan2(data[i + 1], data[i]); 00994 } 00995 data[i] = f; 00996 } 00997 00998 set_ri(false); 00999 update(); 01000 EXITFUNC; 01001 }
void ri2inten | ( | ) |
convert the complex image from real/imaginary to Intensity/0.
This conversion cannot be reversed, and the image remains marked as R/I
void EMData::ri2inten | ( | ) | [inherited] |
convert the complex image from real/imaginary to Intensity/0.
This conversion cannot be reversed, and the image remains marked as R/I
Definition at line 931 of file emdata_transform.cpp.
References EMAN::EMData::ap2ri(), data, emdata_ri2inten(), ENTERFUNC, EXITFUNC, EMAN::EMData::get_data(), EMAN::EMData::is_complex(), EMAN::EMData::is_ri(), EMAN::EMData::nx, EMAN::EMData::ny, EMAN::EMData::nz, EMAN::EMData::set_attr(), and EMAN::EMData::update().
Referenced by EMAN::CTFSNRWeightProcessor::process_inplace().
00932 { 00933 ENTERFUNC; 00934 00935 if (!is_complex()) return; 00936 if (!is_ri()) ap2ri(); 00937 00938 #ifdef EMAN2_USING_CUDA 00939 if (gpu_operation_preferred()) { 00940 EMDataForCuda tmp = get_data_struct_for_cuda(); 00941 emdata_ri2inten(&tmp); 00942 set_attr("is_intensity", int(1)); 00943 gpu_update(); 00944 EXITFUNC; 00945 return; 00946 } 00947 #endif 00948 00949 float * data = get_data(); 00950 size_t size = nx * ny * nz; 00951 for (size_t i = 0; i < size; i += 2) { 00952 data[i]=data[i]*data[i]+data[i+1]*data[i+1]; 00953 data[i+1]=0; 00954 } 00955 00956 set_attr("is_intensity", int(1)); 00957 update(); 00958 EXITFUNC; 00959 }
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 2286 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, unbind_cuda_texture(), UnexpectedBehaviorException, EMAN::EMData::update(), x, and y.
Referenced by EMAN::RTFExhaustiveAligner::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().
02287 { 02288 ENTERFUNC; 02289 02290 if (get_ndim() != 2) { 02291 throw ImageDimensionException("2D image only"); 02292 } 02293 02294 int p = 1; 02295 if (do360) { 02296 p = 2; 02297 } 02298 02299 if (xs < 1) { 02300 xs = (int) Util::fast_floor(p * M_PI * ny / 4); 02301 xs -= xs % 8; 02302 if (xs<=8) xs=16; 02303 } 02304 02305 if (r1 < 0) { 02306 r1 = 4; 02307 } 02308 02309 #ifdef _WIN32 02310 int rr = ny / 2 - 2 - (int) Util::fast_floor(static_cast<float>(_hypot(dx, dy))); 02311 #else 02312 int rr = ny / 2 - 2 - (int) Util::fast_floor(static_cast<float>(hypot(dx, dy))); 02313 #endif //_WIN32 02314 rr-=rr%2; 02315 if (r2 <= r1 || r2 > rr) { 02316 r2 = rr; 02317 } 02318 02319 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"); 02320 02321 #ifdef EMAN2_USING_CUDA 02322 if ( gpu_operation_preferred() ) { 02323 // cout << "Binding " << cuda_cache_handle << endl; 02324 bind_cuda_texture(); 02325 EMData* rslt = new EMData(); 02326 rslt->set_size_cuda(xs,r2-r1,1); 02327 EMDataForCuda r = rslt->get_data_struct_for_cuda(); 02328 // CudaDataLock lock1(rslt); 02329 /*EMDataForCuda* tmp = */emdata_unwrap(&r,r1,r2,xs,p,dx,dy,weight_radial,nx,ny); 02330 unbind_cuda_texture(); 02331 // EMData* e = new EMData(); 02332 // e->set_gpu_rw_data(tmp->data,tmp->nx,tmp->ny,tmp->nz); 02333 // free(tmp); 02334 return rslt; 02335 } 02336 #endif 02337 02338 EMData *ret = new EMData(); 02339 ret->set_size(xs, r2 - r1, 1); 02340 const float *const d = get_const_data(); 02341 float *dd = ret->get_data(); 02342 float pfac = (float)p/(float)xs; 02343 02344 int nxon2 = nx/2; 02345 int nyon2 = ny/2; 02346 for (int x = 0; x < xs; x++) { 02347 float ang = x * M_PI * pfac; 02348 float si = sin(ang); 02349 float co = cos(ang); 02350 02351 for (int y = 0; y < r2 - r1; y++) { 02352 float ypr1 = (float)y + r1; 02353 float xx = ypr1 * co + nxon2 + dx; 02354 float yy = ypr1 * si + nyon2 + dy; 02355 // float t = xx - Util::fast_floor(xx); 02356 // float u = yy - Util::fast_floor(yy); 02357 float t = xx - (int)xx; 02358 float u = yy - (int)yy; 02359 // int k = (int) Util::fast_floor(xx) + (int) (Util::fast_floor(yy)) * nx; 02360 int k = (int) xx + ((int) yy) * nx; 02361 float val = Util::bilinear_interpolate(d[k], d[k + 1], d[k + nx], d[k + nx+1], t,u); 02362 if (weight_radial) val *= ypr1; 02363 dd[x + y * xs] = val; 02364 } 02365 02366 } 02367 ret->update(); 02368 02369 EXITFUNC; 02370 return ret; 02371 }