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

Generated on Thu Nov 17 12:42:58 2011 for EMAN2 by  doxygen 1.4.7