00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "emdata.h"
00037 #include "ctf.h"
00038 #include "emfft.h"
00039 #include "cmp.h"
00040
00041 using namespace EMAN;
00042
00043
00044 #include <iostream>
00045 #include <cstring>
00046
00047 using std::cout;
00048 using std::endl;
00049
00050 #ifdef EMAN2_USING_CUDA
00051 #include "cuda/cuda_processor.h"
00052 #endif // EMAN2_USING_CUDA
00053
00054 void EMData::free_memory()
00055 {
00056 ENTERFUNC;
00057 if (rdata) {
00058 EMUtil::em_free(rdata);
00059 rdata = 0;
00060 }
00061
00062 if (supp) {
00063 EMUtil::em_free(supp);
00064 supp = 0;
00065 }
00066
00067 if (rot_fp != 0)
00068 {
00069 delete rot_fp;
00070 rot_fp = 0;
00071 }
00072
00073
00074
00075
00076
00077
00078
00079 EXITFUNC;
00080 }
00081
00082 EMData * EMData::copy() const
00083 {
00084 ENTERFUNC;
00085
00086 EMData *ret = new EMData(*this);
00087
00088 EXITFUNC;
00089 return ret;
00090 }
00091
00092
00093 EMData *EMData::copy_head() const
00094 {
00095 ENTERFUNC;
00096 EMData *ret = new EMData();
00097 ret->attr_dict = attr_dict;
00098
00099 ret->set_size(nx, ny, nz);
00100 ret->flags = flags;
00101
00102 ret->all_translation = all_translation;
00103
00104 ret->path = path;
00105 ret->pathnum = pathnum;
00106
00107
00108
00109
00110
00111
00112
00113 ret->update();
00114
00115 EXITFUNC;
00116 return ret;
00117 }
00118
00119 std::complex<float> EMData::get_complex_at(const int &x,const int &y) const{
00120 if (abs(x)>=nx/2 || abs(y)>ny/2) return std::complex<float>(0,0);
00121 if (x>=0 && y>=0) return std::complex<float>(rdata[ x*2+y*nx], rdata[x*2+y*nx+1]);
00122 if (x>0 && y<0) return std::complex<float>( rdata[ x*2+(ny+y)*nx], rdata[x*2+(ny+y)*nx+1]);
00123 if (x<0 && y>0) return std::complex<float>( rdata[-x*2+(ny-y)*nx],-rdata[-x*2+(ny-y)*nx+1]);
00124 return std::complex<float>(rdata[-x*2-y*nx],-rdata[-x*2+-y*nx+1]);
00125 }
00126
00127 std::complex<float> EMData::get_complex_at(const int &x,const int &y,const int &z) const{
00128 if (abs(x)>=nx/2 || abs(y)>ny/2 || abs(z)>nz/2) return std::complex<float>(0,0);
00129
00130 if (x<0) {
00131 int idx=-x*2+(y<=0?-y:ny-y)*nx+(z<=0?-z:nz-z)*nxy;
00132 return std::complex<float>(rdata[idx],rdata[idx+1]);
00133 }
00134
00135 int idx=x*2+(y<0?ny+y:y)*nx+(z<0?nz+z:z)*nxy;
00136 return std::complex<float>(rdata[idx],rdata[idx+1]);
00137 }
00138
00139 size_t EMData::get_complex_index(const int &x,const int &y,const int &z) const {
00140 if (abs(x)>=nx/2 || abs(y)>ny/2 || abs(z)>nz/2) return nxyz;
00141 if (x<0) {
00142 return -x*2+(y<=0?-y:ny-y)*(size_t)nx+(z<=0?-z:nz-z)*(size_t)nxy;
00143 }
00144 return x*2+(y<0?ny+y:y)*(size_t)nx+(z<0?nz+z:z)*(size_t)nxy;
00145 }
00146
00147 size_t EMData::get_complex_index(int x,int y,int z,const int &subx0,const int &suby0,const int &subz0,const int &fullnx,const int &fullny,const int &fullnz) const {
00148 if (abs(x)>=fullnx/2 || abs(y)>fullny/2 || abs(z)>fullnz/2) return nxyz;
00149
00150 if (x<0) {
00151 x*=-1;
00152 y*=-1;
00153 z*=-1;
00154 }
00155 if (y<0) y=fullny+y;
00156 if (z<0) z=fullnz+z;
00157
00158 if (x<subx0||y<suby0||z<subz0||x>=subx0+nx||y>=suby0+ny||z>=subz0+nz) return nxyz;
00159
00160 return (x-subx0)*2+(y-suby0)*(size_t)nx+(z-subz0)*(size_t)nx*(size_t)ny;
00161 }
00162
00163
00164 void EMData::set_complex_at(const int &x,const int &y,const std::complex<float> &val) {
00165 if (abs(x)>=nx/2 || abs(y)>ny/2) return;
00166 if (x>=0 && y>=0) { rdata[ x*2+y*nx]=val.real(); rdata[x*2+y*nx+1]=val.imag(); }
00167 else if (x>0 && y<0) { rdata[ x*2+(ny+y)*nx]=val.real(); rdata[x*2+(ny+y)*nx+1]=val.imag(); }
00168 else if (x<0 && y>0) { rdata[-x*2+(ny-y)*nx]=val.real(); rdata[-x*2+(ny-y)*nx+1]=-val.imag(); }
00169 else { rdata[-x*2-y*nx]=val.real(); rdata[-x*2+-y*nx+1]=-val.imag(); }
00170 return;
00171 }
00172
00173 void EMData::set_complex_at(const int &x,const int &y,const int &z,const std::complex<float> &val) {
00174 if (abs(x)>=nx/2 || abs(y)>ny/2 || abs(z)>nz/2) return;
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185 size_t idx;
00186 if (x<0) {
00187 idx=-x*2+(y<=0?-y:ny-y)*(size_t)nx+(z<=0?-z:nz-z)*(size_t)nxy;
00188 rdata[idx]=(float)val.real();
00189 rdata[idx+1]=-(float)val.imag();
00190 return;
00191 }
00192
00193 idx=x*2+(y<0?ny+y:y)*(size_t)nx+(z<0?nz+z:z)*(size_t)nxy;
00194 rdata[idx]=(float)val.real();
00195 rdata[idx+1]=(float)val.imag();
00196
00197 return;
00198 }
00199
00200 size_t EMData::add_complex_at(const int &x,const int &y,const int &z,const std::complex<float> &val) {
00201
00202 if (x>=nx/2 || y>ny/2 || z>nz/2 || x<=-nx/2 || y<-ny/2 || z<-nz/2) return nxyz;
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212 size_t idx;
00213 if (x<0) {
00214 idx=-x*2+(y<=0?-y:ny-y)*(size_t)nx+(z<=0?-z:nz-z)*(size_t)nxy;
00215 rdata[idx]+=(float)val.real();
00216 rdata[idx+1]-=(float)val.imag();
00217 return idx;
00218 }
00219
00220 idx=x*2+(y<0?ny+y:y)*(size_t)nx+(z<0?nz+z:z)*(size_t)nxy;
00221 rdata[idx]+=(float)val.real();
00222 rdata[idx+1]+=(float)val.imag();
00223
00224 return idx;
00225 }
00226
00227 size_t EMData::add_complex_at(int x,int y,int z,const int &subx0,const int &suby0,const int &subz0,const int &fullnx,const int &fullny,const int &fullnz,const std::complex<float> &val) {
00228 if (abs(x)>=fullnx/2 || abs(y)>fullny/2 || abs(z)>fullnz/2) return nxyz;
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241 float cc=1.0;
00242 if (x<0) {
00243 x*=-1;
00244 y*=-1;
00245 z*=-1;
00246 cc=-1.0;
00247 }
00248 if (y<0) y=fullny+y;
00249 if (z<0) z=fullnz+z;
00250
00251 if (x<subx0||y<suby0||z<subz0||x>=subx0+nx||y>=suby0+ny||z>=subz0+nz) return nxyz;
00252
00253 size_t idx=(x-subx0)*2+(y-suby0)*(size_t)nx+(z-subz0)*(size_t)nx*ny;
00254 rdata[idx]+=(float)val.real();
00255 rdata[idx+1]+=cc*(float)val.imag();
00256 return idx;
00257 }
00258
00259
00260 void EMData::add(float f,int keepzero)
00261 {
00262 ENTERFUNC;
00263
00264 float * data = get_data();
00265 if( is_real() )
00266 {
00267 if (f != 0) {
00268
00269
00270 #ifdef EMAN2_USING_CUDA
00271 if ( gpu_operation_preferred () && !keepzero ) {
00272 EMDataForCuda tmp = get_data_struct_for_cuda();
00273 emdata_processor_add(&tmp,f);
00274 gpu_update();
00275 EXITFUNC;
00276 return;
00277 }
00278 #endif // EMAN2_USING_CUDA
00279 size_t size = nxyz;
00280 if (keepzero) {
00281 for (size_t i = 0; i < size; i++) {
00282 if (data[i]) data[i] += f;
00283 }
00284 }
00285 else {
00286 for (size_t i = 0; i < size; i++) {
00287 data[i] += f;
00288 }
00289 }
00290 update();
00291 }
00292 }
00293 else if( is_complex() )
00294 {
00295 if( f!=0 )
00296 {
00297 update();
00298 size_t size = nx*ny*nz;
00299 if( keepzero )
00300 {
00301 for(size_t i=0; i<size; i+=2)
00302 {
00303 if (data[i]) data[i] += f;
00304 }
00305 }
00306 else
00307 {
00308 for(size_t i=0; i<size; i+=2)
00309 {
00310 data[i] += f;
00311 }
00312 }
00313 }
00314 }
00315 else
00316 {
00317 throw ImageFormatException("This image is neither a real nor a complex image.");
00318 }
00319 update();
00320 EXITFUNC;
00321 }
00322
00323
00324
00325 void EMData::add(const EMData & image)
00326 {
00327 ENTERFUNC;
00328 if (nx != image.get_xsize() || ny != image.get_ysize() || nz != image.get_zsize()) {
00329 throw ImageFormatException( "images not same sizes");
00330 }
00331 else if( (is_real()^image.is_real()) == true )
00332 {
00333 throw ImageFormatException( "not support add between real image and complex image");
00334 }
00335 else {
00336
00337 const float *src_data = image.get_data();
00338 size_t size = nxyz;
00339 float* data = get_data();
00340
00341 for (size_t i = 0; i < size; i++) {
00342 data[i] += src_data[i];
00343 }
00344 update();
00345 }
00346 EXITFUNC;
00347 }
00348
00349
00350 void EMData::addsquare(const EMData & image)
00351 {
00352 ENTERFUNC;
00353 if (nx != image.get_xsize() || ny != image.get_ysize() || nz != image.get_zsize()) {
00354 throw ImageFormatException( "images not same sizes");
00355 }
00356 else if( this->is_complex() || image.is_complex() )
00357 {
00358 throw ImageFormatException( "Cannot addsquare() with complex images");
00359 }
00360 else {
00361
00362 const float *src_data = image.get_data();
00363 size_t size = nxyz;
00364 float* data = get_data();
00365
00366 for (size_t i = 0; i < size; i++) {
00367 data[i] += src_data[i]*src_data[i];
00368 }
00369 update();
00370 }
00371 EXITFUNC;
00372 }
00373
00374
00375 void EMData::subsquare(const EMData & image)
00376 {
00377 ENTERFUNC;
00378 if (nx != image.get_xsize() || ny != image.get_ysize() || nz != image.get_zsize()) {
00379 throw ImageFormatException( "images not same sizes");
00380 }
00381 else if( this->is_complex() || image.is_complex() )
00382 {
00383 throw ImageFormatException( "Cannot addsquare() with complex images");
00384 }
00385 else {
00386
00387 const float *src_data = image.get_data();
00388 size_t size = nxyz;
00389 float* data = get_data();
00390
00391 for (size_t i = 0; i < size; i++) {
00392 data[i] -= src_data[i]*src_data[i];
00393 }
00394 update();
00395 }
00396 EXITFUNC;
00397 }
00398
00399
00400 void EMData::sub(float f)
00401 {
00402 ENTERFUNC;
00403
00404 float* data = get_data();
00405 if( is_real() )
00406 {
00407 if (f != 0) {
00408 #ifdef EMAN2_USING_CUDA
00409 if ( gpu_operation_preferred () ) {
00410 EMDataForCuda tmp = get_data_struct_for_cuda();
00411 emdata_processor_add(&tmp,-f);
00412 gpu_update();
00413 EXITFUNC;
00414 return;
00415 }
00416 #endif // EMAN2_USING_CUDA
00417 size_t size = nxyz;
00418 for (size_t i = 0; i < size; i++) {
00419 data[i] -= f;
00420 }
00421 }
00422 update();
00423 }
00424 else if( is_complex() )
00425 {
00426 if( f != 0 )
00427 {
00428 size_t size = nxyz;
00429 for( size_t i=0; i<size; i+=2 )
00430 {
00431 data[i] -= f;
00432 }
00433 }
00434 update();
00435 }
00436 else
00437 {
00438 throw ImageFormatException("This image is neither a real nor a complex image.");
00439 }
00440
00441 EXITFUNC;
00442 }
00443
00444
00445
00446 void EMData::sub(const EMData & em)
00447 {
00448 ENTERFUNC;
00449
00450 if (nx != em.get_xsize() || ny != em.get_ysize() || nz != em.get_zsize()) {
00451 throw ImageFormatException("images not same sizes");
00452 }
00453 else if( (is_real()^em.is_real()) == true )
00454 {
00455 throw ImageFormatException( "not support sub between real image and complex image");
00456 }
00457 else {
00458 const float *src_data = em.get_data();
00459 size_t size = nxyz;
00460 float* data = get_data();
00461
00462 for (size_t i = 0; i < size; i++) {
00463 data[i] -= src_data[i];
00464 }
00465 update();
00466 }
00467 EXITFUNC;
00468 }
00469
00470
00471 void EMData::mult(float f)
00472 {
00473 ENTERFUNC;
00474
00475
00476 if (is_complex()) {
00477 ap2ri();
00478 }
00479 if (f != 1.0) {
00480 #ifdef EMAN2_USING_CUDA
00481 if ( gpu_operation_preferred () ) {
00482 EMDataForCuda tmp = get_data_struct_for_cuda();
00483 emdata_processor_mult(&tmp,f);
00484 gpu_update();
00485 EXITFUNC;
00486 return;
00487 }
00488 #endif // EMAN2_USING_CUDA
00489 float* data = get_data();
00490 size_t size = nxyz;
00491 for (size_t i = 0; i < size; i++) {
00492 data[i] *= f;
00493 }
00494 update();
00495 }
00496 EXITFUNC;
00497 }
00498
00499
00500 void EMData::mult(const EMData & em, bool prevent_complex_multiplication)
00501 {
00502 ENTERFUNC;
00503
00504 if (nx != em.get_xsize() || ny != em.get_ysize() || nz != em.get_zsize()) {
00505 throw ImageFormatException( "can not multiply images that are not the same size");
00506 }
00507 else if( (is_real()^em.is_real()) == true )
00508 {
00509 throw ImageFormatException( "can not multiply real and complex images.");
00510 }
00511 else
00512 {
00513 const float *src_data = em.get_data();
00514 size_t size = nxyz;
00515 float* data = get_data();
00516 if( is_real() || prevent_complex_multiplication )
00517 {
00518 for (size_t i = 0; i < size; i++) {
00519 data[i] *= src_data[i];
00520 }
00521 }
00522 else
00523 {
00524 typedef std::complex<float> comp;
00525 for( size_t i = 0; i < size; i+=2 )
00526 {
00527 comp c_src( src_data[i], src_data[i+1] );
00528 comp c_rdat( data[i], data[i+1] );
00529 comp c_result = c_src * c_rdat;
00530 data[i] = c_result.real();
00531 data[i+1] = c_result.imag();
00532 }
00533 }
00534 update();
00535 }
00536
00537 EXITFUNC;
00538 }
00539
00540 void EMData::mult_complex_efficient(const EMData & em, const int radius)
00541 {
00542 ENTERFUNC;
00543
00544 if( is_real() || em.is_real() )throw ImageFormatException( "can call mult_complex_efficient unless both images are complex");
00545
00546
00547 const float *src_data = em.get_data();
00548
00549 size_t i_radius = radius;
00550 size_t k_radius = 1;
00551 size_t j_radius = 1;
00552 int ndim = get_ndim();
00553
00554 if (ndim != em.get_ndim()) throw ImageDimensionException("Can't do that");
00555
00556 if ( ndim == 3 ) {
00557 k_radius = radius;
00558 j_radius = radius;
00559 } else if ( ndim == 2 ) {
00560 j_radius = radius;
00561 }
00562
00563
00564 int s_nx = em.get_xsize();
00565 int s_nxy = s_nx*em.get_ysize();
00566
00567 size_t r_size = nxyz;
00568 int s_size = s_nxy*em.get_zsize();
00569 float* data = get_data();
00570
00571 for (size_t k = 0; k < k_radius; ++k ) {
00572 for (size_t j = 0; j < j_radius; j++) {
00573 for (size_t i = 0; i < i_radius; i++) {
00574 int r_idx = k*nxy + j*nx + i;
00575 int s_idx = k*s_nxy + j*s_nx + i;
00576 data[r_idx] *= src_data[s_idx];
00577 data[r_size-r_idx-1] *= src_data[s_size-s_idx-1];
00578 }
00579 }
00580 }
00581
00582 update();
00583
00584 EXITFUNC;
00585 }
00586
00587
00588 void EMData::div(float f)
00589 {
00590 ENTERFUNC;
00591 if ( f == 0 ) {
00592 throw InvalidValueException(f,"Can not divide by zero");
00593 }
00594 mult(1.0f/f);
00595 EXITFUNC;
00596 }
00597
00598
00599 void EMData::div(const EMData & em)
00600 {
00601 ENTERFUNC;
00602
00603 if (nx != em.get_xsize() || ny != em.get_ysize() || nz != em.get_zsize()) {
00604 throw ImageFormatException( "images not same sizes");
00605 }
00606 else if( (is_real()^em.is_real()) == true )
00607 {
00608 throw ImageFormatException( "not support division between real image and complex image");
00609 }
00610 else {
00611 const float *src_data = em.get_data();
00612 size_t size = nxyz;
00613 float* data = get_data();
00614
00615 if( is_real() )
00616 {
00617 for (size_t i = 0; i < size; i++) {
00618 if(src_data[i] != 0) {
00619 data[i] /= src_data[i];
00620 }
00621 else {
00622 if (data[i]==0) continue;
00623 throw InvalidValueException(src_data[i], "divide by zero");
00624 }
00625 }
00626 }
00627 else
00628 {
00629 typedef std::complex<float> comp;
00630 for( size_t i = 0; i < size; i+=2 )
00631 {
00632 comp c_src( src_data[i], src_data[i+1] );
00633 comp c_rdat( data[i], data[i+1] );
00634 comp c_result = c_rdat / c_src;
00635 data[i] = c_result.real();
00636 data[i+1] = c_result.imag();
00637 }
00638 }
00639 update();
00640 }
00641
00642 EXITFUNC;
00643 }
00644
00645
00646
00647 float EMData::dot(EMData * with)
00648 {
00649 ENTERFUNC;
00650 if (!with) {
00651 throw NullPointerException("Null EMData Image");
00652 }
00653 DotCmp dot_cmp;
00654 float r = -dot_cmp.cmp(this, with);
00655 EXITFUNC;
00656 return r;
00657 }
00658
00659
00660 EMData *EMData::get_row(int row_index) const
00661 {
00662 ENTERFUNC;
00663
00664 if (get_ndim() > 2) {
00665 throw ImageDimensionException("1D/2D image only");
00666 }
00667
00668 EMData *ret = new EMData();
00669 ret->set_size(nx, 1, 1);
00670 memcpy(ret->get_data(), get_data() + nx * row_index, nx * sizeof(float));
00671 ret->update();
00672 EXITFUNC;
00673 return ret;
00674 }
00675
00676
00677 void EMData::set_row(const EMData * d, int row_index)
00678 {
00679 ENTERFUNC;
00680
00681 if (get_ndim() > 2) {
00682 throw ImageDimensionException("1D/2D image only");
00683 }
00684 if (d->get_ndim() != 1) {
00685 throw ImageDimensionException("1D image only");
00686 }
00687
00688 float *dst = get_data();
00689 float *src = d->get_data();
00690 memcpy(dst + nx * row_index, src, nx * sizeof(float));
00691 update();
00692 EXITFUNC;
00693 }
00694
00695 EMData *EMData::get_col(int col_index) const
00696 {
00697 ENTERFUNC;
00698
00699 if (get_ndim() != 2) {
00700 throw ImageDimensionException("2D image only");
00701 }
00702
00703 EMData *ret = new EMData();
00704 ret->set_size(ny, 1, 1);
00705 float *dst = ret->get_data();
00706 float *src = get_data();
00707
00708 for (int i = 0; i < ny; i++) {
00709 dst[i] = src[i * nx + col_index];
00710 }
00711
00712 ret->update();
00713 EXITFUNC;
00714 return ret;
00715 }
00716
00717
00718 void EMData::set_col(const EMData * d, int n)
00719 {
00720 ENTERFUNC;
00721
00722 if (get_ndim() != 2) {
00723 throw ImageDimensionException("2D image only");
00724 }
00725 if (d->get_ndim() != 1) {
00726 throw ImageDimensionException("1D image only");
00727 }
00728
00729 float *dst = get_data();
00730 float *src = d->get_data();
00731
00732 for (int i = 0; i < ny; i++) {
00733 dst[i * nx + n] = src[i];
00734 }
00735
00736 update();
00737 EXITFUNC;
00738 }
00739
00740 float& EMData::get_value_at_wrap(int x)
00741 {
00742 if (x < 0) x = nx + x;
00743 return get_data()[x];
00744 }
00745
00746 float& EMData::get_value_at_wrap(int x, int y)
00747 {
00748 if (x < 0) x = nx + x;
00749 if (y < 0) y = ny + y;
00750
00751 return get_data()[x + y * nx];
00752 }
00753
00754 float& EMData::get_value_at_wrap(int x, int y, int z)
00755 {
00756 int lx = x;
00757 int ly = y;
00758 int lz = z;
00759 if (lx < 0) lx = nx + lx;
00760 if (ly < 0) ly = ny + ly;
00761 if (lz < 0) lz = nz + lz;
00762
00763 return get_data()[lx + ly * nx + lz * nxy];
00764 }
00765
00766
00767 float EMData::get_value_at_wrap(int x) const
00768 {
00769 if (x < 0) x = nx - x;
00770 return get_data()[x];
00771 }
00772
00773 float EMData::get_value_at_wrap(int x, int y) const
00774 {
00775 if (x < 0) x = nx - x;
00776 if (y < 0) y = ny - y;
00777
00778 return get_data()[x + y * nx];
00779 }
00780
00781 float EMData::get_value_at_wrap(int x, int y, int z) const
00782 {
00783 int lx = x;
00784 int ly = y;
00785 int lz = z;
00786 if (lx < 0) lx = nx + lx;
00787 if (ly < 0) ly = ny + ly;
00788 if (lz < 0) lz = nz + lz;
00789
00790 return get_data()[lx + ly * nx + lz * nxy];
00791 }
00792
00793 float EMData::sget_value_at(int x, int y, int z) const
00794 {
00795 if (x < 0 || x >= nx || y < 0 || y >= ny || z < 0 || z >= nz) {
00796 return 0;
00797 }
00798 return get_data()[x + y * nx + z * nxy];
00799 }
00800
00801
00802 float EMData::sget_value_at(int x, int y) const
00803 {
00804 if (x < 0 || x >= nx || y < 0 || y >= ny) {
00805 return 0;
00806 }
00807 return get_data()[x + y * nx];
00808 }
00809
00810
00811 float EMData::sget_value_at(size_t i) const
00812 {
00813 size_t size = nx*ny;
00814 size *= nz;
00815 if (i >= size) {
00816 return 0;
00817 }
00818 return get_data()[i];
00819 }
00820
00821
00822 float EMData::sget_value_at_interp(float xx, float yy) const
00823 {
00824 int x = static_cast < int >(Util::fast_floor(xx));
00825 int y = static_cast < int >(Util::fast_floor(yy));
00826
00827 float p1 = sget_value_at(x, y);
00828 float p2 = sget_value_at(x + 1, y);
00829 float p3 = sget_value_at(x, y + 1);
00830 float p4 = sget_value_at(x + 1, y + 1);
00831
00832 float result = Util::bilinear_interpolate(p1, p2, p3, p4, xx - x, yy - y);
00833 return result;
00834 }
00835
00836
00837 float EMData::sget_value_at_interp(float xx, float yy, float zz) const
00838 {
00839 int x = (int) Util::fast_floor(xx);
00840 int y = (int) Util::fast_floor(yy);
00841 int z = (int) Util::fast_floor(zz);
00842
00843 float p1 = sget_value_at(x, y, z);
00844 float p2 = sget_value_at(x + 1, y, z);
00845 float p3 = sget_value_at(x, y + 1, z);
00846 float p4 = sget_value_at(x + 1, y + 1, z);
00847
00848 float p5 = sget_value_at(x, y, z + 1);
00849 float p6 = sget_value_at(x + 1, y, z + 1);
00850 float p7 = sget_value_at(x, y + 1, z + 1);
00851 float p8 = sget_value_at(x + 1, y + 1, z + 1);
00852
00853 float result = Util::trilinear_interpolate(p1, p2, p3, p4, p5, p6, p7, p8,
00854 xx - x, yy - y, zz - z);
00855
00856 return result;
00857 }
00858
00859
00860 EMData & EMData::operator+=(float n)
00861 {
00862 add(n);
00863 update();
00864 return *this;
00865 }
00866
00867
00868 EMData & EMData::operator-=(float n)
00869 {
00870 *this += (-n);
00871 return *this;
00872 }
00873
00874
00875 EMData & EMData::operator*=(float n)
00876 {
00877 mult(n);
00878 update();
00879 return *this;
00880 }
00881
00882
00883 EMData & EMData::operator/=(float n)
00884 {
00885 if (n == 0) {
00886 LOGERR("divided by zero");
00887 return *this;
00888 }
00889 *this *= (1.0f / n);
00890 return *this;
00891 }
00892
00893
00894 EMData & EMData::operator+=(const EMData & em)
00895 {
00896 add(em);
00897 update();
00898 return *this;
00899 }
00900
00901
00902 EMData & EMData::operator-=(const EMData & em)
00903 {
00904 sub(em);
00905 update();
00906 return *this;
00907 }
00908
00909
00910 EMData & EMData::operator*=(const EMData & em)
00911 {
00912 mult(em);
00913 update();
00914 return *this;
00915 }
00916
00917
00918 EMData & EMData::operator/=(const EMData & em)
00919 {
00920 div(em);
00921 update();
00922 return *this;
00923 }
00924
00925
00926 EMData * EMData::power(int n) const
00927 {
00928 ENTERFUNC;
00929
00930 if( n<0 ) {
00931 throw InvalidValueException(n, "the power of negative integer not supported.");
00932 }
00933
00934 EMData * r = this->copy();
00935 if( n == 0 ) {
00936 r->to_one();
00937 }
00938 else if( n>1 ) {
00939 for( int i=1; i<n; i++ ) {
00940 *r *= *this;
00941 }
00942 }
00943
00944 r->update();
00945 return r;
00946
00947 EXITFUNC;
00948 }
00949
00950
00951 EMData * EMData::sqrt() const
00952 {
00953 ENTERFUNC;
00954
00955 if (is_complex()) {
00956 throw ImageFormatException("real image only");
00957 }
00958
00959 EMData * r = this->copy();
00960 float * new_data = r->get_data();
00961 float * data = get_data();
00962 size_t size = nxyz;
00963 for (size_t i = 0; i < size; ++i) {
00964 if(data[i] < 0) {
00965 throw InvalidValueException(data[i], "pixel value must be non-negative for logrithm");
00966 }
00967 else {
00968 if(data[i]) {
00969 new_data[i] = std::sqrt(data[i]);
00970 }
00971 }
00972 }
00973
00974 r->update();
00975 return r;
00976
00977 EXITFUNC;
00978 }
00979
00980
00981 EMData * EMData::log() const
00982 {
00983 ENTERFUNC;
00984
00985 if (is_complex()) {
00986 throw ImageFormatException("real image only");
00987 }
00988
00989 EMData * r = this->copy();
00990 float * new_data = r->get_data();
00991 float * data = get_data();
00992 size_t size = nxyz;
00993 for (size_t i = 0; i < size; ++i) {
00994 if(data[i] < 0) {
00995 throw InvalidValueException(data[i], "pixel value must be non-negative for logrithm");
00996 }
00997 else {
00998 if(data[i]) {
00999 new_data[i] = std::log(data[i]);
01000 }
01001 }
01002 }
01003
01004 r->update();
01005 return r;
01006
01007 EXITFUNC;
01008 }
01009
01010
01011 EMData * EMData::log10() const
01012 {
01013 ENTERFUNC;
01014
01015 if (is_complex()) {
01016 throw ImageFormatException("real image only");
01017 }
01018
01019 EMData * r = this->copy();
01020 float * new_data = r->get_data();
01021 float * data = get_data();
01022 size_t size = nxyz;
01023 for (size_t i = 0; i < size; ++i) {
01024 if(data[i] < 0) {
01025 throw InvalidValueException(data[i], "pixel value must be non-negative for logrithm");
01026 }
01027 else {
01028 if(data[i]) {
01029 new_data[i] = std::log10(data[i]);
01030 }
01031 }
01032 }
01033
01034 r->update();
01035 return r;
01036
01037 EXITFUNC;
01038 }
01039
01040
01041 EMData * EMData::real() const
01042 {
01043 ENTERFUNC;
01044
01045 EMData * e = new EMData();
01046
01047 if( is_real() )
01048 {
01049 e = this->copy();
01050 }
01051 else
01052 {
01053 if( !is_ri() )
01054 {
01055 delete e;
01056 throw InvalidCallException("This image is in amplitude/phase format, this function call require a complex image in real/imaginary format.");
01057 }
01058 int nx = get_xsize();
01059 int ny = get_ysize();
01060 int nz = get_zsize();
01061 e->set_size(nx/2, ny, nz);
01062 float * edata = e->get_data();
01063 float * data = get_data();
01064 size_t idx1, idx2;
01065 for( int i=0; i<nx; ++i )
01066 {
01067 for( int j=0; j<ny; ++j )
01068 {
01069 for( int k=0; k<nz; ++k )
01070 {
01071 if( i%2 == 0 )
01072 {
01073
01074 idx1 = i/2+j*(nx/2)+k*(nx/2)*ny;
01075 idx2 = i+j*nx+k*nx*ny;
01076 edata[idx1] = data[idx2];
01077 }
01078 }
01079 }
01080 }
01081 }
01082
01083 e->set_complex(false);
01084 if(e->get_ysize()==1 && e->get_zsize()==1) {
01085 e->set_complex_x(false);
01086 }
01087 e->update();
01088 return e;
01089
01090 EXITFUNC;
01091 }
01092
01093
01094 EMData * EMData::imag() const
01095 {
01096 ENTERFUNC;
01097
01098 EMData * e = new EMData();
01099
01100 if( is_real() ) {
01101 throw InvalidCallException("No imaginary part for a real image, this function call require a complex image.");
01102 }
01103 else {
01104 if( !is_ri() ) {
01105 throw InvalidCallException("This image is in amplitude/phase format, this function call require a complex image in real/imaginary format.");
01106 }
01107 int nx = get_xsize();
01108 int ny = get_ysize();
01109 int nz = get_zsize();
01110 e->set_size(nx/2, ny, nz);
01111 float * edata = e->get_data();
01112 float * data = get_data();
01113 for( int i=0; i<nx; i++ ) {
01114 for( int j=0; j<ny; j++ ) {
01115 for( int k=0; k<nz; k++ ) {
01116 if( i%2 == 1 ) {
01117
01118 edata[i/2+j*(nx/2)+k*(nx/2)*ny] = data[i+j*nx+k*nx*ny];
01119 }
01120 }
01121 }
01122 }
01123 }
01124
01125 e->set_complex(false);
01126 if(e->get_ysize()==1 && e->get_zsize()==1) {
01127 e->set_complex_x(false);
01128 }
01129 e->update();
01130 return e;
01131
01132 EXITFUNC;
01133 }
01134
01135 EMData * EMData::absi() const
01136 {
01137 ENTERFUNC;
01138
01139 EMData * e = new EMData();
01140
01141 if( is_real() )
01142 {
01143 e = this->copy();
01144 int nx = get_xsize();
01145 int ny = get_ysize();
01146 int nz = get_zsize();
01147 float *edata = e->get_data();
01148 float * data = get_data();
01149 size_t idx;
01150 for( int i=0; i<nx; ++i ) {
01151 for( int j=0; j<ny; ++j ) {
01152 for( int k=0; k<nz; ++k ) {
01153 idx = i+j*nx+k*nx*ny;
01154 edata[idx] = std::abs(data[idx]);
01155 }
01156 }
01157 }
01158 }
01159 else
01160 {
01161 if( !is_ri() )
01162 {
01163 throw InvalidCallException("This image is in amplitude/phase format, this function call require a complex image in real/imaginary format.");
01164 }
01165 int nx = get_xsize();
01166 int ny = get_ysize();
01167 int nz = get_zsize();
01168 e->set_size(nx/2, ny, nz);
01169 float * edata = e->get_data();
01170 float * data = get_data();
01171 size_t idx1, idx2;
01172 for( int i=0; i<nx; ++i )
01173 {
01174 for( int j=0; j<ny; ++j )
01175 {
01176 for( int k=0; k<nz; ++k )
01177 {
01178 if( i%2 == 0 )
01179 {
01180 idx1 = i/2+j*(nx/2)+k*(nx/2)*ny;
01181 idx2 = i+j*nx+k*nx*ny;
01182
01183 edata[idx1] =
01184 std::sqrt(data[idx2]*data[idx2]+data[idx2+1]*data[idx2+1]);
01185 }
01186 }
01187 }
01188 }
01189 }
01190
01191 e->set_complex(false);
01192 if(e->get_ysize()==1 && e->get_zsize()==1) {
01193 e->set_complex_x(false);
01194 }
01195 e->update();
01196 return e;
01197
01198 EXITFUNC;
01199 }
01200
01201
01202 EMData * EMData::amplitude() const
01203 {
01204 ENTERFUNC;
01205
01206 EMData * e = new EMData();
01207
01208 if( is_real() ) {
01209 throw InvalidCallException("No imaginary part for a real image, this function call require a complex image.");
01210 }
01211 else {
01212 if(is_ri()) {
01213 throw InvalidCallException("This image is in real/imaginary format, this function call require a complex image in amplitude/phase format.");
01214 }
01215
01216 int nx = get_xsize();
01217 int ny = get_ysize();
01218 int nz = get_zsize();
01219 e->set_size(nx/2, ny, nz);
01220 float * edata = e->get_data();
01221 float * data = get_data();
01222 size_t idx1, idx2;
01223 for( int i=0; i<nx; ++i )
01224 {
01225 for( int j=0; j<ny; ++j )
01226 {
01227 for( int k=0; k<nz; ++k )
01228 {
01229 if( i%2 == 0 )
01230 {
01231 idx1 = i/2+j*(nx/2)+k*(nx/2)*ny;
01232 idx2 = i+j*nx+k*nx*ny;
01233
01234 edata[idx1] = data[idx2];
01235 }
01236 }
01237 }
01238 }
01239 }
01240
01241 e->set_complex(false);
01242 if(e->get_ysize()==1 && e->get_zsize()==1) {
01243 e->set_complex_x(false);
01244 }
01245 e->update();
01246 return e;
01247
01248 EXITFUNC;
01249 }
01250
01251 EMData * EMData::phase() const
01252 {
01253 ENTERFUNC;
01254
01255 EMData * e = new EMData();
01256
01257 if( is_real() ) {
01258 delete e;
01259 throw InvalidCallException("No imaginary part for a real image, this function call require a complex image.");
01260 }
01261 else {
01262 if(is_ri()) {
01263 delete e;
01264 throw InvalidCallException("This image is in real/imaginary format, this function call require a complex image in amplitude/phase format.");
01265 }
01266
01267 int nx = get_xsize();
01268 int ny = get_ysize();
01269 int nz = get_zsize();
01270 e->set_size(nx/2, ny, nz);
01271 float * edata = e->get_data();
01272 float * data = get_data();
01273 size_t idx1, idx2;
01274 for( int i=0; i<nx; ++i ) {
01275 for( int j=0; j<ny; ++j ) {
01276 for( int k=0; k<nz; ++k ) {
01277 if( i%2 == 1 ) {
01278 idx1 = i/2+j*(nx/2)+k*(nx/2)*ny;
01279 idx2 = i+j*nx+k*nx*ny;
01280
01281 edata[idx1] = data[idx2];
01282 }
01283 }
01284 }
01285 }
01286 }
01287
01288 e->set_complex(false);
01289 if(e->get_ysize()==1 && e->get_zsize()==1) {
01290 e->set_complex_x(false);
01291 }
01292 e->update();
01293 return e;
01294
01295 EXITFUNC;
01296 }
01297
01298 EMData * EMData::real2complex(const float img) const
01299 {
01300 ENTERFUNC;
01301
01302 if( is_complex() ) {
01303 throw InvalidCallException("This function call only apply to real image");
01304 }
01305
01306 EMData * e = new EMData();
01307 int nx = get_xsize();
01308 int ny = get_ysize();
01309 int nz = get_zsize();
01310 e->set_size(nx*2, ny, nz);
01311
01312 for( int k=0; k<nz; ++k ) {
01313 for( int j=0; j<ny; ++j ) {
01314 for( int i=0; i<nx; ++i ) {
01315 (*e)(i*2,j,k) = (*this)(i,j,k);
01316 (*e)(i*2+1,j,k) = img;
01317 }
01318 }
01319 }
01320
01321 e->set_complex(true);
01322 if(e->get_ysize()==1 && e->get_zsize()==1) {
01323 e->set_complex_x(true);
01324 }
01325 e->set_ri(true);
01326 e->update();
01327 return e;
01328
01329 EXITFUNC;
01330 }
01331
01332 void EMData::to_zero()
01333 {
01334 ENTERFUNC;
01335
01336 if (is_complex()) {
01337 set_ri(true);
01338 }
01339 else {
01340 set_ri(false);
01341 }
01342
01343
01344 to_value(0.0);
01345 update();
01346 EXITFUNC;
01347 }
01348
01349 void EMData::to_one()
01350 {
01351 ENTERFUNC;
01352
01353 if (is_complex()) {
01354 set_ri(true);
01355 }
01356 else {
01357 set_ri(false);
01358 }
01359 to_value(1.0);
01360
01361 update();
01362 EXITFUNC;
01363 }
01364
01365 void EMData::to_value(const float& value)
01366 {
01367 ENTERFUNC;
01368
01369 #ifdef EMAN2_USING_CUDA
01370 if ( gpu_operation_preferred() ) {
01371 EMDataForCuda tmp = get_data_struct_for_cuda();
01372 emdata_processor_to_value(&tmp,value);
01373 gpu_update();
01374 EXITFUNC;
01375 return;
01376 }
01377 #endif // EMAN2_USING_CUDA
01378 float* data = get_data();
01379 if ( value != 0 ) std::fill(data,data+get_size(),value);
01380 else EMUtil::em_memset(data, 0, nxyz * sizeof(float));
01381
01382 update();
01383 EXITFUNC;
01384 }
01385
01386