emdata_core.cpp

Go to the documentation of this file.
00001 
00005 /*
00006  * Author: Steven Ludtke, 04/10/2003 (sludtke@bcm.edu)
00007  * Copyright (c) 2000-2006 Baylor College of Medicine
00008  *
00009  * This software is issued under a joint BSD/GNU license. You may use the
00010  * source code in this file under either license. However, note that the
00011  * complete EMAN2 and SPARX software packages have some GPL dependencies,
00012  * so you are responsible for compliance with the licenses of these packages
00013  * if you opt to use BSD licensing. The warranty disclaimer below holds
00014  * in either instance.
00015  *
00016  * This complete copyright notice must be included in any revised version of the
00017  * source code. Additional authorship citations may be added, but existing
00018  * author citations must be preserved.
00019  *
00020  * This program is free software; you can redistribute it and/or modify
00021  * it under the terms of the GNU General Public License as published by
00022  * the Free Software Foundation; either version 2 of the License, or
00023  * (at your option) any later version.
00024  *
00025  * This program is distributed in the hope that it will be useful,
00026  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00027  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00028  * GNU General Public License for more details.
00029  *
00030  * You should have received a copy of the GNU General Public License
00031  * along with this program; if not, write to the Free Software
00032  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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 // debug only
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         nx = 0;
00074         ny = 0;
00075         nz = 0;
00076         nxy = 0;
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 // should these be here? d.woolford I did not comment them out, merely place them here (commented out) to draw attention
00108 //      ret->xoff = xoff;
00109 //      ret->yoff = yoff;
00110 //      ret->zoff = zoff;
00111 //      ret->changecount = changecount;
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; //size of data
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 //for add operation, real and complex image is the same
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 //for add operation, real and complex image is the same
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 //for add operation, real and complex image is the same
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 //for sub operation, real and complex image is the same
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 // just a shortcut for cmp("dot")
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]) {   //do nothing with pixel has value zero
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]) {   //do nothing with pixel has value zero
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]) {   //do nothing with pixel has value zero
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 //real part has half of x dimension for a complex image
00908 {
00909         ENTERFUNC;
00910 
00911         EMData * e = new EMData();
00912 
00913         if( is_real() ) // a real image, return a copy of itself
00914         {
00915                 e = this->copy();
00916         }
00917         else //for a complex image
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                                                 //complex data in format [real, complex, real, complex...]
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() ) {       //a real image has no imaginary part, throw exception
00967                 throw InvalidCallException("No imaginary part for a real image, this function call require a complex image.");
00968         }
00969         else {  //for complex image
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                                                 //complex data in format [real, complex, real, complex...]
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//abs has half of x dimension for a complex image
01002 {
01003         ENTERFUNC;
01004 
01005         EMData * e = new EMData();
01006 
01007         if( is_real() ) // a real image
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 //for a complex image
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                                                 //complex data in format [real, complex, real, complex...]
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                                                 //complex data in format [amp, phase, amp, phase...]
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                                                 //complex data in format [real, complex, real, complex...]
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         //EMUtil::em_memset(get_data(), 0, nxy * nz * sizeof(float));
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)); // This might be faster, I don't know
01247 
01248         update();
01249         EXITFUNC;
01250 }
01251 
01252 

Generated on Sat Nov 21 02:19:15 2009 for EMAN2 by  doxygen 1.5.6