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