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