Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

emdata_transform.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 "emfft.h"
00038 
00039 #include <cstring>
00040 #include <cstdio>
00041 
00042 #include  "gsl_sf_result.h"
00043 #include  "gsl_sf_bessel.h"
00044 #include <iostream>
00045 #include <algorithm>
00046 #include <vector>
00047 #include <utility>
00048 #include <cmath>
00049 #include "util.h"
00050 
00051 #ifdef EMAN2_USING_CUDA
00052 #include "cuda/cuda_processor.h"
00053 #endif
00054 
00055 using namespace EMAN;
00056 using namespace std;
00057 typedef vector< pair<float,int> > vp;
00058 
00059 #ifdef EMAN2_USING_CUDA
00060 
00061 #include "cuda/cuda_emfft.h"
00062 
00063 EMData *EMData::do_fft_cuda() const
00064 {
00065         ENTERFUNC;
00066 
00067         if ( is_complex() ) {
00068                 LOGERR("real image expected. Input image is complex image.");
00069                 throw ImageFormatException("real image expected. Input image is complex image.");
00070         }
00071 //      int nxreal = nx;
00072         int offset;
00073         int ndim = get_ndim();
00074         EMData* dat = new EMData();
00075 
00076         offset = 2 - nx%2;
00077         dat->set_size_cuda(nx+offset,ny, nz);
00078         float *d = dat->get_cuda_data();
00079         if ( ndim == 1 ) {
00080                 cuda_dd_fft_real_to_complex_nd(get_cuda_data(), d, nx, 1,1);
00081         } else if (ndim == 2) {
00082                 cuda_dd_fft_real_to_complex_nd(get_cuda_data(), d, ny, nx, 1);
00083         } else if (ndim == 3) {
00084                 cuda_dd_fft_real_to_complex_nd(get_cuda_data(), d, nz, ny, nx);
00085         } else throw ImageDimensionException("No cuda FFT support of images with dimensions exceeding 3");
00086 
00087         if (offset == 1) dat->set_fftodd(true);
00088         else             dat->set_fftodd(false);
00089 
00090         dat->set_fftpad(true);
00091         dat->set_complex(true);
00092         if(dat->get_ysize()==1 && dat->get_zsize()==1) dat->set_complex_x(true);
00093         dat->set_ri(true);
00094         dat->gpu_update();
00095 
00096         EXITFUNC;
00097         return dat;
00098 }
00099 
00100 EMData *EMData::do_ift_cuda(bool preserve_input) const
00101 {
00102         ENTERFUNC;
00103 
00104         if (!is_complex()) {
00105                 LOGERR("complex image expected. Input image is real image.");
00106                 throw ImageFormatException("complex image expected. Input image is real image.");
00107         }
00108 
00109         if (!is_ri()) {
00110                 throw ImageFormatException("complex ri expected. Got amplitude/phase.");
00111         }
00112 
00113         int offset = is_fftodd() ? 1 : 2;
00114         EMData* dat = new EMData();
00115         int ndim = get_ndim();
00116         dat->set_size_cuda(nx-offset, ny, nz);
00117         float *d = dat->get_cuda_data();
00118         float *this_d;
00119         EMData* tmp = 0;
00120         if (preserve_input){
00121                 tmp = new EMData(*this);
00122                 this_d = tmp->get_cuda_data();
00123         } else {
00124                 this_d = get_cuda_data();
00125         }
00126         if ( ndim == 1 ) {
00127                 cuda_dd_fft_complex_to_real_nd(this_d,d, nx-offset,1,1);
00128         } else if (ndim == 2) {
00129                 cuda_dd_fft_complex_to_real_nd(this_d,d, ny,nx-offset,1);
00130         } else if (ndim == 3) {
00131                 cuda_dd_fft_complex_to_real_nd(this_d,d, nz,ny,nx-offset);
00132         } else throw ImageDimensionException("No cuda FFT support of images with dimensions exceeding 3");
00133 
00134         if (tmp != 0) delete tmp;
00135 
00136         // SCALE the inverse FFT
00137         float scale = 1.0f/static_cast<float>((dat->get_size()));
00138         dat->mult(scale); // Use of GPU should be automatic
00139 
00140         dat->set_fftpad(false);
00141         dat->set_fftodd(false);
00142         dat->set_complex(false);
00143         if(dat->get_ysize()==1 && dat->get_zsize()==1)  dat->set_complex_x(false);
00144         dat->set_ri(false);
00145         dat->gpu_update();
00146 
00147         EXITFUNC;
00148         return dat;
00149 }
00150 
00151 #endif //EMAN2_USING_CUDA
00152 
00153 EMData *EMData::do_fft() const
00154 {
00155         ENTERFUNC;
00156 
00157 #ifdef EMAN2_USING_CUDA
00158         if (gpu_operation_preferred()) {
00159                 EXITFUNC;
00160                 return do_fft_cuda();
00161         }
00162 #endif
00163 
00164         if (is_complex() ) { // ming add 08/17/2010
00165 #ifdef NATIVE_FFT
00166                 LOGERR(" NATIVE_FFT not supported yet.");
00167                 throw ImageFormatException("real image expected. Input image is complex image.");
00168                 exit;
00169 #endif // NATIVE_FFT
00170 
00171                         EMData *temp_in=copy();
00172                         EMData *dat= copy_head();
00173                         int offset;
00174                         if(is_fftpadded()) {
00175                                 offset = is_fftodd() ? 1 : 2;
00176                         }
00177                         else offset=0;
00178                         //printf("offset=%d\n",offset);
00179                         EMfft::complex_to_complex_nd(temp_in->get_data(),dat->get_data(),nx-offset,ny,nz);
00180 
00181                         if(dat->get_ysize()==1 && dat->get_zsize()==1) dat->set_complex_x(true);
00182 
00183                         dat->update();
00184                         delete temp_in;
00185                         EXITFUNC;
00186                         return dat;
00187                 }
00188 
00189         else{
00190         int nxreal = nx;
00191         int offset = 2 - nx%2;
00192         int nx2 = nx + offset;
00193         EMData* dat = copy_head();
00194         dat->set_size(nx2, ny, nz);
00195         //dat->to_zero();  // do not need it, real_to_complex will do it right anyway
00196         if (offset == 1) dat->set_fftodd(true);
00197         else             dat->set_fftodd(false);
00198 
00199         float *d = dat->get_data();
00200         //std::cout<<" do_fft "<<rdata[5]<<"  "<<d[5]<<std::endl;
00201         EMfft::real_to_complex_nd(get_data(), d, nxreal, ny, nz);
00202 
00203         dat->update();
00204         dat->set_fftpad(true);
00205         dat->set_complex(true);
00206         if(dat->get_ysize()==1 && dat->get_zsize()==1) dat->set_complex_x(true);
00207         dat->set_ri(true);
00208 
00209         EXITFUNC;
00210         return dat;
00211         }
00212 }
00213 
00214 EMData *EMData::do_fft_inplace()
00215 {
00216         ENTERFUNC;
00217 
00218         if ( is_complex() ) {
00219                 LOGERR("real image expected. Input image is complex image.");
00220                 throw ImageFormatException("real image expected. Input image is complex image.");
00221         }
00222 
00223         size_t offset;
00224         int nxreal;
00225         get_data(); // Required call if GPU caching is being used. Otherwise harmless
00226         if (!is_fftpadded()) {
00227                 // need to extend the matrix along x
00228                 // meaning nx is the un-fftpadded size
00229                 nxreal = nx;
00230                 offset = 2 - nx%2;
00231                 if (1 == offset) set_fftodd(true);
00232                 else             set_fftodd(false);
00233                 int nxnew = nx + offset;
00234                 set_size(nxnew, ny, nz);
00235 
00236                 for (int iz = nz-1; iz >= 0; iz--) {
00237                         for (int iy = ny-1; iy >= 0; iy--) {
00238                                 for (int ix = nxreal-1; ix >= 0; ix--) {
00239                                         size_t oldxpos = ix + (iy + iz*ny)*nxreal;
00240                                         size_t newxpos = ix + (iy + iz*ny)*nxnew;
00241                                         (*this)(newxpos) = (*this)(oldxpos);
00242                                 }
00243                         }
00244                 }
00245                 set_fftpad(true);
00246         } else {
00247                 offset = is_fftodd() ? 1 : 2;
00248                 nxreal = nx - offset;
00249         }
00250         EMfft::real_to_complex_nd(rdata, rdata, nxreal, ny, nz);
00251 
00252         set_complex(true);
00253         if(ny==1 && nz==1)  set_complex_x(true);
00254         set_ri(true);
00255 
00256         update();
00257 
00258         EXITFUNC;
00259         return this;
00260 }
00261 
00262 EMData *EMData::do_ift()
00263 {
00264         ENTERFUNC;
00265 
00266 #ifdef EMAN2_USING_CUDA
00267         if (gpu_operation_preferred()) {
00268                 EXITFUNC;
00269                 return do_ift_cuda();
00270         }
00271 #endif
00272 
00273         if (!is_complex()) {
00274                 LOGERR("complex image expected. Input image is real image.");
00275                 throw ImageFormatException("complex image expected. Input image is real image.");
00276         }
00277 
00278         if (!is_ri()) {
00279                 LOGWARN("run IFT on AP data, only RI should be used. Converting.");
00280         }
00281 
00282         get_data(); // Required call if GPU caching is being used. Otherwise harmless
00283         EMData* dat = copy_head();
00284         dat->set_size(nx, ny, nz);
00285         ap2ri();
00286 
00287         float *d = dat->get_data();
00288         int ndim = get_ndim();
00289 
00290         /* Do inplace IFT on a image copy, because the complex to real transform of
00291          * nd will destroy its input array even for out-of-place transforms.
00292          */
00293         memcpy((char *) d, (char *) rdata, nx * ny * nz * sizeof(float));
00294 
00295         int offset = is_fftodd() ? 1 : 2;
00296         //cout << "Sending offset " << offset << " " << nx-offset << endl;
00297         if (ndim == 1) {
00298                 EMfft::complex_to_real_nd(d, d, nx - offset, ny, nz);
00299         } else {
00300                 EMfft::complex_to_real_nd(d, d, nx - offset, ny, nz);
00301 
00302 #ifndef CUDA_FFT
00303                 size_t row_size = (nx - offset) * sizeof(float);
00304                 for (int i = 1; i < ny * nz; i++) {
00305                         memmove((char *) &d[i * (nx - offset)], (char *) &d[i * nx], row_size);
00306                 }
00307 #endif
00308         }
00309 
00310         dat->set_size(nx - offset, ny, nz);     //remove the padding
00311 #if defined     FFTW2 || defined FFTW3  || defined CUDA_FFT //native fft and ACML already done normalization
00312         // SCALE the inverse FFT
00313         float scale = 1.0f / ((nx - offset) * ny * nz);
00314         dat->mult(scale);
00315 #endif  //FFTW2 || FFTW3
00316         dat->set_fftodd(false);
00317         dat->set_fftpad(false);
00318         dat->set_complex(false);
00319         if(dat->get_ysize()==1 && dat->get_zsize()==1)  dat->set_complex_x(false);
00320         dat->set_ri(false);
00321         dat->update();
00322 
00323 
00324         EXITFUNC;
00325         return dat;
00326 }
00327 
00328 /*
00329    FFT in place does not depad, return real x-extended image
00330    use
00331 */
00332 EMData *EMData::do_ift_inplace()
00333 {
00334         ENTERFUNC;
00335 
00336         if (!is_complex()) {
00337                 LOGERR("complex image expected. Input image is real image.");
00338                 throw ImageFormatException("complex image expected. Input image is real image.");
00339         }
00340 
00341         if (!is_ri()) {
00342                 LOGWARN("run IFT on AP data, only RI should be used. ");
00343         }
00344         ap2ri();
00345 
00346         int offset = is_fftodd() ? 1 : 2;
00347         float* data = get_data();
00348         EMfft::complex_to_real_nd(data, data, nx - offset, ny, nz);
00349 
00350 #if defined     FFTW2 || defined FFTW3 || defined CUDA_FFT      //native fft and ACML already done normalization
00351         // SCALE the inverse FFT
00352         int nxo = nx - offset;
00353         float scale = 1.0f / (nxo * ny * nz);
00354         mult(scale);
00355 #endif //FFTW2 || FFTW3
00356 
00357 #ifndef CUDA_FFT
00358         set_fftpad(true);
00359 #else
00360         set_size(nx - offset, ny, nz);
00361 #endif
00362         set_complex(false);
00363         if(ny==1 && nz==1) set_complex_x(false);
00364         set_ri(false);
00365         update();
00366 
00367 
00368         EXITFUNC;
00369         return this;
00370 }
00371 #undef rdata
00372 
00373 
00374 std::string EMData::render_ap24(int x0, int y0, int ixsize, int iysize,
00375                                                  int bpl, float scale, int mingray, int maxgray,
00376                                                  float render_min, float render_max,float gamma,int flags)
00377 {
00378         ENTERFUNC;
00379 
00380         int asrgb;
00381         int hist=(flags&2)/2;
00382         int invy=(flags&4)?1:0;
00383 
00384         if (!is_complex()) throw ImageDimensionException("complex only");
00385 
00386         if (get_ndim() != 2) {
00387                 throw ImageDimensionException("2D only");
00388         }
00389 
00390         if (is_complex()) ri2ap();
00391 
00392         if (render_max <= render_min) {
00393                 render_max = render_min + 0.01f;
00394         }
00395 
00396         if (gamma<=0) gamma=1.0;
00397 
00398         // Calculating a full floating point gamma for
00399         // each pixel in the image slows rendering unacceptably
00400         // however, applying a gamma-mapping to an 8 bit colorspace
00401         // has unaccepable accuracy. So, we oversample the 8 bit colorspace
00402         // as a 12 bit colorspace and apply the gamma mapping to that
00403         // This should produce good accuracy for gamma values
00404         // larger than 0.5 (and a high upper limit)
00405         static int smg0=0,smg1=0;       // while this destroys threadsafety in the rendering process
00406         static float sgam=0;            // it is necessary for speed when rendering large numbers of small images
00407         static unsigned char gammamap[4096];
00408         if (gamma!=1.0 && (smg0!=mingray || smg1!=maxgray || sgam!=gamma)) {
00409                 for (int i=0; i<4096; i++) {
00410                         if (mingray<maxgray) gammamap[i]=(unsigned char)(mingray+(maxgray-mingray+0.999)*pow(((float)i/4096.0f),gamma));
00411                         else gammamap[4095-i]=(unsigned char)(mingray+(maxgray-mingray+0.999)*pow(((float)i/4096.0f),gamma));
00412                 }
00413         }
00414         smg0=mingray;   // so we don't recompute the map unless something changes
00415         smg1=maxgray;
00416         sgam=gamma;
00417 
00418         if (flags&8) asrgb=4;
00419         else if (flags&1) asrgb=3;
00420         else throw ImageDimensionException("must set flag 1 or 8");
00421 
00422         std::string ret=std::string();
00423 //      ret.resize(iysize*bpl);
00424         ret.assign(iysize*bpl+hist*1024,char(mingray));
00425         unsigned char *data=(unsigned char *)ret.data();
00426         unsigned int *histd=(unsigned int *)(data+iysize*bpl);
00427         if (hist) {
00428                 for (int i=0; i<256; i++) histd[i]=0;
00429         }
00430 
00431         float rm = render_min;
00432         float inv_scale = 1.0f / scale;
00433         int ysize = iysize;
00434         int xsize = ixsize;
00435 
00436         int ymin = 0;
00437         if (iysize * inv_scale > ny) {
00438                 ymin = (int) (iysize - ny / inv_scale);
00439         }
00440 
00441         float gs = (maxgray - mingray) / (render_max - render_min);
00442         float gs2 = 4095.999f / (render_max - render_min);
00443 //      float gs2 = 1.0 / (render_max - render_min);
00444         if (render_max < render_min) {
00445                 gs = 0;
00446                 rm = FLT_MAX;
00447         }
00448 
00449         int dsx = -1;
00450         int dsy = 0;
00451         int remx = 0;
00452         int remy = 0;
00453         const int scale_n = 100000;
00454 
00455         int addi = 0;
00456         int addr = 0;
00457         if (inv_scale == floor(inv_scale)) {
00458                 dsx = (int) inv_scale;
00459                 dsy = (int) (inv_scale * nx);
00460         }
00461         else {
00462                 addi = (int) floor(inv_scale);
00463                 addr = (int) (scale_n * (inv_scale - floor(inv_scale)));
00464         }
00465 
00466         int xmin = 0;
00467         if (x0 < 0) {
00468                 xmin = (int) (-x0 / inv_scale);
00469                 xsize -= (int) floor(x0 / inv_scale);
00470                 x0 = 0;
00471         }
00472 
00473         if ((xsize - xmin) * inv_scale > (nx - x0)) {
00474                 xsize = (int) ((nx - x0) / inv_scale + xmin);
00475         }
00476         int ymax = ysize - 1;
00477         if (y0 < 0) {
00478                 ymax = (int) (ysize + y0 / inv_scale - 1);
00479                 ymin += (int) floor(y0 / inv_scale);
00480                 y0 = 0;
00481         }
00482 
00483         if (xmin < 0) xmin = 0;
00484         if (ymin < 0) ymin = 0;
00485         if (xsize > ixsize) xsize = ixsize;
00486         if (ymax > iysize) ymax = iysize;
00487 
00488         int lmax = nx * ny - 1;
00489 
00490         int mid=nx*ny/2;
00491         float* image_data = get_data();
00492         if (dsx != -1) {
00493                 int l = y0 * nx;
00494                 for (int j = ymax; j >= ymin; j--) {
00495                         int ll = x0;
00496                         for (int i = xmin; i < xsize; i++) {
00497                                 if (l + ll > lmax || ll >= nx - 2) break;
00498 
00499                                 int k = 0;
00500                                 unsigned char p;
00501                                 int ph;
00502                                 if (ll >= nx / 2) {
00503                                         if (l >= (ny - inv_scale) * nx) k = 2 * (ll - nx / 2) + 2;
00504                                         else k = 2 * (ll - nx / 2) + l + 2 + nx;
00505                                         ph = (int)(image_data[k+1]*768/(2.0*M_PI))+384; // complex phase as integer 0-767
00506                                 }
00507                                 else {
00508                                         k = nx * ny - (l + 2 * ll) - 2;
00509                                         ph = (int)(-image_data[k+1]*768/(2.0*M_PI))+384;        // complex phase as integer 0-767
00510                                 }
00511                                 if (k>=mid) k-=mid;             // These 2 lines handle the Fourier origin being in the corner, not the middle
00512                                 else k+=mid;
00513                                 float t = image_data[k];
00514                                 if (t <= rm)  p = mingray;
00515                                 else if (t >= render_max) p = maxgray;
00516                                 else if (gamma!=1.0) {
00517                                         k=(int)(gs2 * (t-render_min));          // map float value to 0-4096 range
00518                                         p = gammamap[k];                                        // apply gamma using precomputed gamma map
00519                                 }
00520                                 else {
00521                                         p = (unsigned char) (gs * (t - render_min));
00522                                         p += mingray;
00523                                 }
00524                                 if (ph<256) {
00525                                         data[i * asrgb + j * bpl] = p*(255-ph)/256;
00526                                         data[i * asrgb + j * bpl+1] = p*ph/256;
00527                                         data[i * asrgb + j * bpl+2] = 0;
00528                                 }
00529                                 else if (ph<512) {
00530                                         data[i * asrgb + j * bpl+1] = p*(511-ph)/256;
00531                                         data[i * asrgb + j * bpl+2] = p*(ph-256)/256;
00532                                         data[i * asrgb + j * bpl] = 0;
00533                                 }
00534                                 else {
00535                                         data[i * asrgb + j * bpl+2] = p*(767-ph)/256;
00536                                         data[i * asrgb + j * bpl] = p*(ph-512)/256;
00537                                         data[i * asrgb + j * bpl+1] = 0;
00538                                 }
00539                                 if (hist) histd[p]++;
00540                                 ll += dsx;
00541                         }
00542                         l += dsy;
00543                 }
00544         }
00545         else {
00546                 remy = 10;
00547                 int l = y0 * nx;
00548                 for (int j = ymax; j >= ymin; j--) {
00549                         int br = l;
00550                         remx = 10;
00551                         int ll = x0;
00552                         for (int i = xmin; i < xsize - 1; i++) {
00553                                 if (l + ll > lmax || ll >= nx - 2) {
00554                                         break;
00555                                 }
00556                                 int k = 0;
00557                                 unsigned char p;
00558                                 int ph;
00559                                 if (ll >= nx / 2) {
00560                                         if (l >= (ny * nx - nx)) k = 2 * (ll - nx / 2) + 2;
00561                                         else k = 2 * (ll - nx / 2) + l + 2 + nx;
00562                                         ph = (int)(image_data[k+1]*768/(2.0*M_PI))+384; // complex phase as integer 0-767
00563                                 }
00564                                 else {
00565                                         k = nx * ny - (l + 2 * ll) - 2;
00566                                         ph = (int)(-image_data[k+1]*768/(2.0*M_PI))+384;        // complex phase as integer 0-767
00567                                 }
00568                                 if (k>=mid) k-=mid;             // These 2 lines handle the Fourier origin being in the corner, not the middle
00569                                 else k+=mid;
00570 
00571                                 float t = image_data[k];
00572                                 if (t <= rm)
00573                                         p = mingray;
00574                                 else if (t >= render_max) {
00575                                         p = maxgray;
00576                                 }
00577                                 else if (gamma!=1.0) {
00578                                         k=(int)(gs2 * (t-render_min));          // map float value to 0-4096 range
00579                                         p = gammamap[k];                                        // apply gamma using precomputed gamma map
00580                                 }
00581                                 else {
00582                                         p = (unsigned char) (gs * (t - render_min));
00583                                         p += mingray;
00584                                 }
00585                                 if (ph<256) {
00586                                         data[i * asrgb + j * bpl] = p*(255-ph)/256;
00587                                         data[i * asrgb + j * bpl+1] = p*ph/256;
00588                                         data[i * asrgb + j * bpl+2] = 0;
00589                                 }
00590                                 else if (ph<512) {
00591                                         data[i * asrgb + j * bpl+1] = p*(511-ph)/256;
00592                                         data[i * asrgb + j * bpl+2] = p*(ph-256)/256;
00593                                         data[i * asrgb + j * bpl] = 0;
00594                                 }
00595                                 else {
00596                                         data[i * asrgb + j * bpl+2] = p*(767-ph)/256;
00597                                         data[i * asrgb + j * bpl] = p*(ph-512)/256;
00598                                         data[i * asrgb + j * bpl+1] = 0;
00599                                 }
00600                                 if (hist) histd[p]++;
00601                                 ll += addi;
00602                                 remx += addr;
00603                                 if (remx > scale_n) {
00604                                         remx -= scale_n;
00605                                         ll++;
00606                                 }
00607                         }
00608                         l = br + addi * nx;
00609                         remy += addr;
00610                         if (remy > scale_n) {
00611                                 remy -= scale_n;
00612                                 l += nx;
00613                         }
00614                 }
00615         }
00616 
00617         // this replicates r -> g,b
00618         if (asrgb==4) {
00619                 for (int j=ymin*bpl; j<=ymax*bpl; j+=bpl) {
00620                         for (int i=xmin; i<xsize*4; i+=4) {
00621                                 data[i+j+3]=255;
00622                         }
00623                 }
00624         }
00625 
00626         EXITFUNC;
00627 
00628         // ok, ok, not the most efficient place to do this, but it works
00629         if (invy) {
00630                 int x,y;
00631                 char swp;
00632                 for (y=0; y<iysize/2; y++) {
00633                         for (x=0; x<ixsize; x++) {
00634                                 swp=ret[y*bpl+x];
00635                                 ret[y*bpl+x]=ret[(iysize-y-1)*bpl+x];
00636                                 ret[(iysize-y-1)*bpl+x]=swp;
00637                         }
00638                 }
00639         }
00640 
00641     //  return PyString_FromStringAndSize((const char*) data,iysize*bpl);
00642         return ret;
00643 }
00644 
00645 
00646 void EMData::render_amp24( int x0, int y0, int ixsize, int iysize,
00647                                                   int bpl, float scale, int mingray, int maxgray,
00648                                                   float render_min, float render_max, void *ref,
00649                                                   void cmap(void *, int coord, unsigned char *tri))
00650 {
00651         ENTERFUNC;
00652 
00653         if (get_ndim() != 2) {
00654                 throw ImageDimensionException("2D only");
00655         }
00656 
00657         if (is_complex()) {
00658                 ri2ap();
00659         }
00660 
00661         if (render_max <= render_min) {
00662                 render_max = render_min + 0.01f;
00663         }
00664 
00665         std::string ret=std::string();
00666         ret.resize(iysize*bpl);
00667         unsigned char *data=(unsigned char *)ret.data();
00668 
00669         float rm = render_min;
00670         float inv_scale = 1.0f / scale;
00671         int ysize = iysize;
00672         int xsize = ixsize;
00673         const int scale_n = 100000;
00674 
00675         int ymin = 0;
00676         if ( iysize * inv_scale > ny) {
00677                 ymin = (int) (iysize - ny / inv_scale);
00678         }
00679         float gs = (maxgray - mingray) / (render_max - render_min);
00680         if (render_max < render_min) {
00681                 gs = 0;
00682                 rm = FLT_MAX;
00683         }
00684         int dsx = -1;
00685         int dsy = 0;
00686         if (inv_scale == floor(inv_scale)) {
00687                 dsx = (int) inv_scale;
00688                 dsy = (int) (inv_scale * nx);
00689         }
00690         int addi = 0;
00691         int addr = 0;
00692 
00693         if (dsx == -1) {
00694                 addi = (int) floor(inv_scale);
00695                 addr = (int) (scale_n * (inv_scale - floor(inv_scale)));
00696         }
00697 
00698         int remx = 0;
00699         int remy = 0;
00700         int xmin = 0;
00701         if (x0 < 0) {
00702                 xmin = (int) (-x0 / inv_scale);
00703                 xsize -= (int) floor(x0 / inv_scale);
00704                 x0 = 0;
00705         }
00706 
00707         if ((xsize - xmin) * inv_scale > (nx - x0)) {
00708                 xsize = (int) ((nx - x0) / inv_scale + xmin);
00709         }
00710         int ymax = ysize - 1;
00711         if (y0 < 0) {
00712                 ymax = (int) (ysize + y0 / inv_scale - 1);
00713                 ymin += (int) floor(y0 / inv_scale);
00714                 y0 = 0;
00715         }
00716 
00717 
00718         if (xmin < 0) {
00719                 xmin = 0;
00720         }
00721 
00722         if (ymin < 0) {
00723                 ymin = 0;
00724         }
00725         if (xsize > ixsize) {
00726                 xsize = ixsize;
00727         }
00728         if (ymax > iysize) {
00729                 ymax = iysize;
00730         }
00731 
00732         int lmax = nx * ny - 1;
00733         unsigned char tri[3];
00734         float* image_data = get_data();
00735         if (is_complex()) {
00736                 if (dsx != -1) {
00737                         int l = y0 * nx;
00738                         for (int j = ymax; j >= ymin; j--) {
00739                                 int ll = x0;
00740                                 for (int i = xmin; i < xsize; i++, ll += dsx) {
00741                                         if (l + ll > lmax || ll >= nx - 2) {
00742                                                 break;
00743                                         }
00744                                         int kk = 0;
00745                                         if (ll >= nx / 2) {
00746                                                 if (l >= (ny - inv_scale) * nx) {
00747                                                         kk = 2 * (ll - nx / 2) + 2;
00748                                                 }
00749                                                 else {
00750                                                         kk = 2 * (ll - nx / 2) + l + 2 + nx;
00751                                                 }
00752                                         }
00753                                         else {
00754                                                 kk = nx * ny - (l + 2 * ll) - 2;
00755                                         }
00756                                         int k = 0;
00757                                         float t = image_data[kk];
00758                                         if (t <= rm) {
00759                                                 k = mingray;
00760                                         }
00761                                         else if (t >= render_max) {
00762                                                 k = maxgray;
00763                                         }
00764                                         else {
00765                                                 k = (int) (gs * (t - render_min));
00766                                                 k += mingray;
00767                                         }
00768                                         tri[0] = static_cast < unsigned char >(k);
00769                                         cmap(ref, kk, tri);
00770                                         data[i * 3 + j * bpl] = tri[0];
00771                                         data[i * 3 + 1 + j * bpl] = tri[1];
00772                                         data[i * 3 + 2 + j * bpl] = tri[2];
00773                                 }
00774                                 l += dsy;
00775                         }
00776                 }
00777                 else {
00778                         remy = 10;
00779                         for (int j = ymax, l = y0 * nx; j >= ymin; j--) {
00780                                 int br = l;
00781                                 remx = 10;
00782                                 for (int i = xmin, ll = x0; i < xsize - 1; i++) {
00783                                         if (l + ll > lmax || ll >= nx - 2) {
00784                                                 break;
00785                                         }
00786                                         int kk = 0;
00787                                         if (ll >= nx / 2) {
00788                                                 if (l >= (ny * nx - nx)) {
00789                                                         kk = 2 * (ll - nx / 2) + 2;
00790                                                 }
00791                                                 else {
00792                                                         kk = 2 * (ll - nx / 2) + l + 2 + nx;
00793                                                 }
00794                                         }
00795                                         else {
00796                                                 kk = nx * ny - (l + 2 * ll) - 2;
00797                                         }
00798                                         int k = 0;
00799                                         float t = image_data[kk];
00800                                         if (t <= rm) {
00801                                                 k = mingray;
00802                                         }
00803                                         else if (t >= render_max) {
00804                                                 k = maxgray;
00805                                         }
00806                                         else {
00807                                                 k = (int) (gs * (t - render_min));
00808                                                 k += mingray;
00809                                         }
00810                                         tri[0] = static_cast < unsigned char >(k);
00811                                         cmap(ref, kk, tri);
00812                                         data[i * 3 + j * bpl] = tri[0];
00813                                         data[i * 3 + 1 + j * bpl] = tri[1];
00814                                         data[i * 3 + 2 + j * bpl] = tri[2];
00815                                         ll += addi;
00816                                         remx += addr;
00817                                         if (remx > scale_n) {
00818                                                 remx -= scale_n;
00819                                                 ll++;
00820                                         }
00821                                 }
00822                                 l = br + addi * nx;
00823                                 remy += addr;
00824                                 if (remy > scale_n) {
00825                                         remy -= scale_n;
00826                                         l += nx;
00827                                 }
00828                         }
00829                 }
00830         }
00831         else {
00832                 if (dsx != -1) {
00833                         for (int j = ymax, l = x0 + y0 * nx; j >= ymin; j--) {
00834                                 int br = l;
00835                                 for (int i = xmin; i < xsize; i++, l += dsx) {
00836                                         if (l > lmax) {
00837                                                 break;
00838                                         }
00839                                         float t = image_data[l];
00840                                         int k = 0;
00841                                         if (t <= rm) {
00842                                                 k = mingray;
00843                                         }
00844                                         else if (t >= render_max) {
00845                                                 k = maxgray;
00846                                         }
00847                                         else {
00848                                                 k = (int) (gs * (t - render_min));
00849                                                 k += mingray;
00850                                         }
00851                                         tri[0] = static_cast < unsigned char >(k);
00852                                         cmap(ref, l, tri);
00853                                         data[i * 3 + j * bpl] = tri[0];
00854                                         data[i * 3 + 1 + j * bpl] = tri[1];
00855                                         data[i * 3 + 2 + j * bpl] = tri[2];
00856                                 }
00857                                 l = br + dsy;
00858                         }
00859                 }
00860                 else {
00861                         remy = 10;
00862                         for (int j = ymax, l = x0 + y0 * nx; j >= ymin; j--) {
00863                                 int br = l;
00864                                 remx = 10;
00865                                 for (int i = xmin; i < xsize; i++) {
00866                                         if (l > lmax) {
00867                                                 break;
00868                                         }
00869                                         float t = image_data[l];
00870                                         int k = 0;
00871                                         if (t <= rm) {
00872                                                 k = mingray;
00873                                         }
00874                                         else if (t >= render_max) {
00875                                                 k = maxgray;
00876                                         }
00877                                         else {
00878                                                 k = (int) (gs * (t - render_min));
00879                                                 k += mingray;
00880                                         }
00881                                         tri[0] = static_cast < unsigned char >(k);
00882                                         cmap(ref, l, tri);
00883                                         data[i * 3 + j * bpl] = tri[0];
00884                                         data[i * 3 + 1 + j * bpl] = tri[1];
00885                                         data[i * 3 + 2 + j * bpl] = tri[2];
00886                                         l += addi;
00887                                         remx += addr;
00888                                         if (remx > scale_n) {
00889                                                 remx -= scale_n;
00890                                                 l++;
00891                                         }
00892                                 }
00893                                 l = br + addi * nx;
00894                                 remy += addr;
00895                                 if (remy > scale_n) {
00896                                         remy -= scale_n;
00897                                         l += nx;
00898                                 }
00899                         }
00900                 }
00901         }
00902 
00903         EXITFUNC;
00904 }
00905 
00906 void EMData::ap2ri()
00907 {
00908         ENTERFUNC;
00909 
00910         if (!is_complex() || is_ri()) {
00911                 return;
00912         }
00913 
00914 #ifdef EMAN2_USING_CUDA
00915         if (gpu_operation_preferred()) {
00916                 EMDataForCuda tmp = get_data_struct_for_cuda();
00917                 emdata_ap2ri(&tmp);
00918                 set_ri(true);
00919                 gpu_update();
00920                 EXITFUNC;
00921                 return;
00922         }
00923 #endif
00924 
00925         Util::ap2ri(get_data(), nx * ny * nz);
00926         set_ri(true);
00927         update();
00928         EXITFUNC;
00929 }
00930 
00931 void EMData::ri2inten()
00932 {
00933         ENTERFUNC;
00934 
00935         if (!is_complex()) return;
00936         if (!is_ri()) ap2ri();
00937 
00938 #ifdef EMAN2_USING_CUDA
00939         if (gpu_operation_preferred()) {
00940                 EMDataForCuda tmp = get_data_struct_for_cuda();
00941                 emdata_ri2inten(&tmp);
00942                 set_attr("is_intensity", int(1));
00943                 gpu_update();
00944                 EXITFUNC;
00945                 return;
00946         }
00947 #endif
00948 
00949         float * data = get_data();
00950         size_t size = nx * ny * nz;
00951         for (size_t i = 0; i < size; i += 2) {
00952                 data[i]=data[i]*data[i]+data[i+1]*data[i+1];
00953                 data[i+1]=0;
00954         }
00955 
00956         set_attr("is_intensity", int(1));
00957         update();
00958         EXITFUNC;
00959 }
00960 
00961 
00962 void EMData::ri2ap()
00963 {
00964         ENTERFUNC;
00965 
00966         if (!is_complex() || !is_ri()) {
00967                 return;
00968         }
00969 #ifdef EMAN2_USING_CUDA
00970         if (gpu_operation_preferred()) {
00971                 EMDataForCuda tmp = get_data_struct_for_cuda();
00972                 emdata_ri2ap(&tmp);
00973                 set_ri(false);
00974                 gpu_update();
00975                 EXITFUNC;
00976                 return;
00977         }
00978 #endif
00979 
00980         float * data = get_data();
00981 
00982         size_t size = nx * ny * nz;
00983         for (size_t i = 0; i < size; i += 2) {
00984 #ifdef  _WIN32
00985                 float f = (float)_hypot(data[i], data[i + 1]);
00986 #else
00987                 float f = (float)hypot(data[i], data[i + 1]);
00988 #endif
00989                 if (data[i] == 0 && data[i + 1] == 0) {
00990                         data[i + 1] = 0;
00991                 }
00992                 else {
00993                         data[i + 1] = atan2(data[i + 1], data[i]);
00994                 }
00995                 data[i] = f;
00996         }
00997 
00998         set_ri(false);
00999         update();
01000         EXITFUNC;
01001 }
01002 
01003 
01004 float calc_bessel(const int n, const float& x) {
01005         gsl_sf_result result;
01006 //      int success =
01007         gsl_sf_bessel_Jn_e(n,(double)x, &result);
01008         return (float)result.val;
01009 }
01010 
01011 EMData*   EMData::bispecRotTransInvN(int N, int NK)
01012 {
01013 
01014         int EndP = this -> get_xsize(); // length(fTrueVec);
01015         int Mid  = (int) ((1+EndP)/2);
01016         int End = 2*Mid-1;
01017 
01018         int CountxyMax = End*End;
01019 
01020         int   *SortfkInds       = new    int[CountxyMax];
01021         int   *kVecX            = new    int[CountxyMax];
01022         int   *kVecY            = new    int[CountxyMax];
01023         float *fkVecR           = new  float[CountxyMax];
01024         float *fkVecI           = new  float[CountxyMax];
01025         float *absD1fkVec       = new  float[CountxyMax];
01026         float *absD1fkVecSorted = new  float[CountxyMax];
01027 
01028         float *jxjyatan2         = new  float[End*End]; //  jxjyatan2[jy*End + jx]  = atan2(jy+1-Mid , jx +1 -Mid);
01029 
01030         EMData * ThisCopy = new EMData(End,End);
01031 
01032         for (int jx=0; jx <End ; jx++) {
01033                 for (int jy=0; jy <End ; jy++) {
01034                         float ValNow = this -> get_value_at(jx,jy);
01035                         ThisCopy -> set_value_at(jx,jy,ValNow);
01036 //              cout<< " jxM= " << jx+1<<" jyM= " << jy+1<< "ValNow" << ValNow << endl; //    Works
01037         }}
01038 
01039 
01040         EMData* fk = ThisCopy -> do_fft();
01041         fk          ->process_inplace("xform.fourierorigin.tocenter");
01042 
01043 //      EMData* fk
01044         EMData* fkRCopy = new EMData(End,End);
01045         EMData* fkICopy = new EMData(End,End);
01046         EMData* fkCopy  = new EMData(End,End);
01047 
01048 
01049         for  (int jCount= 0; jCount<End*End; jCount++) {
01050 //              jCount = jy*End + jx;
01051                 int jx             = jCount%End ;
01052                 int jy             = (jCount-jx)/End ;
01053                 jxjyatan2[jCount]  = atan2((float)(jy+1-Mid) , (float)(jx +1-Mid));
01054         }
01055 
01056 
01057         for (int kEx= 0; kEx<2*Mid; kEx=kEx+2) { // kEx twice the value of the Fourier
01058                                                 // x variable: EMAN index for real, imag
01059                 int kx    = kEx/2;              // kx  is  the value of the Fourier variable
01060                 int kIx   = kx+Mid-1; // This is the value of the index for a matlab image (-1)
01061                 int kCx   =  -kx ;
01062                 int kCIx  = kCx+ Mid-1 ;
01063                 for (int kEy= 0 ; kEy<End; kEy++) { // This is the value of the EMAN index
01064                         int kIy              =  kEy       ; //  This is the value of the index for a matlab image (-1)
01065                         int ky               =  kEy+1-Mid; // (kEy+ Mid-1)%End - Mid+1 ;  // This is the actual value of the Fourier variable
01066                         float realVal        =  fk -> get_value_at(kEx  ,kEy) ;
01067                         float imagVal        =  fk -> get_value_at(kEx+1,kEy) ;
01068                         float absVal         =  ::sqrt(realVal*realVal+imagVal*imagVal);
01069                         float fkAng          =  atan2(imagVal,realVal);
01070 
01071                         float NewRealVal   ;
01072                         float NewImagVal   ;
01073                         float AngMatlab    ;
01074 
01075                         if (kIx==Mid-1) {
01076 //                              AngMatlab = -fkAng - 2.*M_PI*(kIy+ 1-Mid)*(Mid)/End;
01077 //                      cout<< "i= " << i << " kIx= " << kIx << " kIy=" << kIy << " fkVecR[i] =" << fkVecR[i]<< " fkVecI[i]="  << fkVecI[i] <<"  angle[i]= "  << AngMatlab << endl;
01078                         }
01079 
01080                         if (kIx>Mid-1){
01081 //                      cout<< "i= " << i << " kIx= " << kIx << " kIy=" << kIy << " fkVecR[i] =" << fkVecR[i]<< " fkVecI[i]="  << fkVecI[i] <<"  angle[i]= "  << AngMatlab << endl;
01082                         }
01083 
01084                         AngMatlab = fkAng - 2.0f*M_PI*(kx +ky)*(Mid)/End;
01085                         NewRealVal  =   absVal*cos(AngMatlab);
01086                         NewImagVal  =   absVal*sin(AngMatlab);
01087 
01088 
01089                         fkVecR[kIy+kIx *End] =  NewRealVal ;
01090                         fkVecR[kIy+kCIx*End] =  NewRealVal ;
01091                         fkVecI[kIy+kIx *End] =  NewImagVal ;
01092                         fkVecI[kIy+kCIx*End] = -NewImagVal ;
01093                         absD1fkVec[kIy + kIx  *End] = absVal;
01094                         absD1fkVec[kIy + kCIx *End] = absVal;
01095                         kVecX[kIy+kIx  *End] =  kx      ;
01096                         kVecX[kIy+kCIx *End] =  kCx    ;
01097                         kVecY[kIy+kIx  *End] =  ky     ;
01098                         kVecY[kIy+kCIx *End] =  ky     ;
01099 //                      printf("kx=%d,ky=%d,tempVal =%f+ i %4.2f \n",kx,ky,realVal,imagVal );
01100 //                      cout << "kx = " << kx << "; ky = "<< ky << "; val is" << realVal<<"+ i "<<imagVal<< endl;
01101 
01102 //                      cout << "kIMx = "<< kIx+1 << "; kIMy = "<< kIy+1 <<"; fkAng*9/ 2pi is " << fkAng*9/2/M_PI<<  endl;
01103 //                      cout << "kIMx = "<< kIx+1 << "; kIMy = "<< kIy+1 <<"; absval is " << absVal<<  "; realval is " << NewRealVal<< "; imagval is " << NewImagVal<< endl;
01104                         fkCopy  -> set_value_at(kIx ,kIy, absVal);
01105                         fkCopy  -> set_value_at(kCIx,kIy, absVal);
01106                         fkRCopy -> set_value_at(kIx, kIy, NewRealVal);
01107                         fkRCopy -> set_value_at(kCIx,kIy, NewRealVal);
01108                         fkICopy -> set_value_at(kIx, kIy, NewImagVal);
01109                         fkICopy -> set_value_at(kCIx,kIy,-NewImagVal);
01110 
01111                 }
01112         }
01113         system("rm -f fkCopy.???");
01114         system("rm -f fk?Copy.???");
01115         fkCopy  -> write_image("fkCopy.img");
01116         fkRCopy -> write_image("fkRCopy.img");
01117         fkICopy -> write_image("fkICopy.img");
01118 
01119         cout << "Starting the sort "<< endl;
01120 
01121         vector< pair<float, int> > absInds;
01122         for(int i  = 0; i < CountxyMax; ++i ) {
01123                 pair<float,int> p;
01124                 p = make_pair(absD1fkVec[i],i); // p = make_pair(rand(),i);
01125                 absInds.push_back( p);
01126         }
01127 
01128         std::sort(absInds.begin(),absInds.end());
01129 
01130         for(int i  = 0; i < CountxyMax; ++i ) {
01131                 pair<float,int> p   ;
01132                 p = absInds[i]         ;
01133                 absD1fkVecSorted[CountxyMax-1-i] =  p.first ;
01134                 SortfkInds[CountxyMax-1-i]       =  p.second ;
01135         }
01136 
01137         cout << "Ending the sort "<< endl;
01138 
01139 // float AngsMat[] ={2.8448, -0.3677,-0.2801,-1.0494,-1.7836,-2.5179, 2.9959, 3.0835,-0.1290,-0.8876,2.1829, 2.2705,1.5011,0.7669,0.0327,-0.7366,-0.6489,2.4215,-1.6029,1.4676,1.5552,0.7859,0.0517,-0.6825,-1.4518,-1.3642,1.7063,-1.7845,1.2859,1.3736,0.6043,-0.1299,-0.8642,-1.6335,-1.5459,1.5247,-1.6546,1.4159,1.5036,0.7342,0,-0.7342,-1.5036,-1.4159,1.6546,-1.5247,1.5459,1.6335,0.8642,0.1299,-0.6043,-1.3736,-1.286,1.7846,-1.7063,1.3642,1.4519,0.6825,-0.0517,-0.7859,-1.5553,-1.4676,1.6029,-2.4216,0.649,0.7366,-0.0327,-0.767,-1.5012,-2.2705,-2.1829,0.8877,0.1291,-3.0836,-2.9959,2.5179,1.7837,1.0495,0.2801,0.3677,-2.8449};
01140 
01141 
01142         for(int i  = 0; i < CountxyMax; ++i ) {  // creates a new fkVec
01143                 int Si  = SortfkInds[i];
01144                 int kIx = (int)  Si/End;  kIx = (int)  i/End; // i = kIx*End+kIy
01145 //              int kIy = Si  - kIx*End;  kIy = i  - kIx*End;
01146 //              int iC = (End-1-kIx)*End + (End-1-kIy);
01147 //              if (i<30) { cout<< "i= " << i << " kIx= " << kIx << " kIy=" << kIy << " valAft=" << absD1fkVecSorted[i]<< " valBef="  <<     absD1fkVec[Si] << "  SortfkInds = " << Si <<endl; }// This worked
01148 //              cout<< "i= " << i << " kIx= " << kIx << " kIy=" << kIy << " fkVecR[i] =" << fkVecR[i]<< " fkVecI[i]="  << fkVecI[i] <<"  angle[i]= "  << fkAng << endl;
01149         }
01150         cout<< "Ratio of Last Amplitude to First Amplitude= " << absD1fkVecSorted[NK] /absD1fkVecSorted[0]  << endl;
01151 
01152 //      pause;
01153 
01154 //      for(int i  = 0; i < NK; ++i ) { // Prints out the new fkVec ,  CountxyMax
01155 //              int Si= SortfkInds[i];
01156 //              int kIx = (int)  Si/End; // i = kIx*End+kIy
01157 //              int kIy = Si  - kIx*End;
01158 //              cout << " kIxM= " << kIx+1 << " kIyM=" << kIy+1 << " fkVecAbs=" << ::sqrt(fkVecR[Si]*fkVecR[Si] +  fkVecI[Si]* fkVecI[Si]) << " fkVecAbs=" << absD1fkVecSorted[i] << " kx= " << kVecX[Si] <<  " ky=" << kVecY[Si] <<  endl;
01159 //      }
01160 
01161 //       angEMAN+angMat+angDiff    =0  mod 2 pi
01162 
01163 //      angDiff=  2*pi*((-4):4)*(Mid)/End; angEMAN+angMat+angDiff= integer*2 *pi
01164 //              [  absD1fkVecSorted, SortfkInds] =sort( absD1fkVec,'descend') ;
01165 //      Util::sort_mat(&absD1fkVec[0],&absD1fkVec[Countxy],&SortfkInds[0],&SortfkInds[Countxy]);
01166 
01167 
01168 //      Let radial sampling be 0:0.5:(Mid-1)
01169 
01170  //     int NK=  min(12,CountxyMax) ;
01171 
01172 
01173 
01174         cout << "NK = " << NK << endl;
01175         float frR= 3.0/4.0;
01176         int LradRange= (int) (floor(Mid/frR)) ;
01177 
01178         float *radRange = new float[LradRange]; //= 0:.75:(Mid-1);
01179         radRange[0]=0;
01180         for (int irad=1; irad < LradRange; irad++){
01181                         radRange[irad] = radRange[irad-1] + frR; }
01182 
01183 
01184 
01185          // should equal to (2*Mid-1)
01186         cout << "Starting the calculation of invariants for N= " << N << endl;
01187 
01188 /*      int NMax=5;            */
01189 
01190         EMData* RotTransInv = new EMData();
01191         RotTransInv -> set_size(LradRange,LradRange);
01192 
01193 
01194 //      float  *RotTransInv       = new float[LradRange*LradRange ] ;
01195 //      float  *RotTransInvN      = new float[LradRange*LradRange*(NMax+1) ] ;
01196 
01197 //      for (int N=0 ; N<NMax; N++) {
01198 
01199         for (int jr1=0; jr1 < LradRange ; jr1++ ) { // LradRange
01200                 float r1= radRange[jr1];
01201 //              cout << "Pre jr2 "<< endl;
01202                 for (int jr2=0;  jr2<LradRange;  jr2++ ) { //LradRange
01203                         float r2= radRange[jr2];
01204                         float RotTransInvTemp=0;
01205                         for (int jCountkxy =0; jCountkxy<NK; jCountkxy++){
01206                                 int Countkxy =SortfkInds[jCountkxy] ;   // 1: CountxyMax
01207                                 int kx = kVecX[Countkxy] ;
01208                                 int ky = kVecY[Countkxy] ;
01209                                 float k2 = (float)(kx*kx+ky*ky);
01210                                 if (k2==0) { continue;}
01211                                 float phiK =0;
01212                                 if (k2>0) phiK= jxjyatan2[ (ky+Mid-1)*End + kx+Mid-1];  phiK= atan2((float)ky,(float)kx);
01213 
01214                                 float fkR     = fkVecR[Countkxy] ;
01215                                 float fkI     = fkVecI[Countkxy]  ;
01216 /*                              printf("jCountkxy=%d, Countkxy=%d,absD1fkVec(Countkxy)=%f,\t\t kx=%d, ky=%d \n", jCountkxy, Countkxy, absD1fkVec[Countkxy], kx, ky);*/
01217 
01218                                 for (int jCountqxy =0; jCountqxy<NK; jCountqxy++){
01219                                         int Countqxy =SortfkInds[jCountqxy] ;   // Countqxy is the index for absD1fkVec
01220                                         int qx   = kVecX[Countqxy] ;
01221                                         int qy   = kVecY[Countqxy] ;
01222                                         int q2   = qx*qx+qy*qy;
01223                                         if (q2==0) {continue;}
01224                                         float phiQ =0;
01225                                         if (q2>0) phiQ = jxjyatan2[ (qy+Mid-1)*End + qx+Mid-1];   phiQ=atan2((float)qy,(float)qx);
01226                                         float fqR     = fkVecR[Countqxy]  ;
01227                                         float fqI     = fkVecI[Countqxy]  ;
01228                                         int kCx  = (-kx-qx);
01229                                         int kCy  = (-ky-qy);
01230                                         int kCIx = ((kCx+Mid+2*End)%End);// labels of the image in C
01231                                         int kCIy = ((kCy+Mid+2*End)%End);
01232                                         kCx  = kCIx-Mid; // correct
01233                                         kCy  = kCIy-Mid; // correct
01234                                         int CountCxy = kCIx*End+kCIy;
01235                                         float fCR     = fkVecR[CountCxy];
01236                                         float fCI     = fkVecI[CountCxy];
01237                                         if (jr1+jr2==-1) {
01238                                         printf("jCountqxy=%d , Countqxy=%d, absD1fkVec(Countqxy)=%f,qx=%d, qy=%d \n", jCountqxy, Countqxy, absD1fkVec[Countqxy],qx, qy);
01239                                         printf(" CountCxy=%d,absD1fkVec[CountCxy]=%f,  kCx=%d,     kCy=%d \n",CountCxy, absD1fkVec[CountCxy], kCx, kCy );
01240                                         }
01241                                         for (int p=0; p<NK; p++){
01242 //                                              printf("p=%d, SortfkInds[p]=%d, CountCxy =%d \n", p,SortfkInds[p], CountCxy);
01243                                                 if (SortfkInds[p]==CountCxy){
01244                                                         float Arg1 = 2.0f*M_PI*r1*::sqrt((float) q2)/End;
01245                                                         float Arg2 = 2.0f*M_PI*r2*::sqrt((float) k2)/End;
01246 //                                                      printf("Arg1=%4.2f, Arg2=%4.2f,  \n",Arg1, Arg2 );
01247 //                                                      if (Arg1+ Arg2<15) {
01248                                                                 float bispectemp  = (fkR*(fqR*fCR -fqI*fCI) -fkI*(fqI*fCR  +fqR*fCI))
01249                                                                 * cos(N*(phiK-phiQ+M_PI));
01250                                                                 bispectemp  -= (fkR*(fqR*fCI + fqI*fCR) +fkI*(fqR*fCR - fqI*fCI))
01251                                                                 * sin(N*(phiK-phiQ+M_PI));
01252                                                                 float bess1 = calc_bessel(N, Arg1 );
01253                                                                 float bess2 = calc_bessel(N, Arg2 );
01254 //                      printf("fkr=%4.2f, fqr=%4.2f, bess1=%4.2f,bess2=%4.2f \n",fkR, fqR, bess1, bess2);
01255 /*                      printf("p =%d, SortfkInds[p]=%d, CountCxy=%d, Arg1 =%4.2f, bess1=%4.2f,  \n",
01256                                 p, SortfkInds[p],CountCxy, Arg1, bess1);*/
01257                                                                 RotTransInvTemp   = RotTransInvTemp  + bispectemp  * bess1*bess2 ;
01258 //                                                      }
01259                                                 }
01260                                         }
01261                                 } // jCountqxy
01262                         } // jCountkxy
01263                         RotTransInv -> set_value_at(jr1,jr2, RotTransInvTemp)   ;
01264 /*              RotTransInvN[jr1 + LradRange*jr2+LradRange*LradRange*N] = RotTransInvTemp  ;*/
01265                 } //jr2
01266         } //jr1
01267 // }//N
01268 
01269         return  RotTransInv ;
01270 
01271 
01272 }
01273 
01274 
01275 
01276 /*
01277 // find example
01278 #include <iostream>
01279 #include <algorithm>
01280 #include <vector>
01281 using namespace std;
01282 
01283 int main () {
01284   int myints[] = { 10, 20, 30 ,40 };
01285   int * p;
01286 
01287   // pointer to array element:
01288   p = find(myints,myints+4,30);
01289   ++p;
01290   cout << "The element following 30 is " << *p << endl;
01291 
01292   vector<int> myvector (myints,myints+4);
01293   vector<int>::iterator it;
01294 
01295   // iterator to vector element:
01296   it = find (myvector.begin(), myvector.end(), 30);
01297   ++it;
01298   cout << "The element following 30 is " << *it << endl;
01299 
01300   return 0;
01301 }*/
01302 
01303 EMData*   EMData::bispecRotTransInvDirect(int type)
01304 {
01305 
01306         int EndP = this -> get_xsize(); // length(fTrueVec);
01307         int Mid  = (int) ((1+EndP)/2);
01308         int End = 2*Mid-1;
01309 
01310         int CountxyMax = End*End;
01311 
01312 //      int   *SortfkInds       = new    int[CountxyMax];
01313         int   *kVecX            = new    int[CountxyMax];
01314         int   *kVecY            = new    int[CountxyMax];
01315         float *fkVecR           = new  float[CountxyMax];
01316         float *fkVecI           = new  float[CountxyMax];
01317         float *absD1fkVec       = new  float[CountxyMax];
01318 //      float *absD1fkVecSorted = new  float[CountxyMax];
01319 
01320 
01321         float *jxjyatan2         = new  float[End*End];
01322 
01323 
01324         EMData * ThisCopy = new EMData(End,End);
01325 
01326         for (int jx=0; jx <End ; jx++) {  // create jxjyatan2
01327                 for (int jy=0; jy <End ; jy++) {
01328                         float ValNow = this -> get_value_at(jx,jy);
01329                         ThisCopy -> set_value_at(jx,jy,ValNow);
01330                         jxjyatan2[jy*End + jx]  = atan2((float)(jy+1-Mid) , (float)(jx +1 -Mid));
01331 //              cout<< " jxM= " << jx+1<<" jyM= " << jy+1<< "ValNow" << ValNow << endl; //    Works
01332         }}
01333 
01334 
01335         EMData* fk = ThisCopy -> do_fft();
01336         fk          ->process_inplace("xform.fourierorigin.tocenter");
01337 
01338 //      Create kVecX , kVecy etc
01339 
01340         for (int kEx= 0; kEx<2*Mid; kEx=kEx+2) { // kEx twice the value of the Fourier
01341                                                 // x variable: EMAN index for real, imag
01342                 int kx    = kEx/2;              // kx  is  the value of the Fourier variable
01343                 int kIx   = kx+Mid-1; // This is the value of the index for a matlab image (-1)
01344                 int kCx   = -kx ;
01345                 int kCIx  = kCx+ Mid-1 ;
01346                 for (int kEy= 0 ; kEy<End; kEy++) { // This is the value of the EMAN index
01347                         int kIy              =  kEy       ; //  This is the value of the index for a matlab image (-1)
01348                         int ky               =  kEy+1-Mid; // (kEy+ Mid-1)%End - Mid+1 ;  // This is the actual value of the Fourier variable
01349                         float realVal        =  fk -> get_value_at(kEx  ,kEy) ;
01350                         float imagVal        =  fk -> get_value_at(kEx+1,kEy) ;
01351                         float absVal         =  ::sqrt(realVal*realVal+imagVal*imagVal);
01352                         float fkAng          =  atan2(imagVal,realVal);
01353 
01354                         float NewRealVal   ;
01355                         float NewImagVal   ;
01356                         float AngMatlab    ;
01357 
01358                         if (kIx==Mid-1) {
01359 //                              AngMatlab = -fkAng - 2.*M_PI*(kIy+ 1-Mid)*(Mid)/End;
01360                         }
01361 
01362                         if (kIx>Mid-1){
01363 //                      cout<< "i= " << i << " kIx= " << kIx << " kIy=" << kIy << " fkVecR[i] =" << fkVecR[i]<< " fkVecI[i]="  << fkVecI[i] <<"  angle[i]= "  << AngMatlab << endl;
01364                         }
01365 
01366                         AngMatlab = fkAng - 2.0f*M_PI*(kx +ky)*(Mid)/End;
01367                         NewRealVal  =   absVal*cos(AngMatlab);
01368                         NewImagVal  =   absVal*sin(AngMatlab);
01369 
01370 
01371                         fkVecR[ kIy +kIx *End] =  NewRealVal ;
01372                         fkVecR[(End-1-kIy)+kCIx*End] =  NewRealVal ;
01373                         fkVecI[ kIy +kIx *End] =  NewImagVal ;
01374                         fkVecI[(End-1-kIy)+kCIx*End] = -NewImagVal ;
01375                         absD1fkVec[(End-1-kIy) + kIx  *End] = absVal;
01376                         absD1fkVec[(End-1-kIy) + kCIx *End] = absVal;
01377                         kVecX[kIy+kIx  *End] =  kx      ;
01378                         kVecX[kIy+kCIx *End] =  kCx    ;
01379                         kVecY[kIy+kIx  *End] =  ky     ;
01380                         kVecY[kIy+kCIx *End] =  ky     ;
01381 
01382  //                     cout << " kIxM= " << kIx+1 << " kIy=" << kIy+1 << " fkVecR[i] =" << NewRealVal << " fkVecI[i]="  << NewImagVal <<"  angle[i]= "  << AngMatlab << " Total Index" << kIy+kIx *End << endl;
01383 
01384 //                      printf("kx=%d,ky=%d,tempVal =%f+ i %4.2f \n",kx,ky,realVal,imagVal );
01385 //                      cout << "kx = " << kx << "; ky = "<< ky << "; val is" << realVal<<"+ i "<<imagVal<< endl;
01386 
01387 //                      cout << "kIMx = "<< kIx+1 << "; kIMy = "<< kIy+1 <<"; fkAng*9/ 2pi is " << fkAng*9/2/M_PI<<  endl;
01388 //                      cout << "kIMx = "<< kIx+1 << "; kIMy = "<< kIy+1 <<"; absval is " << absVal<<  "; realval is " << NewRealVal<< "; imagval is " << NewImagVal<< endl;
01389                 }
01390         }
01391 
01392 
01393 //      for (int TotalInd = 0 ;  TotalInd < CountxyMax ; TotalInd++){
01394 //              int kx     = kVecX[TotalInd]; // This is the value of the index for a matlab image (-1)
01395 //              int kIx    = kx+Mid-1; // This is the value of the index for a matlab image (-1)
01396 //              int ky     = kVecY[TotalInd];
01397 //              int kIy    = ky+Mid-1; // This is the value of the index for a matlab image (-1)
01398                 //float fkR  = fkVecR[kIy+kIx *End]  ;
01399                 //float fkI  = fkVecI[kIy+kIx *End]  ;
01400 //      }
01401 
01402         float frR= 3.0/4.0;
01403         frR= 1;
01404         int LradRange= (int) (1+floor(Mid/frR -.1)) ;
01405 
01406         float *radRange = new float[LradRange]; //= 0:.75:(Mid-1);
01407         for (int irad=0; irad < LradRange; irad++){
01408                         radRange[irad] =  frR*irad;
01409 //                      cout << " irad = " << irad << " radRange[irad]= " <<  radRange[irad] <<  " LradRange= " << LradRange << endl;
01410         }
01411 
01412         cout << "Starting the calculation of invariants" << endl;
01413 
01414 
01415         if (type==0) {
01416                 int LthetaRange  = 59;
01417                 float ftR        = (2.0f*M_PI/LthetaRange );
01418                 float *thetaRange = new float[LthetaRange]; //= 0:.75:(Mid-1);
01419 
01420                 for (int ith=0; ith < LthetaRange; ith++){
01421                                 thetaRange[ith] =  ftR*ith; }
01422 
01423                 int TotalVol = LradRange*LradRange*LthetaRange;
01424 
01425                 float *RotTransInv   = new  float[TotalVol];
01426                 float *WeightInv     = new  float[TotalVol];
01427 
01428                 for (int jW=0; jW<TotalVol; jW++) {
01429                         RotTransInv[jW] = 0;
01430                         WeightInv[jW]   = 0;
01431                 }
01432 
01433                 for (int jW=0; jW<TotalVol; jW++) {
01434                         RotTransInv[jW] = 0;
01435                         WeightInv[jW]   = 0;
01436                 }
01437         //      float  *RotTransInv       = new float[LradRange*LradRange ] ;
01438         //      float  *RotTransInvN      = new float[LradRange*LradRange*(NMax+1) ] ;
01439 
01440                 for (int Countkxy =0; Countkxy<CountxyMax; Countkxy++){  // Main Section for type 0
01441                         int kx = kVecX[Countkxy] ;
01442                         int ky = kVecY[Countkxy] ;
01443                         float k2 = ::sqrt((float)(kx*kx+ky*ky));
01444                         float phiK =0;
01445                         if (k2>0)    phiK = jxjyatan2[ (ky+Mid-1)*End + kx+Mid-1]; //  phiK=atan2(ky,kx);
01446                         float fkR     = fkVecR[(ky+Mid-1) + (kx+Mid-1) *End] ;
01447                         float fkI     = fkVecI[(ky+Mid-1) + (kx+Mid-1) *End]  ;
01448         //              printf("Countkxy=%d,\t kx=%d, ky=%d, fkR=%3.2f,fkI=%3.2f \n", Countkxy, kx, ky, fkR, fkI);
01449 
01450                         if ((k2==0)|| (k2>Mid) ) { continue;}
01451 
01452                         for (int Countqxy =0; Countqxy<CountxyMax; Countqxy++){   // This is the innermost loop
01453                                 int qx   = kVecX[Countqxy] ;
01454                                 int qy   = kVecY[Countqxy] ;
01455                                 float q2   = ::sqrt((float)(qx*qx+qy*qy));
01456                                 if ((q2==0)|| (q2>Mid) ) {continue;}
01457                                 float phiQ =0;
01458                                 if (q2>0)   phiQ = jxjyatan2[ (qy+Mid-1)*End + qx+Mid-1]; // phiQ=atan2(qy,qx);
01459                                 float fqR     = fkVecR[(qy+Mid-1) + (qx+Mid-1) *End] ;
01460                                 float fqI     = fkVecI[(qy+Mid-1) + (qx+Mid-1) *End]  ;
01461                                 int kCx  = (-kx-qx);
01462                                 int kCy  = (-ky-qy);
01463                                 int kCIx = ((kCx+Mid+2*End)%End);// labels of the image in C
01464                                 int kCIy = ((kCy+Mid+2*End)%End);
01465                                 kCx  = ((kCIx+End-1)%End)+1-Mid; // correct
01466                                 kCy  = ((kCIy+End-1)%End)+1-Mid ; // correct
01467 
01468 //                              float C2   = ::sqrt((float)(kCx*kCx+ kCy*kCy));
01469                                 int CountCxy  = (kCx+Mid-1)*End+(kCy+Mid-1);
01470                                 float fCR     = fkVecR[CountCxy];
01471                                 float fCI     = fkVecI[CountCxy];
01472         /*                      if (Countkxy==1) {
01473                                         printf(" Countqxy=%d, absD1fkVec(Countqxy)=%f,qx=%d, qy=%d \n", Countqxy, absD1fkVec[Countqxy],qx, qy);
01474                                         printf(" CountCxy=%d, absD1fkVec[CountCxy]=%f,kCx=%d,kCy=%d \n",CountCxy, absD1fkVec[CountCxy], kCx, kCy );
01475                                 }*/
01476 //                              float   phiC = jxjyatan2[ (kCy+Mid-1)*End + kCx+Mid-1];
01477                                 float   phiQK = (4*M_PI+phiQ-phiK);
01478                                 while (phiQK> (2*M_PI)) phiQK -= (2*M_PI);
01479 
01480 
01481 
01482                                 float bispectemp  = (fkR*(fqR*fCR -fqI*fCI) -fkI*(fqI*fCR  +fqR*fCI));
01483 
01484                                 if  ((q2<k2) )  continue;
01485 //                              if  ((q2<k2) || (C2<k2) || (C2<q2))  continue;
01486 
01487         //                              printf(" CountCxy=%d, absD1fkVec[CountCxy]=%f,kCx=%d,kCy=%d \n",CountCxy, absD1fkVec[CountCxy], kCx, kCy );
01488 
01489         //                      up to here, matched perfectly with Matlab
01490 
01491                                 int k2IndLo  = 0; while ((k2>=radRange[k2IndLo+1]) && (k2IndLo+1 < LradRange ) ) k2IndLo +=1;
01492                                 int k2IndHi = k2IndLo;
01493                                 float k2Lo= radRange[k2IndLo];
01494                                 if (k2IndLo+1< LradRange) {
01495                                         k2IndHi   = k2IndLo+1;
01496                                 }
01497 //                              float k2Hi= radRange[k2IndHi];
01498 
01499                                 float kCof =k2-k2Lo;
01500 
01501                                 int q2IndLo  = 0; while ((q2>=radRange[q2IndLo+1]) && (q2IndLo+1 < LradRange ) ) q2IndLo +=1;
01502                                 int q2IndHi=q2IndLo;
01503                                 float q2Lo= radRange[q2IndLo];
01504                                 if (q2IndLo+1 < LradRange)  {
01505                                         q2IndHi   = q2IndLo+1 ;
01506                                 }
01507                                 float qCof = q2-q2Lo;
01508 
01509                                 if ((qCof<0) || (qCof >1) ) {
01510                                         cout<< "Weird! qCof="<< qCof <<  " q2="<< q2 << " q2IndLo="<< q2IndLo << endl ;
01511                                         int x    ;
01512                                         cin >> x ;
01513                                 }
01514 
01515                                 int thetaIndLo = 0; while ((phiQK>=thetaRange[thetaIndLo+1])&& (thetaIndLo+1<LthetaRange)) thetaIndLo +=1;
01516                                 int thetaIndHi = thetaIndLo;
01517 
01518                                 float thetaLo  = thetaRange[thetaIndLo];
01519                                 float thetaHi = thetaLo;
01520                                 float thetaCof = 0;
01521 
01522                                 if (thetaIndLo+1< LthetaRange) {
01523                                         thetaIndHi = thetaIndLo +1;
01524                                 }else{
01525                                         thetaIndHi=0;
01526                                 }
01527 
01528                                 thetaHi    = thetaRange[thetaIndHi];
01529 
01530                                 if (thetaHi==thetaLo) {
01531                                         thetaCof =0 ;
01532                                 } else {
01533                                         thetaCof   = (phiQK-thetaLo)/(thetaHi-thetaLo);
01534                                 }
01535 
01536                                 if ((thetaCof>2*M_PI)  ) {
01537                                         cout<< "Weird! thetaCof="<< thetaCof <<endl ;
01538                                         thetaCof=0;
01539                                 }
01540 
01541 
01542         //                      if ((thetaIndLo>=58) || (k2IndLo >= LradRange-1) || (q2IndLo >= LradRange-1) ) {
01543 
01544 
01545                                 for (int jk =1; jk<=2; jk++){
01546                                 for (int jq =1; jq<=2; jq++){
01547                                 for (int jtheta =1; jtheta<=2; jtheta++){
01548 
01549                                         float Weight = (kCof+(1-2*kCof)*(jk==1))*(qCof+(1-2*qCof)*(jq==1))
01550                                                         * (thetaCof+(1-2*thetaCof)*(jtheta==1));
01551 
01552 
01553                                         int k2Ind      =  k2IndLo*(jk==1)      +   k2IndHi*(jk==2);
01554                                         int q2Ind      =  q2IndLo*(jq==1)      +   q2IndHi*(jq==2);
01555                                         int thetaInd   =  thetaIndLo*(jtheta==1)  + thetaIndHi*(jtheta ==2);
01556                                         int TotalInd   = thetaInd*LradRange*LradRange+q2Ind*LradRange+k2Ind;
01557         /*                              if (TotalInd+1 >=  LthetaRange*LradRange*LradRange) {
01558                                                 cout << "Weird!!! TotalInd="<< TotalInd << " IndMax" << LthetaRange*LradRange*LradRange << " LradRange=" << LradRange << endl;
01559                                                 cout << "k2Ind= "<< k2Ind  << " q2Ind="<< q2Ind  << " thetaInd="<< thetaInd  << " q2IndLo="<< q2IndLo  << " q2IndHi="<< q2IndHi  <<  endl;
01560                                                 cout << "k2=" << k2 << "q2=" << q2 << " phiQK=" << phiQK*180.0/M_PI<< endl;
01561                                         }*/
01562 
01563                                         RotTransInv[TotalInd] += Weight*bispectemp;
01564                                         WeightInv[TotalInd]   +=  Weight;
01565         //                              cout << "k2Ind= "<< k2Ind  << " q2Ind="<< q2Ind  << "Weight=" << Weight << endl;
01566                                 }}}
01567                         } // Countqxy
01568                 } // Countkxy
01569 
01570                 cout << "Finished Main Section " << endl;
01571 
01572         /*              RotTransInvN[jr1 + LradRange*jr2+LradRange*LradRange*N] = RotTransInvTemp  ;*/
01573 
01574                 cout << " LradRange " <<LradRange <<" LthetaRange " << LthetaRange << endl;
01575                 EMData *RotTransInvF  = new  EMData(LradRange,LradRange,LthetaRange);
01576                 EMData *WeightImage   = new  EMData(LradRange,LradRange,LthetaRange);
01577 
01578         //      cout << "FFFFFFF" << endl;
01579         //
01580         //      RotTransInvF -> set_size(LradRange,LradRange,LthetaRange);
01581         //
01582         //      cout << "GGGG" << endl;
01583 
01584                 for (int jtheta =0; jtheta < LthetaRange; jtheta++){    // write out to RotTransInvF
01585                 for (int jq =0; jq<LradRange; jq++){ // LradRange
01586                 for (int jk =0; jk<LradRange ; jk++){// LradRange
01587         //              cout << "Hi There" << endl;
01588                         int TotalInd   = jtheta*LradRange*LradRange+jq*LradRange+jk;
01589                         float Weight = WeightInv[TotalInd];
01590                         WeightImage    -> set_value_at(jk,jq,jtheta,Weight);
01591                         RotTransInvF   -> set_value_at(jk,jq,jtheta,0);
01592                         if (Weight <= 0) continue;
01593                         RotTransInvF -> set_value_at(jk,jq,jtheta,RotTransInv[TotalInd] / Weight);//  include /Weight
01594                         int newjtheta = (LthetaRange- jtheta)%LthetaRange;
01595                         RotTransInvF -> set_value_at(jq,jk,newjtheta,RotTransInv[TotalInd]/Weight );//  include /Weight
01596                                 }
01597                         }
01598                 }
01599 
01600                 cout << " Almost Done " << endl;
01601                 system("rm -f WeightImage.???");
01602                 WeightImage  -> write_image("WeightImage.img");
01603 
01604                 return  RotTransInvF ;
01605         } // Finish type 0
01606 
01607         if (type==1) {
01608                 int TotalVol = LradRange*LradRange;
01609 
01610                 float *RotTransInv   = new  float[TotalVol];
01611                 float *WeightInv     = new  float[TotalVol];
01612 
01613                 for (int jW=0; jW<TotalVol; jW++) {
01614                         RotTransInv[jW] = 0;
01615                         WeightInv[jW]   = 0;
01616                 }
01617 
01618 
01619                 for (int Countkxy =0; Countkxy<CountxyMax; Countkxy++){
01620                         int kx = kVecX[Countkxy] ;
01621                         int ky = kVecY[Countkxy] ;
01622                         float k2 = ::sqrt((float)(kx*kx+ky*ky));
01623                         float fkR     = fkVecR[(ky+Mid-1) + (kx+Mid-1) *End] ;
01624                         float fkI     = fkVecI[(ky+Mid-1) + (kx+Mid-1) *End]  ;
01625         //              printf("Countkxy=%d,\t kx=%d, ky=%d, fkR=%3.2f,fkI=%3.2f \n", Countkxy, kx, ky, fkR, fkI);
01626 
01627                         if ((k2==0)|| (k2>Mid) ) { continue;}
01628 
01629                         for (int Countqxy =0; Countqxy<CountxyMax; Countqxy++){   // This is the innermost loop
01630 
01631 //                      up to here, matched perfectly with Matlab
01632                                 int qx   = kVecX[Countqxy] ;
01633                                 int qy   = kVecY[Countqxy] ;
01634                                 float q2   = ::sqrt((float)(qx*qx+qy*qy));
01635                                 if ((q2==0)|| (q2>Mid) ) {continue;}
01636                                 if  ((q2<k2) )   continue;
01637 
01638                                 float fqR     = fkVecR[(qy+Mid-1) + (qx+Mid-1) *End] ;
01639                                 float fqI     = fkVecI[(qy+Mid-1) + (qx+Mid-1) *End]  ;
01640 
01641                                 int kCx  = (-kx-qx);
01642                                 int kCy  = (-ky-qy);
01643                                 int kCIx = ((kCx+Mid+2*End)%End);// labels of the image in C
01644                                 int kCIy = ((kCy+Mid+2*End)%End);
01645                                 kCx  = ((kCIx+End-1)%End)+1-Mid; // correct
01646                                 kCy  = ((kCIy+End-1)%End)+1-Mid ; // correct
01647 
01648 //                              float C2   = ::sqrt((float)(kCx*kCx+ kCy*kCy));
01649                                 int CountCxy  = (kCx+Mid-1)*End+(kCy+Mid-1);
01650                                 float fCR     = fkVecR[CountCxy];
01651                                 float fCI     = fkVecI[CountCxy];
01652 
01653 
01654                                 float bispectemp  = (fkR*(fqR*fCR -fqI*fCI) -fkI*(fqI*fCR  +fqR*fCI));
01655 
01656 
01657                                 int k2IndLo  = 0; while ((k2>=radRange[k2IndLo+1]) && (k2IndLo+1 < LradRange ) ) k2IndLo +=1;
01658                                 int k2IndHi = k2IndLo;
01659                                 float k2Lo= radRange[k2IndLo];
01660                                 if (k2IndLo+1< LradRange) {
01661                                         k2IndHi   = k2IndLo+1;
01662                                 }
01663 //                              float k2Hi= radRange[k2IndHi];
01664 
01665                                 float kCof =k2-k2Lo;
01666 
01667                                 int q2IndLo  = 0; while ((q2>=radRange[q2IndLo+1]) && (q2IndLo+1 < LradRange ) ) q2IndLo +=1;
01668                                 int q2IndHi=q2IndLo;
01669                                 float q2Lo= radRange[q2IndLo];
01670                                 if (q2IndLo+1 < LradRange)  {
01671                                         q2IndHi   = q2IndLo+1 ;
01672                                 }
01673                                 float qCof = q2-q2Lo;
01674 
01675 
01676                                 for (int jk =1; jk<=2; jk++){
01677                                 for (int jq =1; jq<=2; jq++){
01678 
01679                                         float Weight = (kCof+(1-2*kCof)*(jk==1))*(qCof+(1-2*qCof)*(jq==1));
01680 
01681                                         int k2Ind      =  k2IndLo*(jk==1)      +   k2IndHi*(jk==2);
01682                                         int q2Ind      =  q2IndLo*(jq==1)      +   q2IndHi*(jq==2);
01683                                         int TotalInd   = q2Ind*LradRange+k2Ind;
01684                                         RotTransInv[TotalInd] += Weight*bispectemp;
01685                                         WeightInv[TotalInd]   +=  Weight;
01686         //                              cout << "k2Ind= "<< k2Ind  << " q2Ind="<< q2Ind  << "Weight=" << Weight << endl;
01687                                 }}
01688                         } // Countqxy
01689                 } // Countkxy
01690 
01691 //              cout << "Finished Main Section " << endl;
01692 //              cout << " LradRange " <<LradRange <<  endl;
01693 
01694 
01695                 EMData *RotTransInvF  = new  EMData(LradRange,LradRange);
01696                 EMData *WeightImage   = new  EMData(LradRange,LradRange);
01697 
01698                 for (int jk =0; jk<LradRange ; jk++){// LradRange
01699                 for (int jq =jk; jq<LradRange; jq++){ // LradRange
01700                         int TotalInd      = jq*LradRange+jk;
01701                         int TotalIndBar   = jq*LradRange+jk;
01702                         float Weight = WeightInv[TotalInd] + WeightInv[TotalIndBar];
01703                         if (Weight <=0) continue;
01704                         WeightImage    -> set_value_at(jk,jq,Weight);
01705                         WeightImage    -> set_value_at(jq,jk,Weight);
01706 #ifdef _WIN32
01707                         float ValNow  = pow( (RotTransInv[TotalInd] + RotTransInv[TotalIndBar]) / Weight, 1.0f/3.0f )  ;
01708 #else
01709                         float ValNow  = cbrt( (RotTransInv[TotalInd] + RotTransInv[TotalIndBar]) / Weight )  ;
01710 #endif  //_WIN32
01711                         RotTransInvF -> set_value_at(jk,jq,ValNow);//  include /Weight
01712                         RotTransInvF -> set_value_at(jq,jk,ValNow );//  include /Weight
01713                 }}
01714 
01715                 system("rm -f WeightImage.???");
01716                 WeightImage  -> write_image("WeightImage.img");
01717 
01718                 return  RotTransInvF ;
01719         }
01720         return 0;
01721 }
01722 
01723 
01724 void EMData::insert_clip(const EMData * const block, const IntPoint &origin) {
01725         int nx1 = block->get_xsize();
01726         int ny1 = block->get_ysize();
01727         int nz1 = block->get_zsize();
01728 
01729         Region area(origin[0], origin[1], origin[2],nx1, ny1, nz1);
01730 
01731         int x0 = (int) area.origin[0];
01732         x0 = x0 < 0 ? 0 : x0;
01733 
01734         int y0 = (int) area.origin[1];
01735         y0 = y0 < 0 ? 0 : y0;
01736 
01737         int z0 = (int) area.origin[2];
01738         z0 = z0 < 0 ? 0 : z0;
01739 
01740         int x1 = (int) (area.origin[0] + area.size[0]);
01741         x1 = x1 > nx ? nx : x1;
01742 
01743         int y1 = (int) (area.origin[1] + area.size[1]);
01744         y1 = y1 > ny ? ny : y1;
01745 
01746         int z1 = (int) (area.origin[2] + area.size[2]);
01747         z1 = z1 > nz ? nz : z1;
01748         if (z1 <= 0) {
01749                 z1 = 1;
01750         }
01751 
01752         int xd0 = (int) (area.origin[0] < 0 ? -area.origin[0] : 0);
01753         int yd0 = (int) (area.origin[1] < 0 ? -area.origin[1] : 0);
01754         int zd0 = (int) (area.origin[2] < 0 ? -area.origin[2] : 0);
01755 
01756         if (x1 < x0 || y1 < y0 || z1 < z0) return; // out of bounds, this is fine, nothing happens
01757 
01758         size_t clipped_row_size = (x1-x0) * sizeof(float);
01759         int src_secsize =  nx1 * ny1;
01760         int dst_secsize = nx * ny;
01761 
01762 #ifdef EMAN2_USING_CUDA
01763         if (gpu_operation_preferred()) {
01764 //              cudaMemcpy3DParms copyParams = {0};
01765 //              copyParams.srcPtr   = make_cudaPitchedPtr((void*)get_cuda_data(), nx*sizeof(float), nx, ny);
01766 //              cout << "Src pos is " << x0 << " " << y0 << " " << z0 << endl;
01767 //              copyParams.srcPos  = make_cudaPos(x0,y0,z0);
01768 //              cout << "Extent is " << x1-x0 << " " << y1-y0 << " " << z1-z0 << endl;
01769 //              cudaExtent extent = make_cudaExtent(x1-x0,y1-y0,z1-z0);
01770 //              int rnx = result->get_xsize();
01771 //              int rny = result->get_ysize();
01772 //              copyParams.dstPtr = make_cudaPitchedPtr((void*)result->get_cuda_data(),rnx*sizeof(float),rnx,rny );
01773 //              cout << "Dest pos is " << xd0 << " " << yd0 << " " << zd0 << endl;
01774 //              copyParams.dstPos  = make_cudaPos(xd0,yd0,zd0);
01775 //              copyParams.extent   = extent;
01776 //              copyParams.kind     = cudaMemcpyDeviceToDevice;
01777 //              cudaError_t error =  cudaMemcpy3D(&copyParams);
01778 //              if ( error != cudaSuccess) {
01779 //                      string e = cudaGetErrorString(error);
01780 //                      throw UnexpectedBehaviorException("CudaMemcpy3D failed with error: " + e);
01781 //              }
01782                 get_cuda_data();
01783                 CudaDataLock lock(this);
01784                 block->get_cuda_data();
01785                 CudaDataLock lock2(block);
01786                 for (int i = 0; i < (z1-z0); i++) {
01787                         float* ldst = get_cuda_data() + (z0+i) * dst_secsize + y0 * nx + x0;
01788                         float* lsrc = block->get_cuda_data() + (zd0+i) * src_secsize + yd0 * nx1 + xd0;
01789 
01790 
01791 //                      float* ldst = result->get_cuda_data() + (zd0+i) * dst_secsize + yd0 * (int)area.size[0] + xd0;
01792 //                      float* lsrc = get_cuda_data() + (z0+i) * src_secsize + y0 * nx + x0;
01793                         cudaError_t error =  cudaMemcpy2D( ldst, (nx)*sizeof(float), lsrc,nx1*sizeof(float), clipped_row_size, (y1-y0), cudaMemcpyDeviceToDevice );
01794                         if ( error != cudaSuccess) {
01795                                 string e = cudaGetErrorString(error);
01796                                 throw UnexpectedBehaviorException("cudaMemcpy2D failed in get_clip with error: " + e);
01797                         }
01798                 }
01799                 gpu_update();
01800                 EXITFUNC;
01801                 return;
01802         }
01803 #endif
01804         float *src = block->get_data() + zd0 * src_secsize + yd0 * nx1 + xd0;
01805         float *dst = get_data() + z0 * dst_secsize + y0 * nx + x0;
01806 
01807 //              float *src = get_data() + z0 * src_secsize + y0 * nx + x0;
01808 //              float *dst = result->get_data();
01809 //              dst += zd0 * dst_secsize + yd0 * (int)area.size[0] + xd0;
01810 
01811         int src_gap = src_secsize - (y1-y0) * nx1;
01812         int dst_gap = dst_secsize - (y1-y0) * nx;
01813         for (int i = z0; i < z1; i++) {
01814                 for (int j = y0; j < y1; j++) {
01815                         EMUtil::em_memcpy(dst, src, clipped_row_size);
01816                         src += nx1;
01817                         dst += nx;
01818                 }
01819                 src += src_gap;
01820                 dst += dst_gap;
01821         }
01822 
01823         update();
01824         EXITFUNC;
01825 }
01826 
01827 
01828 void EMData::insert_scaled_sum(EMData *block, const FloatPoint &center,
01829                                                    float scale, float)
01830 {
01831         ENTERFUNC;
01832         float * data = get_data();
01833         if (get_ndim()==3) {
01834                 // Start by determining the region to operate on
01835                 int xs=(int)floor(block->get_xsize()*scale/2.0);
01836                 int ys=(int)floor(block->get_ysize()*scale/2.0);
01837                 int zs=(int)floor(block->get_zsize()*scale/2.0);
01838                 int x0=(int)center[0]-xs;
01839                 int x1=(int)center[0]+xs;
01840                 int y0=(int)center[1]-ys;
01841                 int y1=(int)center[1]+ys;
01842                 int z0=(int)center[2]-zs;
01843                 int z1=(int)center[2]+zs;
01844 
01845                 if (x1<0||y1<0||z1<0||x0>get_xsize()||y0>get_ysize()||z0>get_zsize()) return;   // object is completely outside the target volume
01846 
01847                 // make sure we stay inside the volume
01848                 if (x0<0) x0=0;
01849                 if (y0<0) y0=0;
01850                 if (z0<0) z0=0;
01851                 if (x1>=get_xsize()) x1=get_xsize()-1;
01852                 if (y1>=get_ysize()) y1=get_ysize()-1;
01853                 if (z1>=get_zsize()) z1=get_zsize()-1;
01854 
01855                 float bx=block->get_xsize()/2.0f;
01856                 float by=block->get_ysize()/2.0f;
01857                 float bz=block->get_zsize()/2.0f;
01858 
01859                 size_t idx;
01860                 for (int x=x0; x<=x1; x++) {
01861                         for (int y=y0; y<=y1; y++) {
01862                                 for (int z=z0; z<=z1; z++) {
01863                                         idx = x + y * nx + z * nx * ny;
01864                                         data[idx] +=
01865                                                 block->sget_value_at_interp((x-center[0])/scale+bx,(y-center[1])/scale+by,(z-center[2])/scale+bz);
01866                                 }
01867                         }
01868                 }
01869                 update();
01870         }
01871         else if (get_ndim()==2) {
01872                 // Start by determining the region to operate on
01873                 int xs=(int)floor(block->get_xsize()*scale/2.0);
01874                 int ys=(int)floor(block->get_ysize()*scale/2.0);
01875                 int x0=(int)center[0]-xs;
01876                 int x1=(int)center[0]+xs;
01877                 int y0=(int)center[1]-ys;
01878                 int y1=(int)center[1]+ys;
01879 
01880                 if (x1<0||y1<0||x0>get_xsize()||y0>get_ysize()) return; // object is completely outside the target volume
01881 
01882                 // make sure we stay inside the volume
01883                 if (x0<0) x0=0;
01884                 if (y0<0) y0=0;
01885                 if (x1>=get_xsize()) x1=get_xsize()-1;
01886                 if (y1>=get_ysize()) y1=get_ysize()-1;
01887 
01888                 float bx=block->get_xsize()/2.0f;
01889                 float by=block->get_ysize()/2.0f;
01890 
01891                 for (int x=x0; x<=x1; x++) {
01892                         for (int y=y0; y<=y1; y++) {
01893                                 data[x + y * nx] +=
01894                                         block->sget_value_at_interp((x-center[0])/scale+bx,(y-center[1])/scale+by);
01895                         }
01896                 }
01897                 update();
01898         }
01899         else {
01900                 LOGERR("insert_scaled_sum supports only 2D and 3D data");
01901                 throw ImageDimensionException("2D/3D only");
01902         }
01903 
01904         EXITFUNC;
01905 }
01906 //                      else if ( m == 0 )
01907 //                      {
01908 //                              if ( n_f == -ny/2 )
01909 //                              {
01910 //                                      t2++;
01911 // //                                   continue;
01912 //                                      for (int y = 0; y < return_slice->get_ysize(); ++y) {
01913 //                                              for (int x = 0; x < return_slice->get_xsize(); ++x) {
01914 //                                                      double cur_val = return_slice->get_value_at(x,y);
01915 //                                                      return_slice->set_value_at(x,y,cur_val+dat[idx]*std::pow(-1.0f,y));
01916 //                                              }
01917 //                                      }
01918 //                                      if (phase > 0.01 ) cout << "foo 2 " << phase << " " << amp << " " << dat[idx] << endl;
01919 //                              }
01920 //                              else
01921 //                              {
01922 //                                      if ( n_f < 1 ) continue;
01923 //                                      t3++;
01924 //                                      for (int y = 0; y < return_slice->get_ysize(); ++y) {
01925 //                                              for (int x = 0; x < return_slice->get_xsize(); ++x) {
01926 //                                                      double cur_val = return_slice->get_value_at(x,y);
01927 //                                                      return_slice->set_value_at(x,y,cur_val+2*amp*cos(ndash*y+phase));
01928 //                                              }
01929 //                                      }
01930 //                              }
01931 //                      }
01932 //                      else if ( n_f == -ny/2 )
01933 //                      {
01934 //                              if ( m == ((nx-2)/2) )
01935 //                              {
01936 //                                      t4++;
01937 //                                      for (int y = 0; y < return_slice->get_ysize(); ++y) {
01938 //                                              for (int x = 0; x < return_slice->get_xsize(); ++x) {
01939 //                                                      double cur_val = return_slice->get_value_at(x,y);
01940 //                                                      return_slice->set_value_at(x,y,cur_val+dat[idx]*std::pow(-1.0f,x+y));
01941 //                                              }
01942 //                                      }
01943 //                                      if (phase > 0.01 ) cout << "foo 4 " << phase << " " << amp << " " << dat[idx] << endl;
01944 //                              }
01945 //                              else
01946 //                              {
01947 //                                      t5++;
01948 //                                      for (int y = 0; y < return_slice->get_ysize(); ++y) {
01949 //                                              for (int x = 0; x < return_slice->get_xsize(); ++x) {
01950 //                                                      double cur_val = return_slice->get_value_at(x,y);
01951 //                                                      return_slice->set_value_at(x,y,cur_val+2*amp*cos(mdash*x+phase));
01952 //                                              }
01953 //                                      }
01954 //                              }
01955 //                      }
01956 //                      else if ( n_f == 0 )
01957 //                      {
01958 //                              if ( m == ((nx-2)/2) )
01959 //                              {
01960 //                                      t6++;
01961 //                                      for (int y = 0; y < return_slice->get_ysize(); ++y) {
01962 //                                              for (int x = 0; x < return_slice->get_xsize(); ++x) {
01963 //                                                      double cur_val = return_slice->get_value_at(x,y);
01964 //                                                      return_slice->set_value_at(x,y,cur_val+dat[idx]*std::pow(-1.0f,x));
01965 //                                              }
01966 //                                      }
01967 //                                      if (phase > 0.01 ) cout << "foo 3 " << phase << " " << amp << " " << dat[idx] << endl;
01968 //                              }
01969 //                              else
01970 //                              {
01971 //                                      t7++;
01972 //                                      for (int y = 0; y < return_slice->get_ysize(); ++y) {
01973 //                                              for (int x = 0; x < return_slice->get_xsize(); ++x) {
01974 //                                                      double cur_val = return_slice->get_value_at(x,y);
01975 //                                                      return_slice->set_value_at(x,y,cur_val+2*amp*cos(mdash*x+M_PI*y + phase));
01976 //                                              }
01977 //                                      }
01978 //                              }
01979 //                      }
01980 //                      else if ( m == ((nx-2)/2) )
01981 //                      {
01982 //                              if ( n_f < 1 ) continue;
01983 //                              t8++;
01984 //                              for (int y = 0; y < return_slice->get_ysize(); ++y) {
01985 //                                      for (int x = 0; x < return_slice->get_xsize(); ++x) {
01986 //                                              double cur_val = return_slice->get_value_at(x,y);
01987 //                                              return_slice->set_value_at(x,y,cur_val+2*amp*cos(ndash*y+M_PI*x+phase));
01988 //                                      }
01989 //                              }
01990 //                      }
01991 // }

Generated on Thu Dec 9 13:45:45 2010 for EMAN2 by  doxygen 1.3.9.1