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 throw InvalidValueException(src_data[i], "divide by zero");
00623 }
00624 }
00625 }
00626 else
00627 {
00628 typedef std::complex<float> comp;
00629 for( size_t i = 0; i < size; i+=2 )
00630 {
00631 comp c_src( src_data[i], src_data[i+1] );
00632 comp c_rdat( data[i], data[i+1] );
00633 comp c_result = c_rdat / c_src;
00634 data[i] = c_result.real();
00635 data[i+1] = c_result.imag();
00636 }
00637 }
00638 update();
00639 }
00640
00641 EXITFUNC;
00642 }
00643
00644
00645
00646 float EMData::dot(EMData * with)
00647 {
00648 ENTERFUNC;
00649 if (!with) {
00650 throw NullPointerException("Null EMData Image");
00651 }
00652 DotCmp dot_cmp;
00653 float r = -dot_cmp.cmp(this, with);
00654 EXITFUNC;
00655 return r;
00656 }
00657
00658
00659 EMData *EMData::get_row(int row_index) const
00660 {
00661 ENTERFUNC;
00662
00663 if (get_ndim() > 2) {
00664 throw ImageDimensionException("1D/2D image only");
00665 }
00666
00667 EMData *ret = new EMData();
00668 ret->set_size(nx, 1, 1);
00669 memcpy(ret->get_data(), get_data() + nx * row_index, nx * sizeof(float));
00670 ret->update();
00671 EXITFUNC;
00672 return ret;
00673 }
00674
00675
00676 void EMData::set_row(const EMData * d, int row_index)
00677 {
00678 ENTERFUNC;
00679
00680 if (get_ndim() > 2) {
00681 throw ImageDimensionException("1D/2D image only");
00682 }
00683 if (d->get_ndim() != 1) {
00684 throw ImageDimensionException("1D image only");
00685 }
00686
00687 float *dst = get_data();
00688 float *src = d->get_data();
00689 memcpy(dst + nx * row_index, src, nx * sizeof(float));
00690 update();
00691 EXITFUNC;
00692 }
00693
00694 EMData *EMData::get_col(int col_index) const
00695 {
00696 ENTERFUNC;
00697
00698 if (get_ndim() != 2) {
00699 throw ImageDimensionException("2D image only");
00700 }
00701
00702 EMData *ret = new EMData();
00703 ret->set_size(ny, 1, 1);
00704 float *dst = ret->get_data();
00705 float *src = get_data();
00706
00707 for (int i = 0; i < ny; i++) {
00708 dst[i] = src[i * nx + col_index];
00709 }
00710
00711 ret->update();
00712 EXITFUNC;
00713 return ret;
00714 }
00715
00716
00717 void EMData::set_col(const EMData * d, int n)
00718 {
00719 ENTERFUNC;
00720
00721 if (get_ndim() != 2) {
00722 throw ImageDimensionException("2D image only");
00723 }
00724 if (d->get_ndim() != 1) {
00725 throw ImageDimensionException("1D image only");
00726 }
00727
00728 float *dst = get_data();
00729 float *src = d->get_data();
00730
00731 for (int i = 0; i < ny; i++) {
00732 dst[i * nx + n] = src[i];
00733 }
00734
00735 update();
00736 EXITFUNC;
00737 }
00738
00739 float& EMData::get_value_at_wrap(int x)
00740 {
00741 if (x < 0) x = nx + x;
00742 return get_data()[x];
00743 }
00744
00745 float& EMData::get_value_at_wrap(int x, int y)
00746 {
00747 if (x < 0) x = nx + x;
00748 if (y < 0) y = ny + y;
00749
00750 return get_data()[x + y * nx];
00751 }
00752
00753 float& EMData::get_value_at_wrap(int x, int y, int z)
00754 {
00755 int lx = x;
00756 int ly = y;
00757 int lz = z;
00758 if (lx < 0) lx = nx + lx;
00759 if (ly < 0) ly = ny + ly;
00760 if (lz < 0) lz = nz + lz;
00761
00762 return get_data()[lx + ly * nx + lz * nxy];
00763 }
00764
00765
00766 float EMData::get_value_at_wrap(int x) const
00767 {
00768 if (x < 0) x = nx - x;
00769 return get_data()[x];
00770 }
00771
00772 float EMData::get_value_at_wrap(int x, int y) const
00773 {
00774 if (x < 0) x = nx - x;
00775 if (y < 0) y = ny - y;
00776
00777 return get_data()[x + y * nx];
00778 }
00779
00780 float EMData::get_value_at_wrap(int x, int y, int z) const
00781 {
00782 int lx = x;
00783 int ly = y;
00784 int lz = z;
00785 if (lx < 0) lx = nx + lx;
00786 if (ly < 0) ly = ny + ly;
00787 if (lz < 0) lz = nz + lz;
00788
00789 return get_data()[lx + ly * nx + lz * nxy];
00790 }
00791
00792 float EMData::sget_value_at(int x, int y, int z) const
00793 {
00794 if (x < 0 || x >= nx || y < 0 || y >= ny || z < 0 || z >= nz) {
00795 return 0;
00796 }
00797 return get_data()[x + y * nx + z * nxy];
00798 }
00799
00800
00801 float EMData::sget_value_at(int x, int y) const
00802 {
00803 if (x < 0 || x >= nx || y < 0 || y >= ny) {
00804 return 0;
00805 }
00806 return get_data()[x + y * nx];
00807 }
00808
00809
00810 float EMData::sget_value_at(size_t i) const
00811 {
00812 size_t size = nx*ny;
00813 size *= nz;
00814 if (i >= size) {
00815 return 0;
00816 }
00817 return get_data()[i];
00818 }
00819
00820
00821 float EMData::sget_value_at_interp(float xx, float yy) const
00822 {
00823 int x = static_cast < int >(Util::fast_floor(xx));
00824 int y = static_cast < int >(Util::fast_floor(yy));
00825
00826 float p1 = sget_value_at(x, y);
00827 float p2 = sget_value_at(x + 1, y);
00828 float p3 = sget_value_at(x, y + 1);
00829 float p4 = sget_value_at(x + 1, y + 1);
00830
00831 float result = Util::bilinear_interpolate(p1, p2, p3, p4, xx - x, yy - y);
00832 return result;
00833 }
00834
00835
00836 float EMData::sget_value_at_interp(float xx, float yy, float zz) const
00837 {
00838 int x = (int) Util::fast_floor(xx);
00839 int y = (int) Util::fast_floor(yy);
00840 int z = (int) Util::fast_floor(zz);
00841
00842 float p1 = sget_value_at(x, y, z);
00843 float p2 = sget_value_at(x + 1, y, z);
00844 float p3 = sget_value_at(x, y + 1, z);
00845 float p4 = sget_value_at(x + 1, y + 1, z);
00846
00847 float p5 = sget_value_at(x, y, z + 1);
00848 float p6 = sget_value_at(x + 1, y, z + 1);
00849 float p7 = sget_value_at(x, y + 1, z + 1);
00850 float p8 = sget_value_at(x + 1, y + 1, z + 1);
00851
00852 float result = Util::trilinear_interpolate(p1, p2, p3, p4, p5, p6, p7, p8,
00853 xx - x, yy - y, zz - z);
00854
00855 return result;
00856 }
00857
00858
00859 EMData & EMData::operator+=(float n)
00860 {
00861 add(n);
00862 update();
00863 return *this;
00864 }
00865
00866
00867 EMData & EMData::operator-=(float n)
00868 {
00869 *this += (-n);
00870 return *this;
00871 }
00872
00873
00874 EMData & EMData::operator*=(float n)
00875 {
00876 mult(n);
00877 update();
00878 return *this;
00879 }
00880
00881
00882 EMData & EMData::operator/=(float n)
00883 {
00884 if (n == 0) {
00885 LOGERR("divided by zero");
00886 return *this;
00887 }
00888 *this *= (1.0f / n);
00889 return *this;
00890 }
00891
00892
00893 EMData & EMData::operator+=(const EMData & em)
00894 {
00895 add(em);
00896 update();
00897 return *this;
00898 }
00899
00900
00901 EMData & EMData::operator-=(const EMData & em)
00902 {
00903 sub(em);
00904 update();
00905 return *this;
00906 }
00907
00908
00909 EMData & EMData::operator*=(const EMData & em)
00910 {
00911 mult(em);
00912 update();
00913 return *this;
00914 }
00915
00916
00917 EMData & EMData::operator/=(const EMData & em)
00918 {
00919 div(em);
00920 update();
00921 return *this;
00922 }
00923
00924
00925 EMData * EMData::power(int n) const
00926 {
00927 ENTERFUNC;
00928
00929 if( n<0 ) {
00930 throw InvalidValueException(n, "the power of negative integer not supported.");
00931 }
00932
00933 EMData * r = this->copy();
00934 if( n == 0 ) {
00935 r->to_one();
00936 }
00937 else if( n>1 ) {
00938 for( int i=1; i<n; i++ ) {
00939 *r *= *this;
00940 }
00941 }
00942
00943 r->update();
00944 return r;
00945
00946 EXITFUNC;
00947 }
00948
00949
00950 EMData * EMData::sqrt() const
00951 {
00952 ENTERFUNC;
00953
00954 if (is_complex()) {
00955 throw ImageFormatException("real image only");
00956 }
00957
00958 EMData * r = this->copy();
00959 float * new_data = r->get_data();
00960 float * data = get_data();
00961 size_t size = nxyz;
00962 for (size_t i = 0; i < size; ++i) {
00963 if(data[i] < 0) {
00964 throw InvalidValueException(data[i], "pixel value must be non-negative for logrithm");
00965 }
00966 else {
00967 if(data[i]) {
00968 new_data[i] = std::sqrt(data[i]);
00969 }
00970 }
00971 }
00972
00973 r->update();
00974 return r;
00975
00976 EXITFUNC;
00977 }
00978
00979
00980 EMData * EMData::log() const
00981 {
00982 ENTERFUNC;
00983
00984 if (is_complex()) {
00985 throw ImageFormatException("real image only");
00986 }
00987
00988 EMData * r = this->copy();
00989 float * new_data = r->get_data();
00990 float * data = get_data();
00991 size_t size = nxyz;
00992 for (size_t i = 0; i < size; ++i) {
00993 if(data[i] < 0) {
00994 throw InvalidValueException(data[i], "pixel value must be non-negative for logrithm");
00995 }
00996 else {
00997 if(data[i]) {
00998 new_data[i] = std::log(data[i]);
00999 }
01000 }
01001 }
01002
01003 r->update();
01004 return r;
01005
01006 EXITFUNC;
01007 }
01008
01009
01010 EMData * EMData::log10() const
01011 {
01012 ENTERFUNC;
01013
01014 if (is_complex()) {
01015 throw ImageFormatException("real image only");
01016 }
01017
01018 EMData * r = this->copy();
01019 float * new_data = r->get_data();
01020 float * data = get_data();
01021 size_t size = nxyz;
01022 for (size_t i = 0; i < size; ++i) {
01023 if(data[i] < 0) {
01024 throw InvalidValueException(data[i], "pixel value must be non-negative for logrithm");
01025 }
01026 else {
01027 if(data[i]) {
01028 new_data[i] = std::log10(data[i]);
01029 }
01030 }
01031 }
01032
01033 r->update();
01034 return r;
01035
01036 EXITFUNC;
01037 }
01038
01039
01040 EMData * EMData::real() const
01041 {
01042 ENTERFUNC;
01043
01044 EMData * e = new EMData();
01045
01046 if( is_real() )
01047 {
01048 e = this->copy();
01049 }
01050 else
01051 {
01052 if( !is_ri() )
01053 {
01054 delete e;
01055 throw InvalidCallException("This image is in amplitude/phase format, this function call require a complex image in real/imaginary format.");
01056 }
01057 int nx = get_xsize();
01058 int ny = get_ysize();
01059 int nz = get_zsize();
01060 e->set_size(nx/2, ny, nz);
01061 float * edata = e->get_data();
01062 float * data = get_data();
01063 size_t idx1, idx2;
01064 for( int i=0; i<nx; ++i )
01065 {
01066 for( int j=0; j<ny; ++j )
01067 {
01068 for( int k=0; k<nz; ++k )
01069 {
01070 if( i%2 == 0 )
01071 {
01072
01073 idx1 = i/2+j*(nx/2)+k*(nx/2)*ny;
01074 idx2 = i+j*nx+k*nx*ny;
01075 edata[idx1] = data[idx2];
01076 }
01077 }
01078 }
01079 }
01080 }
01081
01082 e->set_complex(false);
01083 if(e->get_ysize()==1 && e->get_zsize()==1) {
01084 e->set_complex_x(false);
01085 }
01086 e->update();
01087 return e;
01088
01089 EXITFUNC;
01090 }
01091
01092
01093 EMData * EMData::imag() const
01094 {
01095 ENTERFUNC;
01096
01097 EMData * e = new EMData();
01098
01099 if( is_real() ) {
01100 throw InvalidCallException("No imaginary part for a real image, this function call require a complex image.");
01101 }
01102 else {
01103 if( !is_ri() ) {
01104 throw InvalidCallException("This image is in amplitude/phase format, this function call require a complex image in real/imaginary format.");
01105 }
01106 int nx = get_xsize();
01107 int ny = get_ysize();
01108 int nz = get_zsize();
01109 e->set_size(nx/2, ny, nz);
01110 float * edata = e->get_data();
01111 float * data = get_data();
01112 for( int i=0; i<nx; i++ ) {
01113 for( int j=0; j<ny; j++ ) {
01114 for( int k=0; k<nz; k++ ) {
01115 if( i%2 == 1 ) {
01116
01117 edata[i/2+j*(nx/2)+k*(nx/2)*ny] = data[i+j*nx+k*nx*ny];
01118 }
01119 }
01120 }
01121 }
01122 }
01123
01124 e->set_complex(false);
01125 if(e->get_ysize()==1 && e->get_zsize()==1) {
01126 e->set_complex_x(false);
01127 }
01128 e->update();
01129 return e;
01130
01131 EXITFUNC;
01132 }
01133
01134 EMData * EMData::absi() const
01135 {
01136 ENTERFUNC;
01137
01138 EMData * e = new EMData();
01139
01140 if( is_real() )
01141 {
01142 e = this->copy();
01143 int nx = get_xsize();
01144 int ny = get_ysize();
01145 int nz = get_zsize();
01146 float *edata = e->get_data();
01147 float * data = get_data();
01148 size_t idx;
01149 for( int i=0; i<nx; ++i ) {
01150 for( int j=0; j<ny; ++j ) {
01151 for( int k=0; k<nz; ++k ) {
01152 idx = i+j*nx+k*nx*ny;
01153 edata[idx] = std::abs(data[idx]);
01154 }
01155 }
01156 }
01157 }
01158 else
01159 {
01160 if( !is_ri() )
01161 {
01162 throw InvalidCallException("This image is in amplitude/phase format, this function call require a complex image in real/imaginary format.");
01163 }
01164 int nx = get_xsize();
01165 int ny = get_ysize();
01166 int nz = get_zsize();
01167 e->set_size(nx/2, ny, nz);
01168 float * edata = e->get_data();
01169 float * data = get_data();
01170 size_t idx1, idx2;
01171 for( int i=0; i<nx; ++i )
01172 {
01173 for( int j=0; j<ny; ++j )
01174 {
01175 for( int k=0; k<nz; ++k )
01176 {
01177 if( i%2 == 0 )
01178 {
01179 idx1 = i/2+j*(nx/2)+k*(nx/2)*ny;
01180 idx2 = i+j*nx+k*nx*ny;
01181
01182 edata[idx1] =
01183 std::sqrt(data[idx2]*data[idx2]+data[idx2+1]*data[idx2+1]);
01184 }
01185 }
01186 }
01187 }
01188 }
01189
01190 e->set_complex(false);
01191 if(e->get_ysize()==1 && e->get_zsize()==1) {
01192 e->set_complex_x(false);
01193 }
01194 e->update();
01195 return e;
01196
01197 EXITFUNC;
01198 }
01199
01200
01201 EMData * EMData::amplitude() const
01202 {
01203 ENTERFUNC;
01204
01205 EMData * e = new EMData();
01206
01207 if( is_real() ) {
01208 throw InvalidCallException("No imaginary part for a real image, this function call require a complex image.");
01209 }
01210 else {
01211 if(is_ri()) {
01212 throw InvalidCallException("This image is in real/imaginary format, this function call require a complex image in amplitude/phase format.");
01213 }
01214
01215 int nx = get_xsize();
01216 int ny = get_ysize();
01217 int nz = get_zsize();
01218 e->set_size(nx/2, ny, nz);
01219 float * edata = e->get_data();
01220 float * data = get_data();
01221 size_t idx1, idx2;
01222 for( int i=0; i<nx; ++i )
01223 {
01224 for( int j=0; j<ny; ++j )
01225 {
01226 for( int k=0; k<nz; ++k )
01227 {
01228 if( i%2 == 0 )
01229 {
01230 idx1 = i/2+j*(nx/2)+k*(nx/2)*ny;
01231 idx2 = i+j*nx+k*nx*ny;
01232
01233 edata[idx1] = data[idx2];
01234 }
01235 }
01236 }
01237 }
01238 }
01239
01240 e->set_complex(false);
01241 if(e->get_ysize()==1 && e->get_zsize()==1) {
01242 e->set_complex_x(false);
01243 }
01244 e->update();
01245 return e;
01246
01247 EXITFUNC;
01248 }
01249
01250 EMData * EMData::phase() const
01251 {
01252 ENTERFUNC;
01253
01254 EMData * e = new EMData();
01255
01256 if( is_real() ) {
01257 delete e;
01258 throw InvalidCallException("No imaginary part for a real image, this function call require a complex image.");
01259 }
01260 else {
01261 if(is_ri()) {
01262 delete e;
01263 throw InvalidCallException("This image is in real/imaginary format, this function call require a complex image in amplitude/phase format.");
01264 }
01265
01266 int nx = get_xsize();
01267 int ny = get_ysize();
01268 int nz = get_zsize();
01269 e->set_size(nx/2, ny, nz);
01270 float * edata = e->get_data();
01271 float * data = get_data();
01272 size_t idx1, idx2;
01273 for( int i=0; i<nx; ++i ) {
01274 for( int j=0; j<ny; ++j ) {
01275 for( int k=0; k<nz; ++k ) {
01276 if( i%2 == 1 ) {
01277 idx1 = i/2+j*(nx/2)+k*(nx/2)*ny;
01278 idx2 = i+j*nx+k*nx*ny;
01279
01280 edata[idx1] = data[idx2];
01281 }
01282 }
01283 }
01284 }
01285 }
01286
01287 e->set_complex(false);
01288 if(e->get_ysize()==1 && e->get_zsize()==1) {
01289 e->set_complex_x(false);
01290 }
01291 e->update();
01292 return e;
01293
01294 EXITFUNC;
01295 }
01296
01297 EMData * EMData::real2complex(const float img) const
01298 {
01299 ENTERFUNC;
01300
01301 if( is_complex() ) {
01302 throw InvalidCallException("This function call only apply to real image");
01303 }
01304
01305 EMData * e = new EMData();
01306 int nx = get_xsize();
01307 int ny = get_ysize();
01308 int nz = get_zsize();
01309 e->set_size(nx*2, ny, nz);
01310
01311 for( int k=0; k<nz; ++k ) {
01312 for( int j=0; j<ny; ++j ) {
01313 for( int i=0; i<nx; ++i ) {
01314 (*e)(i*2,j,k) = (*this)(i,j,k);
01315 (*e)(i*2+1,j,k) = img;
01316 }
01317 }
01318 }
01319
01320 e->set_complex(true);
01321 if(e->get_ysize()==1 && e->get_zsize()==1) {
01322 e->set_complex_x(true);
01323 }
01324 e->set_ri(true);
01325 e->update();
01326 return e;
01327
01328 EXITFUNC;
01329 }
01330
01331 void EMData::to_zero()
01332 {
01333 ENTERFUNC;
01334
01335 if (is_complex()) {
01336 set_ri(true);
01337 }
01338 else {
01339 set_ri(false);
01340 }
01341
01342
01343 to_value(0.0);
01344 update();
01345 EXITFUNC;
01346 }
01347
01348 void EMData::to_one()
01349 {
01350 ENTERFUNC;
01351
01352 if (is_complex()) {
01353 set_ri(true);
01354 }
01355 else {
01356 set_ri(false);
01357 }
01358 to_value(1.0);
01359
01360 update();
01361 EXITFUNC;
01362 }
01363
01364 void EMData::to_value(const float& value)
01365 {
01366 ENTERFUNC;
01367
01368 #ifdef EMAN2_USING_CUDA
01369 if ( gpu_operation_preferred() ) {
01370 EMDataForCuda tmp = get_data_struct_for_cuda();
01371 emdata_processor_to_value(&tmp,value);
01372 gpu_update();
01373 EXITFUNC;
01374 return;
01375 }
01376 #endif // EMAN2_USING_CUDA
01377 float* data = get_data();
01378 if ( value != 0 ) std::fill(data,data+get_size(),value);
01379 else EMUtil::em_memset(data, 0, nxyz * sizeof(float));
01380
01381 update();
01382 EXITFUNC;
01383 }
01384
01385