EMAN2
emdata_core.h
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 
00040 #ifndef emdata__core_h__
00041 #define emdata__core_h__
00042 
00043 public:
00047 EMData *copy() const;
00048 
00049 
00053 EMData *copy_head() const;
00054 
00055 
00060 void add(float f,int keepzero=0);
00061 
00062 
00068 void add(const EMData & image);
00069 
00075 void addsquare(const EMData & image);
00076 
00077 
00081 void sub(float f);
00082 
00083 
00088 void sub(const EMData & image);
00089 
00095 void subsquare(const EMData & image);
00096 
00097 
00101 void mult(int n)
00102 {
00103         mult((float)n);
00104 }
00105 
00106 
00110 void mult(float f);
00111 
00112 
00120 void mult(const EMData & image, bool prevent_complex_multiplication=false);
00121 
00122 void mult_complex_efficient(const EMData & em, const int radius);
00123 
00127 void div(float f);
00128 
00129 
00135 void div(const EMData & image);
00136 
00138 void to_zero();
00139 
00140 
00142 void to_one();
00143 
00145 void to_value(const float& value);
00146 
00157 float dot(EMData * with);
00158 
00159 
00166 EMData *get_row(int row_index) const;
00167 
00168 
00175 void set_row(const EMData * data, int row_index);
00176 
00177 
00184 EMData *get_col(int col_index) const;
00185 
00186 
00193 void set_col(const EMData * data, int col_index);
00194 
00195 
00204 inline float get_value_at(int x, int y, int z) const
00205 {
00206         return get_data()[(size_t)x + (size_t)y * (size_t)nx + (size_t)z * (size_t)nxy];
00207 }
00208 
00212 inline float get_value_at_index(int i)
00213 {
00214         return *(rdata + i);
00215 }
00216 
00224 inline float get_value_at(int x, int y) const
00225 {
00226         return get_data()[x + y * nx];
00227 }
00228 
00229 
00237 inline float get_value_at(size_t i) const
00238 {
00239         return get_data()[i];
00240 }
00241 
00253 std::complex<float> get_complex_at(const int &x,const int &y) const;
00254 
00267 std::complex<float> get_complex_at(const int &x,const int &y,const int &z) const;
00268 
00281 size_t get_complex_index(const int &x,const int &y,const int &z) const;
00282 
00283 size_t 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;
00284 
00285 inline size_t get_complex_index_fast(const int &x,const int &y,const int &z) const {
00286 //      if (abs(x)>=nx/2 || abs(y)>ny/2 || abs(z)>nz/2) return nxyz;
00287         if (x<0) {
00288                 return (size_t)x*-2+(y<=0?-y:ny-y)*(size_t)nx+(z<=0?-z:nz-z)*(size_t)nxy;
00289         }
00290         return x*2+(y<0?ny+y:y)*(size_t)nx+(z<0?nz+z:z)*(size_t)nxy;
00291 }
00292 
00305 void set_complex_at(const int &x,const int &y,const std::complex<float> &val);
00306 
00320 void set_complex_at(const int &x,const int &y,const int &z,const std::complex<float> &val);
00321 
00335 size_t add_complex_at(const int &x,const int &y,const int &z,const std::complex<float> &val);
00336 
00337 inline size_t add_complex_at_fast(const int &x,const int &y,const int &z,const std::complex<float> &val) {
00338 //if (x>=nx/2 || y>ny/2 || z>nz/2 || x<=-nx/2 || y<-ny/2 || z<-nz/2) return nxyz;
00339 
00340 size_t idx;
00341 if (x<0) {
00342         idx=-x*2+(y<=0?-y:ny-y)*(size_t)nx+(z<=0?-z:nz-z)*(size_t)nxy;
00343         rdata[idx]+=(float)val.real();
00344         rdata[idx+1]-=(float)val.imag();
00345         return idx;
00346 }
00347 
00348 idx=x*2+(y<0?ny+y:y)*(size_t)nx+(z<0?nz+z:z)*(size_t)nxy;
00349 rdata[idx]+=(float)val.real();
00350 rdata[idx+1]+=(float)val.imag();
00351 
00352 return idx;
00353 }
00354 
00366 size_t 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);
00367 
00377 float get_value_at_wrap(int x, int y, int z) const;
00378 float& get_value_at_wrap(int x, int y, int z);
00379 
00388 float get_value_at_wrap(int x, int y) const;
00389 float& get_value_at_wrap(int x, int y);
00390 
00398 float get_value_at_wrap(int x) const;
00399 float& get_value_at_wrap(int x);
00400 
00405 inline float sget_value_at(Vec3i v) { return sget_value_at(v[0],v[1],v[2]); }
00406 
00416 float sget_value_at(int x, int y, int z) const;
00417 
00418 
00427 float sget_value_at(int x, int y) const;
00428 
00429 
00438 float sget_value_at(size_t i) const;
00439 
00440 
00448 float sget_value_at_interp(float x, float y) const;
00449 
00450 
00459 float sget_value_at_interp(float x, float y, float z) const;
00460 
00465 inline void set_value_at(Vec3i loc,float val) { set_value_at(loc[0],loc[1],loc[2],val); }
00466 
00476 inline void set_value_at(int x, int y, int z, float v)
00477 {
00478         if( x>=nx || x<0 )
00479         {
00480                 throw OutofRangeException(0, nx-1, x, "x dimension index");
00481         }
00482         else if( y>=ny || y<0 )
00483         {
00484                 throw OutofRangeException(0, ny-1, y, "y dimension index");
00485         }
00486         else if( z>=nz || z<0 )
00487         {
00488                 throw OutofRangeException(0, nz-1, z, "z dimension index");
00489         }
00490         else
00491         {
00492                 get_data()[(size_t)x + (size_t)y * (size_t)nx + (size_t)z * (size_t)nxy] = v;
00493                 update();
00494         }
00495 }
00496 
00497 
00507 inline void set_value_at_fast(int x, int y, int z, float v)
00508 {
00509         get_data()[(size_t)x + (size_t)y * (size_t)nx + (size_t)z * (size_t)nxy] = v;
00510         update();
00511 }
00512 
00519 inline void set_value_at_index(int i, float v)
00520 {
00521         *(rdata + i) = v;
00522 }
00523 
00532 inline void set_value_at(int x, int y, float v)
00533 {
00534         if( x>=nx || x<0 )
00535         {
00536                 throw OutofRangeException(0, nx-1, x, "x dimension index");
00537         }
00538         else if( y>=ny || y<0 )
00539         {
00540                 throw OutofRangeException(0, ny-1, y, "y dimension index");
00541         }
00542         else
00543         {
00544                 get_data()[x + y * nx] = v;
00545                 update();
00546                 
00547         }
00548 }
00549 
00550 
00558 inline void set_value_at_fast(int x, int y, float v)
00559 {
00560         get_data()[x + y * nx] = v;
00561         update();
00562 }
00563 
00564 
00572 inline void set_value_at(int x, float v)
00573 {
00574         if( x>=nx || x<0 )
00575         {
00576                 throw OutofRangeException(0, nx-1, x, "x dimension index");
00577         }
00578         else
00579         {
00580                 get_data()[x] = v;
00581 
00582                 update();
00583         }
00584 }
00585 
00592 inline void set_value_at_fast(int x, float v)
00593 {
00594         get_data()[x] = v;
00595 
00596         update();
00597 }
00598 
00599 
00603 void free_memory();
00604 
00608 void free_rdata();
00609 
00610 EMData & operator+=(float n);
00611 EMData & operator-=(float n);
00612 EMData & operator*=(float n);
00613 EMData & operator/=(float n);
00614 
00615 EMData & operator+=(const EMData & em);
00616 EMData & operator-=(const EMData & em);
00617 EMData & operator*=(const EMData & em);
00618 EMData & operator/=(const EMData & em);
00619 
00620 bool operator==(const EMData& that) const;
00622 bool equal(const EMData& that) const;
00623 
00625 inline float& operator()(const int ix, const int iy, const int iz) const {
00626         ptrdiff_t pos = (size_t)(ix-xoff) + ((iy-yoff) + (size_t)(iz-zoff)*ny)*nx;
00627 #ifdef BOUNDS_CHECKING
00628         if (pos < 0 || pos >= (size_t)nx*ny*nz) {
00629                 throw OutofRangeException(0, (size_t)nx*ny*nz-1, pos, "EMData");
00630         }
00631 #endif // BOUNDS_CHECKING
00632         return *(get_data() + pos);
00633 }
00634 
00635 inline float& operator()(const int ix, const int iy) const {
00636         ptrdiff_t pos = (ix - xoff) + (iy-yoff)*nx;
00637 #ifdef BOUNDS_CHECKING
00638         if (pos < 0 || pos >= (size_t)nx*ny*nz)
00639         {
00640                 throw OutofRangeException(0, (size_t)nx*ny*nz-1, pos, "EMData");
00641         }
00642 #endif // BOUNDS_CHECKING
00643         return *(get_data() + pos);
00644 }
00645 
00646 
00647 inline float& operator()(const size_t ix) const {
00648         ptrdiff_t pos = ix - xoff;
00649 #ifdef BOUNDS_CHECKING
00650         if (pos < 0 || pos >= (size_t)nx*ny*nz)
00651                 throw OutofRangeException(0, (size_t)nx*ny*nz-1, pos, "EMData");
00652 #endif // BOUNDS_CHECKING
00653         return *(get_data() + pos);
00654 }
00655 
00656 
00658 void set_array_offsets(const int xoff_=0, const int yoff_=0,
00659                                const int zoff_=0) {
00660         xoff=xoff_; yoff=yoff_; zoff=zoff_;
00661 }
00662 
00663 
00664 void set_array_offsets(vector<int> offsets) {
00665         set_array_offsets(offsets[0],offsets[1],offsets[2]);
00666 }
00667 
00668 
00669 vector<int> get_array_offsets() {
00670         vector<int> offsets;
00671         offsets.push_back(xoff);
00672         offsets.push_back(yoff);
00673         offsets.push_back(zoff);
00674         return offsets;
00675 }
00676 
00677 
00679 std::complex<float>& cmplx(const int ix, const int iy, const int iz) {
00680         ptrdiff_t pos = 2*(ix-xoff)+((iy-yoff)+(iz-zoff)*ny)*(size_t)nx;
00681 #ifdef BOUNDS_CHECKING
00682         if (pos < 0 || pos >= (size_t)nx*ny*nz)
00683                 throw OutofRangeException(0, (size_t)nx*ny*nz-1, pos, "EMData");
00684 #endif // BOUNDS_CHECKING
00685         float* begin = get_data() + pos;
00686         return *(reinterpret_cast<std::complex<float>* >(begin));
00687 }
00688 
00689 
00690 std::complex<float>& cmplx(const int ix, const int iy) {
00691         ptrdiff_t pos = 2*(ix-xoff)+(iy-yoff)*nx;
00692 #ifdef BOUNDS_CHECKING
00693         if (pos < 0 || pos >= (size_t)nx*ny*nz)
00694                 throw OutofRangeException(0, (size_t)nx*ny*nz-1, pos, "EMData");
00695 #endif // BOUNDS_CHECKING
00696         float* begin = get_data() + pos;
00697         return *(reinterpret_cast<std::complex<float>* >(begin));
00698 }
00699 
00700 
00701 std::complex<float>& cmplx(const int ix) {
00702         ptrdiff_t pos = 2*(ix-xoff);
00703 #ifdef BOUNDS_CHECKING
00704         if (pos < 0 || pos >= (size_t)nx*ny*nz)
00705                 throw OutofRangeException(0, (size_t)nx*ny*nz-1, pos, "EMData");
00706 #endif // BOUNDS_CHECKING
00707         float* begin = get_data() + pos;
00708         return *(reinterpret_cast<std::complex<float>* >(begin));
00709 }
00710 
00711 
00717 EMData * power(int n) const;
00718 
00723 EMData * sqrt() const;
00724 
00725 
00731 EMData * log() const;
00732 
00733 
00739 EMData * log10() const;
00740 
00741 
00746 EMData * real() const;
00747 
00748 
00754 EMData * imag() const;
00755 
00761 EMData * absi() const;
00762 
00763 
00768 EMData * amplitude() const;
00769 
00770 
00775 EMData * phase() const;
00776 
00777 
00783 EMData * real2complex(float img = 0.0f) const;
00784 
00785 #endif  //emdata__core_h__