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 "all_imageio.h"
00038 #include "ctf.h"
00039 #include "processor.h"
00040 #include "aligner.h"
00041 #include "cmp.h"
00042 #include "emfft.h"
00043 #include "projector.h"
00044 #include "geometry.h"
00045
00046 #include <gsl/gsl_sf_bessel.h>
00047 #include <gsl/gsl_errno.h>
00048
00049 #include <iomanip>
00050 #include <complex>
00051
00052 #include <algorithm>
00053 #include <cmath>
00054
00055 #ifdef WIN32
00056 #define M_PI 3.14159265358979323846f
00057 #endif //WIN32
00058
00059 #define EMDATA_EMAN2_DEBUG 0
00060
00061 #ifdef EMAN2_USING_CUDA
00062
00063 #include "cuda/cuda_processor.h"
00064 #include "cuda/cuda_emfft.h"
00065 #endif // EMAN2_USING_CUDA
00066
00067 using namespace EMAN;
00068 using namespace std;
00069 using namespace boost;
00070
00071 int EMData::totalalloc=0;
00072
00073 EMData::EMData() :
00074 #ifdef EMAN2_USING_CUDA
00075 cudarwdata(0), cudarodata(0), num_bytes(0), nextlistitem(0), prevlistitem(0), roneedsupdate(0),
00076 #endif
00077 attr_dict(), rdata(0), supp(0), flags(0), changecount(0), nx(0), ny(0), nz(0), nxy(0), nxyz(0), xoff(0), yoff(0),
00078 zoff(0), all_translation(), path(""), pathnum(0), rot_fp(0)
00079
00080 {
00081 ENTERFUNC;
00082
00083 attr_dict["apix_x"] = 1.0f;
00084 attr_dict["apix_y"] = 1.0f;
00085 attr_dict["apix_z"] = 1.0f;
00086
00087 attr_dict["is_complex"] = int(0);
00088 attr_dict["is_complex_x"] = int(0);
00089 attr_dict["is_complex_ri"] = int(1);
00090
00091 attr_dict["datatype"] = (int)EMUtil::EM_FLOAT;
00092
00093 EMData::totalalloc++;
00094 #ifdef MEMDEBUG2
00095 printf("EMDATA+ %4d %p\n",EMData::totalalloc,this);
00096 #endif
00097
00098 EXITFUNC;
00099 }
00100
00101 EMData::EMData(const string& filename, int image_index) :
00102 #ifdef EMAN2_USING_CUDA
00103 cudarwdata(0), cudarodata(0), num_bytes(0), nextlistitem(0), prevlistitem(0), roneedsupdate(0),
00104 #endif
00105 attr_dict(), rdata(0), supp(0), flags(0), changecount(0), nx(0), ny(0), nz(0), nxy(0), nxyz(0), xoff(0), yoff(0), zoff(0),
00106 all_translation(), path(filename), pathnum(image_index), rot_fp(0)
00107 {
00108 ENTERFUNC;
00109
00110 attr_dict["apix_x"] = 1.0f;
00111 attr_dict["apix_y"] = 1.0f;
00112 attr_dict["apix_z"] = 1.0f;
00113
00114 attr_dict["is_complex"] = int(0);
00115 attr_dict["is_complex_x"] = int(0);
00116 attr_dict["is_complex_ri"] = int(1);
00117
00118 attr_dict["datatype"] = (int)EMUtil::EM_FLOAT;
00119
00120 this->read_image(filename, image_index);
00121
00122 update();
00123 EMData::totalalloc++;
00124 #ifdef MEMDEBUG2
00125 printf("EMDATA+ %4d %p\n",EMData::totalalloc,this);
00126 #endif
00127
00128 EXITFUNC;
00129 }
00130
00131 EMData::EMData(const EMData& that) :
00132 #ifdef EMAN2_USING_CUDA
00133 cudarwdata(0), cudarodata(0), num_bytes(0), nextlistitem(0), prevlistitem(0), roneedsupdate(0),
00134 #endif
00135 attr_dict(that.attr_dict), rdata(0), supp(0), flags(that.flags), changecount(that.changecount), nx(that.nx), ny(that.ny), nz(that.nz),
00136 nxy(that.nx*that.ny), nxyz((size_t)that.nx*that.ny*that.nz), xoff(that.xoff), yoff(that.yoff), zoff(that.zoff),all_translation(that.all_translation), path(that.path),
00137 pathnum(that.pathnum), rot_fp(0)
00138 {
00139 ENTERFUNC;
00140
00141 float* data = that.rdata;
00142 size_t num_bytes = (size_t)nx*ny*nz*sizeof(float);
00143 if (data && num_bytes != 0)
00144 {
00145 rdata = (float*)EMUtil::em_malloc(num_bytes);
00146 EMUtil::em_memcpy(rdata, data, num_bytes);
00147 }
00148 #ifdef EMAN2_USING_CUDA
00149 if (num_bytes != 0 && that.cudarwdata != 0) {
00150
00151 rw_alloc();
00152 cudaError_t error = cudaMemcpy(cudarwdata,that.cudarwdata,num_bytes,cudaMemcpyDeviceToDevice);
00153 if ( error != cudaSuccess ) throw UnexpectedBehaviorException("cudaMemcpy failed in EMData copy construction with error: " + string(cudaGetErrorString(error)));
00154 }
00155 #endif //EMAN2_USING_CUDA
00156
00157 if (that.rot_fp != 0) rot_fp = new EMData(*(that.rot_fp));
00158
00159 EMData::totalalloc++;
00160 #ifdef MEMDEBUG2
00161 printf("EMDATA+ %4d %p\n",EMData::totalalloc,this);
00162 #endif
00163
00164 ENTERFUNC;
00165 }
00166
00167 EMData& EMData::operator=(const EMData& that)
00168 {
00169 ENTERFUNC;
00170
00171 if ( this != &that )
00172 {
00173 free_memory();
00174
00175
00176 float* data = that.rdata;
00177 size_t num_bytes = that.nx*that.ny*that.nz*sizeof(float);
00178 if (data && num_bytes != 0)
00179 {
00180 nx = 1;
00181 set_size(that.nx,that.ny,that.nz);
00182 EMUtil::em_memcpy(rdata, data, num_bytes);
00183 }
00184
00185 flags = that.flags;
00186
00187 all_translation = that.all_translation;
00188
00189 path = that.path;
00190 pathnum = that.pathnum;
00191 attr_dict = that.attr_dict;
00192
00193 xoff = that.xoff;
00194 yoff = that.yoff;
00195 zoff = that.zoff;
00196
00197 #ifdef EMAN2_USING_CUDA
00198 cout << "That copy constructor #2" << endl;
00199 if (num_bytes != 0 && that.cudarwdata != 0) {
00200 rw_alloc();
00201 cudaError_t error = cudaMemcpy(cudarwdata,that.cudarwdata,num_bytes,cudaMemcpyDeviceToDevice);
00202 if ( error != cudaSuccess ) throw UnexpectedBehaviorException("cudaMemcpy failed in EMData copy construction with error: " + string(cudaGetErrorString(error)));
00203
00204 }
00205 #endif //EMAN2_USING_CUDA
00206
00207 changecount = that.changecount;
00208
00209 if (that.rot_fp != 0) rot_fp = new EMData(*(that.rot_fp));
00210 else rot_fp = 0;
00211 }
00212 EXITFUNC;
00213 return *this;
00214 }
00215
00216 EMData::EMData(int nx, int ny, int nz, bool is_real) :
00217 #ifdef EMAN2_USING_CUDA
00218 cudarwdata(0), cudarodata(0), num_bytes(0), nextlistitem(0), prevlistitem(0), roneedsupdate(0),
00219 #endif
00220 attr_dict(), rdata(0), supp(0), flags(0), changecount(0), nx(0), ny(0), nz(0), nxy(0), nxyz(0), xoff(0), yoff(0), zoff(0),
00221 all_translation(), path(""), pathnum(0), rot_fp(0)
00222 {
00223 ENTERFUNC;
00224
00225
00226 attr_dict["apix_x"] = 1.0f;
00227 attr_dict["apix_y"] = 1.0f;
00228 attr_dict["apix_z"] = 1.0f;
00229
00230 if(is_real) {
00231 attr_dict["is_complex"] = int(0);
00232 attr_dict["is_complex_x"] = int(0);
00233 attr_dict["is_complex_ri"] = int(1);
00234 set_size(nx, ny, nz);
00235 }
00236 else {
00237 int new_nx = nx + 2 - nx%2;
00238 set_size(new_nx, ny, nz);
00239
00240 attr_dict["is_complex"] = int(1);
00241
00242 if(ny==1 && nz ==1) {
00243 attr_dict["is_complex_x"] = int(1);
00244 }
00245 else {
00246 attr_dict["is_complex_x"] = int(0);
00247 }
00248
00249 attr_dict["is_complex_ri"] = int(1);
00250 attr_dict["is_fftpad"] = int(1);
00251
00252 if(nx%2 == 1) {
00253 attr_dict["is_fftodd"] = 1;
00254 }
00255 }
00256
00257 this->to_zero();
00258 update();
00259 EMData::totalalloc++;
00260 #ifdef MEMDEBUG2
00261 printf("EMDATA+ %4d %p\n",EMData::totalalloc,this);
00262 #endif
00263
00264 EXITFUNC;
00265 }
00266
00267
00268 EMData::EMData(float* data, const int x, const int y, const int z, const Dict& attr_dict) :
00269 #ifdef EMAN2_USING_CUDA
00270 cudarwdata(0), cudarodata(0), num_bytes(0), nextlistitem(0), prevlistitem(0), roneedsupdate(0),
00271 #endif
00272 attr_dict(attr_dict), rdata(data), supp(0), flags(0), changecount(0), nx(x), ny(y), nz(z), nxy(x*y), nxyz((size_t)x*y*z), xoff(0),
00273 yoff(0), zoff(0), all_translation(), path(""), pathnum(0), rot_fp(0)
00274 {
00275 ENTERFUNC;
00276
00277 attr_dict["apix_x"] = 1.0f;
00278 attr_dict["apix_y"] = 1.0f;
00279 attr_dict["apix_z"] = 1.0f;
00280
00281 EMData::totalalloc++;
00282 #ifdef MEMDEBUG2
00283 printf("EMDATA+ %4d %p\n",EMData::totalalloc,this);
00284 #endif
00285
00286 update();
00287 EXITFUNC;
00288 }
00289
00290 #ifdef EMAN2_USING_CUDA
00291
00292 EMData::EMData(float* data, float* cudadata, const int x, const int y, const int z, const Dict& attr_dict) :
00293 cudarwdata(cudadata), cudarodata(0), num_bytes(x*y*z*sizeof(float)), nextlistitem(0), prevlistitem(0), roneedsupdate(0),
00294 attr_dict(attr_dict), rdata(data), supp(0), flags(0), changecount(0), nx(x), ny(y), nz(z), nxy(x*y), nxyz((size_t)x*y*z), xoff(0),
00295 yoff(0), zoff(0), all_translation(), path(""), pathnum(0), rot_fp(0)
00296 {
00297 ENTERFUNC;
00298
00299
00300 attr_dict["apix_x"] = 1.0f;
00301 attr_dict["apix_y"] = 1.0f;
00302 attr_dict["apix_z"] = 1.0f;
00303
00304 EMData::totalalloc++;
00305 #ifdef MEMDEBUG2
00306 printf("EMDATA+ %4d %p\n",EMData::totalalloc,this);
00307 #endif
00308
00309 update();
00310 EXITFUNC;
00311 }
00312
00313 #endif //EMAN2_USING_CUDA
00314
00315
00316 using std::cout;
00317 using std::endl;
00318 EMData::~EMData()
00319 {
00320 ENTERFUNC;
00321 free_memory();
00322
00323 #ifdef EMAN2_USING_CUDA
00324 if(cudarwdata){rw_free();}
00325 if(cudarodata){ro_free();}
00326 #endif // EMAN2_USING_CUDA
00327 EMData::totalalloc--;
00328 #ifdef MEMDEBUG2
00329 printf("EMDATA- %4d %p\n",EMData::totalalloc,this);
00330 #endif
00331 EXITFUNC;
00332 }
00333
00334 void EMData::clip_inplace(const Region & area,const float& fill_value)
00335 {
00336
00337 ENTERFUNC;
00338
00339
00340
00341 int prev_nx = nx, prev_ny = ny, prev_nz = nz;
00342 size_t prev_size = (size_t)nx*ny*nz;
00343
00344
00345 int new_nz = ( area.size[2]==0 ? 1 : (int)area.size[2]);
00346 int new_ny = ( area.size[1]==0 ? 1 : (int)area.size[1]);
00347 int new_nx = (int)area.size[0];
00348
00349 if ( new_nz < 0 || new_ny < 0 || new_nx < 0 )
00350 {
00351
00352 throw ImageDimensionException("New image dimensions are negative - this is not supported in the clip_inplace operation");
00353 }
00354
00355 size_t new_size = (size_t)new_nz*new_ny*new_nx;
00356
00357
00358 int x0 = (int) area.origin[0];
00359 int y0 = (int) area.origin[1];
00360 int z0 = (int) area.origin[2];
00361
00362
00363 ClipInplaceVariables civ(prev_nx, prev_ny, prev_nz, new_nx, new_ny, new_nz, x0, y0, z0);
00364
00365 get_data();
00366
00367 if ( x0 > prev_nx || y0 > prev_ny || z0 > prev_nz || civ.x_iter == 0 || civ.y_iter == 0 || civ.z_iter == 0)
00368 {
00369
00370
00371
00372
00373 set_size(new_nx, new_ny, new_nz);
00374
00375
00376 EMUtil::em_memset(rdata, 0, (size_t)new_nx*new_ny*new_nz);
00377
00378 return;
00379 }
00380
00381
00382
00383
00384 if ( new_size > prev_size )
00385 set_size(new_nx, new_ny, new_nz);
00386
00387
00388 size_t clipped_row_size = (civ.x_iter) * sizeof(float);
00389
00390
00391 size_t new_sec_size = new_nx * new_ny;
00392 size_t prev_sec_size = prev_nx * prev_ny;
00393
00394
00395
00396 size_t src_it_begin = civ.prv_z_bottom*prev_sec_size + civ.prv_y_front*prev_nx + civ.prv_x_left;
00397 size_t dst_it_begin = civ.new_z_bottom*new_sec_size + civ.new_y_front*new_nx + civ.new_x_left;
00398
00399
00400
00401
00402 for (int i = 0; i < civ.z_iter; ++i) {
00403 for (int j = 0; j < civ.y_iter; ++j) {
00404
00405
00406
00407 size_t dst_inc = dst_it_begin + j*new_nx + i*new_sec_size;
00408 size_t src_inc = src_it_begin + j*prev_nx + i*prev_sec_size;
00409 float* local_dst = rdata + dst_inc;
00410 float* local_src = rdata + src_inc;
00411
00412 if ( dst_inc >= src_inc )
00413 {
00414
00415
00416
00417 continue;
00418 }
00419
00420
00421
00422 Assert( dst_inc < new_size && src_inc < prev_size && dst_inc >= 0 && src_inc >= 0 );
00423
00424
00425 EMUtil::em_memcpy(local_dst, local_src, clipped_row_size);
00426 }
00427 }
00428
00429
00430
00431 size_t src_it_end = prev_size - civ.prv_z_top*prev_sec_size - civ.prv_y_back*prev_nx - prev_nx + civ.prv_x_left;
00432 size_t dst_it_end = new_size - civ.new_z_top*new_sec_size - civ.new_y_back*new_nx - new_nx + civ.new_x_left;
00433
00434
00435
00436
00437 for (int i = 0; i < civ.z_iter; ++i) {
00438 for (int j = 0; j < civ.y_iter; ++j) {
00439
00440
00441 size_t dst_inc = dst_it_end - j*new_nx - i*new_sec_size;
00442 size_t src_inc = src_it_end - j*prev_nx - i*prev_sec_size;
00443 float* local_dst = rdata + dst_inc;
00444 float* local_src = rdata + src_inc;
00445
00446 if (dst_inc <= (src_inc + civ.x_iter ))
00447 {
00448
00449 if ( dst_inc > src_inc )
00450 {
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461 memmove(local_dst, local_src, clipped_row_size);
00462 }
00463 continue;
00464 }
00465
00466
00467 Assert( dst_inc < new_size && src_inc < prev_size && dst_inc >= 0 && src_inc >= 0 );
00468
00469
00470 EMUtil::em_memcpy(local_dst, local_src, clipped_row_size);
00471 }
00472 }
00473
00474
00475
00476 if ( new_size < prev_size )
00477 set_size(new_nx, new_ny, new_nz);
00478
00479
00480
00481
00482 if ( z0 < 0 )
00483 {
00484
00485 size_t inc = (-z0)*new_sec_size;
00486 std::fill(rdata,rdata+inc,fill_value);
00487 }
00488
00489
00490 if ( civ.new_z_top > 0 )
00491 {
00492 float* begin_pointer = rdata + (new_nz-civ.new_z_top)*new_sec_size;
00493
00494 float* end_pointer = begin_pointer+(civ.new_z_top)*new_sec_size;
00495 std::fill(begin_pointer,end_pointer,fill_value);
00496 }
00497
00498
00499 for ( int i = civ.new_z_bottom; i < civ.new_z_bottom + civ.z_iter; ++i )
00500 {
00501
00502 if ( y0 < 0 )
00503 {
00504 float* begin_pointer = rdata + i*new_sec_size;
00505
00506 float* end_pointer = begin_pointer+(-y0)*new_nx;
00507 std::fill(begin_pointer,end_pointer,fill_value);
00508 }
00509
00510
00511 if ( civ.new_y_back > 0 )
00512 {
00513 float* begin_pointer = rdata + i*new_sec_size + (new_ny-civ.new_y_back)*new_nx;
00514
00515 float* end_pointer = begin_pointer+(civ.new_y_back)*new_nx;
00516 std::fill(begin_pointer,end_pointer,fill_value);
00517 }
00518
00519
00520 for (int j = civ.new_y_front; j <civ.new_y_front + civ.y_iter; ++j)
00521 {
00522
00523 if ( x0 < 0 )
00524 {
00525 float* begin_pointer = rdata + i*new_sec_size + j*new_nx;
00526
00527 float* end_pointer = begin_pointer+(-x0);
00528 std::fill(begin_pointer,end_pointer,fill_value);
00529 }
00530
00531
00532 if ( civ.new_x_right > 0 )
00533 {
00534 float* begin_pointer = rdata + i*new_sec_size + j*new_nx + (new_nx - civ.new_x_right);
00535
00536 float* end_pointer = begin_pointer+(civ.new_x_right);
00537 std::fill(begin_pointer,end_pointer,fill_value);
00538 }
00539
00540 }
00541 }
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554 if( attr_dict.has_key("origin_x") && attr_dict.has_key("origin_y") &&
00555 attr_dict.has_key("origin_z") )
00556 {
00557 float xorigin = attr_dict["origin_x"];
00558 float yorigin = attr_dict["origin_y"];
00559 float zorigin = attr_dict["origin_z"];
00560
00561 float apix_x = attr_dict["apix_x"];
00562 float apix_y = attr_dict["apix_y"];
00563 float apix_z = attr_dict["apix_z"];
00564
00565 set_xyz_origin(xorigin + apix_x * area.origin[0],
00566 yorigin + apix_y * area.origin[1],
00567 zorigin + apix_z * area.origin[2]);
00568 }
00569
00570
00571 update();
00572
00573 EXITFUNC;
00574 }
00575
00576 EMData *EMData::get_clip(const Region & area, const float fill) const
00577 {
00578 ENTERFUNC;
00579 if (get_ndim() != area.get_ndim()) {
00580 LOGERR("cannot get %dD clip out of %dD image", area.get_ndim(),get_ndim());
00581 return 0;
00582 }
00583
00584 EMData *result = new EMData();
00585
00586
00587
00588
00589 result->attr_dict = this->attr_dict;
00590 int zsize = (int)area.size[2];
00591 if (zsize == 0 && nz <= 1) {
00592 zsize = 1;
00593 }
00594 int ysize = (ny<=1 && (int)area.size[1]==0 ? 1 : (int)area.size[1]);
00595
00596 if ( (int)area.size[0] < 0 || ysize < 0 || zsize < 0 )
00597 {
00598
00599 throw ImageDimensionException("New image dimensions are negative - this is not supported in the the get_clip operation");
00600 }
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617 result->set_size((int)area.size[0], ysize, zsize);
00618 if (fill != 0.0) { result->to_value(fill); };
00619
00620
00621 int x0 = (int) area.origin[0];
00622 x0 = x0 < 0 ? 0 : x0;
00623
00624 int y0 = (int) area.origin[1];
00625 y0 = y0 < 0 ? 0 : y0;
00626
00627 int z0 = (int) area.origin[2];
00628 z0 = z0 < 0 ? 0 : z0;
00629
00630 int x1 = (int) (area.origin[0] + area.size[0]);
00631 x1 = x1 > nx ? nx : x1;
00632
00633 int y1 = (int) (area.origin[1] + area.size[1]);
00634 y1 = y1 > ny ? ny : y1;
00635
00636 int z1 = (int) (area.origin[2] + area.size[2]);
00637 z1 = z1 > nz ? nz : z1;
00638 if (z1 <= 0) {
00639 z1 = 1;
00640 }
00641
00642 result->insert_clip(this,-((IntPoint)area.origin));
00643
00644 if( attr_dict.has_key("apix_x") && attr_dict.has_key("apix_y") &&
00645 attr_dict.has_key("apix_z") )
00646 {
00647 if( attr_dict.has_key("origin_x") && attr_dict.has_key("origin_y") &&
00648 attr_dict.has_key("origin_z") )
00649 {
00650 float xorigin = attr_dict["origin_x"];
00651 float yorigin = attr_dict["origin_y"];
00652 float zorigin = attr_dict["origin_z"];
00653
00654 float apix_x = attr_dict["apix_x"];
00655 float apix_y = attr_dict["apix_y"];
00656 float apix_z = attr_dict["apix_z"];
00657
00658 result->set_xyz_origin(xorigin + apix_x * area.origin[0],
00659 yorigin + apix_y * area.origin[1],
00660 zorigin + apix_z * area.origin[2]);
00661 }
00662 }
00663
00664
00665
00666
00667
00668 result->update();
00669
00670
00671
00672 result->set_path(path);
00673 result->set_pathnum(pathnum);
00674
00675 EXITFUNC;
00676 return result;
00677 }
00678
00679
00680 EMData *EMData::get_top_half() const
00681 {
00682 ENTERFUNC;
00683
00684 if (get_ndim() != 3) {
00685 throw ImageDimensionException("3D only");
00686 }
00687
00688 EMData *half = new EMData();
00689 half->attr_dict = attr_dict;
00690 half->set_size(nx, ny, nz / 2);
00691
00692 float *half_data = half->get_data();
00693 EMUtil::em_memcpy(half_data, &(get_data()[(size_t)nz / 2 * (size_t)nx * (size_t)ny]), sizeof(float) * (size_t)nx * (size_t)ny * (size_t)nz / 2lu);
00694
00695 float apix_z = attr_dict["apix_z"];
00696 float origin_z = attr_dict["origin_z"];
00697 origin_z += apix_z * nz / 2;
00698 half->attr_dict["origin_z"] = origin_z;
00699 half->update();
00700
00701 EXITFUNC;
00702 return half;
00703 }
00704
00705
00706 EMData *EMData::get_rotated_clip(const Transform &xform,
00707 const IntSize &size, float)
00708 {
00709 EMData *result = new EMData();
00710 result->set_size(size[0],size[1],size[2]);
00711
00712 if (nz==1) {
00713 for (int y=-size[1]/2; y<(size[1]+1)/2; y++) {
00714 for (int x=-size[0]/2; x<(size[0]+1)/2; x++) {
00715 Vec3f xv=xform.transform(Vec3f((float)x,(float)y,0.0f));
00716 float v = 0;
00717
00718 if (xv[0]<0||xv[1]<0||xv[0]>nx-2||xv[1]>ny-2) v=0.;
00719 else v=sget_value_at_interp(xv[0],xv[1]);
00720 result->set_value_at(x+size[0]/2,y+size[1]/2,v);
00721 }
00722 }
00723 }
00724 else {
00725 for (int z=-size[2]/2; z<(size[2]+1)/2; z++) {
00726 for (int y=-size[1]/2; y<(size[1]+1)/2; y++) {
00727 for (int x=-size[0]/2; x<(size[0]+1)/2; x++) {
00728 Vec3f xv=xform.transform(Vec3f((float)x,(float)y,0.0f));
00729 float v = 0;
00730
00731 if (xv[0]<0||xv[1]<0||xv[2]<0||xv[0]>nx-2||xv[1]>ny-2||xv[2]>nz-2) v=0.;
00732 else v=sget_value_at_interp(xv[0],xv[1],xv[2]);
00733 result->set_value_at(x+size[0]/2,y+size[1]/2,z+size[2]/2,v);
00734 }
00735 }
00736 }
00737 }
00738 result->update();
00739
00740 return result;
00741 }
00742
00743
00744 EMData* EMData::window_center(int l) {
00745 ENTERFUNC;
00746
00747 int n = nx;
00748 if (is_complex()) {
00749 LOGERR("Need real-space data for window_center()");
00750 throw ImageFormatException(
00751 "Complex input image; real-space expected.");
00752 }
00753 if (is_fftpadded()) {
00754
00755 n -= (2 - int(is_fftodd()));
00756 }
00757 int corner = n/2 - l/2;
00758 int ndim = get_ndim();
00759 EMData* ret;
00760 switch (ndim) {
00761 case 3:
00762 if ((n != ny) || (n != nz)) {
00763 LOGERR("Need the real-space image to be cubic.");
00764 throw ImageFormatException(
00765 "Need cubic real-space image.");
00766 }
00767 ret = get_clip(Region(corner, corner, corner, l, l, l));
00768 break;
00769 case 2:
00770 if (n != ny) {
00771 LOGERR("Need the real-space image to be square.");
00772 throw ImageFormatException(
00773 "Need square real-space image.");
00774 }
00775
00776 ret = get_clip(Region(corner, corner, l, l));
00777 break;
00778 case 1:
00779 ret = get_clip(Region(corner, l));
00780 break;
00781 default:
00782 throw ImageDimensionException(
00783 "window_center only supports 1-d, 2-d, and 3-d images");
00784 }
00785 return ret;
00786 EXITFUNC;
00787 }
00788
00789
00790 float *EMData::setup4slice(bool redo)
00791 {
00792 ENTERFUNC;
00793
00794 if (!is_complex()) {
00795 throw ImageFormatException("complex image only");
00796 }
00797
00798 if (get_ndim() != 3) {
00799 throw ImageDimensionException("3D only");
00800 }
00801
00802 if (supp) {
00803 if (redo) {
00804 EMUtil::em_free(supp);
00805 supp = 0;
00806 }
00807 else {
00808 EXITFUNC;
00809 return supp;
00810 }
00811 }
00812
00813 const int SUPP_ROW_SIZE = 8;
00814 const int SUPP_ROW_OFFSET = 4;
00815 const int supp_size = SUPP_ROW_SIZE + SUPP_ROW_OFFSET;
00816
00817 supp = (float *) EMUtil::em_calloc(supp_size * ny * nz, sizeof(float));
00818 int nxy = nx * ny;
00819 int supp_xy = supp_size * ny;
00820 float * data = get_data();
00821
00822 for (int z = 0; z < nz; z++) {
00823 size_t cur_z1 = z * nxy;
00824 size_t cur_z2 = z * supp_xy;
00825
00826 for (int y = 0; y < ny; y++) {
00827 size_t cur_y1 = y * nx;
00828 size_t cur_y2 = y * supp_size;
00829
00830 for (int x = 0; x < SUPP_ROW_SIZE; x++) {
00831 size_t k = (x + SUPP_ROW_OFFSET) + cur_y2 + cur_z2;
00832 supp[k] = data[x + cur_y1 + cur_z1];
00833 }
00834 }
00835 }
00836
00837 for (int z = 1, zz = nz - 1; z < nz; z++, zz--) {
00838 size_t cur_z1 = zz * nxy;
00839 size_t cur_z2 = z * supp_xy;
00840
00841 for (int y = 1, yy = ny - 1; y < ny; y++, yy--) {
00842 supp[y * 12 + cur_z2] = data[4 + yy * nx + cur_z1];
00843 supp[1 + y * 12 + cur_z2] = -data[5 + yy * nx + cur_z1];
00844 supp[2 + y * 12 + cur_z2] = data[2 + yy * nx + cur_z1];
00845 supp[3 + y * 12 + cur_z2] = -data[3 + yy * nx + cur_z1];
00846 }
00847 }
00848
00849 EXITFUNC;
00850 return supp;
00851 }
00852
00853
00854 void EMData::scale(float s)
00855 {
00856 ENTERFUNC;
00857 Transform t;
00858 t.set_scale(s);
00859 transform(t);
00860 EXITFUNC;
00861 }
00862
00863
00864 void EMData::translate(int dx, int dy, int dz)
00865 {
00866 ENTERFUNC;
00867 translate(Vec3i(dx, dy, dz));
00868 EXITFUNC;
00869 }
00870
00871
00872 void EMData::translate(float dx, float dy, float dz)
00873 {
00874 ENTERFUNC;
00875 int dx_ = Util::round(dx);
00876 int dy_ = Util::round(dy);
00877 int dz_ = Util::round(dz);
00878 if( ( (dx-dx_) == 0 ) && ( (dy-dy_) == 0 ) && ( (dz-dz_) == 0 )) {
00879 translate(dx_, dy_, dz_);
00880 }
00881 else {
00882 translate(Vec3f(dx, dy, dz));
00883 }
00884 EXITFUNC;
00885 }
00886
00887
00888 void EMData::translate(const Vec3i &translation)
00889 {
00890 ENTERFUNC;
00891
00892
00893 if( translation[0] == 0 && translation[1] == 0 && translation[2] == 0) {
00894 EXITFUNC;
00895 return;
00896 }
00897
00898 Dict params("trans",static_cast< vector<int> >(translation));
00899 process_inplace("math.translate.int",params);
00900
00901
00902 all_translation += translation;
00903
00904 EXITFUNC;
00905 }
00906
00907
00908 void EMData::translate(const Vec3f &translation)
00909 {
00910 ENTERFUNC;
00911
00912 if( translation[0] == 0.0f && translation[1] == 0.0f && translation[2] == 0.0f ) {
00913 EXITFUNC;
00914 return;
00915 }
00916
00917 Transform* t = new Transform();
00918 t->set_trans(translation);
00919 process_inplace("xform",Dict("transform",t));
00920 delete t;
00921
00922 all_translation += translation;
00923 EXITFUNC;
00924 }
00925
00926
00927 void EMData::rotate(float az, float alt, float phi)
00928 {
00929 Dict d("type","eman");
00930 d["az"] = az;
00931 d["alt"] = alt;
00932 d["phi"] = phi;
00933 Transform t(d);
00934 transform(t);
00935 }
00936
00937
00938
00939 void EMData::rotate(const Transform & t)
00940 {
00941 cout << "Deprecation warning in EMData::rotate. Please consider using EMData::transform() instead " << endl;
00942 transform(t);
00943 }
00944
00945 float EMData::max_3D_pixel_error(const Transform &t1, const Transform & t2, float r) {
00946
00947 Transform t;
00948 int r0 = (int)r;
00949 float ddmax = 0.0f;
00950
00951 t = t2*t1.inverse();
00952 for (int i=0; i<int(2*M_PI*r0+0.5); i++) {
00953 Vec3f v = Vec3f(r0*cos((float)i), r0*sin((float)i), 0);
00954 Vec3f d = t*v-v;
00955 float dd = d[0]*d[0]+d[1]*d[1]+d[2]*d[2];
00956 if (dd > ddmax) ddmax = dd;
00957 }
00958 return std::sqrt(ddmax);
00959 }
00960
00961 void EMData::rotate_translate(float az, float alt, float phi, float dx, float dy, float dz)
00962 {
00963 cout << "Deprecation warning in EMData::rotate_translate. Please consider using EMData::transform() instead " << endl;
00964
00965 Transform t;
00966 t.set_rotation(Dict("type", "eman", "az", az, "alt", alt, "phi", phi));
00967 t.set_trans(dx, dy, dz);
00968 rotate_translate(t);
00969 }
00970
00971
00972 void EMData::rotate_translate(float az, float alt, float phi, float dx, float dy,
00973 float dz, float pdx, float pdy, float pdz)
00974 {
00975 cout << "Deprecation warning in EMData::rotate_translate. Please consider using EMData::transform() instead " << endl;
00976
00977
00978
00979 Transform t;
00980 t.set_pre_trans(Vec3f(dx, dy, dz));
00981 t.set_rotation(Dict("type", "eman", "az", az, "alt", alt, "phi", phi));
00982 t.set_trans(pdx, pdy, pdz);
00983 rotate_translate(t);
00984 }
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
01000
01002
01003
01004
01005
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175 void EMData::rotate_x(int dx)
01176 {
01177 ENTERFUNC;
01178
01179 if (get_ndim() > 2) {
01180 throw ImageDimensionException("no 3D image");
01181 }
01182
01183
01184 size_t row_size = nx * sizeof(float);
01185 float *tmp = (float*)EMUtil::em_malloc(row_size);
01186 float * data = get_data();
01187
01188 for (int y = 0; y < ny; y++) {
01189 int y_nx = y * nx;
01190 for (int x = 0; x < nx; x++) {
01191 tmp[x] = data[y_nx + (x + dx) % nx];
01192 }
01193 EMUtil::em_memcpy(&data[y_nx], tmp, row_size);
01194 }
01195
01196 update();
01197 if( tmp )
01198 {
01199 delete[]tmp;
01200 tmp = 0;
01201 }
01202 EXITFUNC;
01203 }
01204
01205 double EMData::dot_rotate_translate(EMData * with, float dx, float dy, float da, const bool mirror)
01206 {
01207 ENTERFUNC;
01208
01209 if (!EMUtil::is_same_size(this, with)) {
01210 LOGERR("images not same size");
01211 throw ImageFormatException("images not same size");
01212 }
01213
01214 if (get_ndim() == 3) {
01215 LOGERR("1D/2D Images only");
01216 throw ImageDimensionException("1D/2D only");
01217 }
01218
01219 float *this_data = 0;
01220
01221 this_data = get_data();
01222
01223 float da_rad = da*(float)M_PI/180.0f;
01224
01225 float *with_data = with->get_data();
01226 float mx0 = cos(da_rad);
01227 float mx1 = sin(da_rad);
01228 float y = -ny / 2.0f;
01229 float my0 = mx0 * (-nx / 2.0f - 1.0f) + nx / 2.0f - dx;
01230 float my1 = -mx1 * (-nx / 2.0f - 1.0f) + ny / 2.0f - dy;
01231 double result = 0;
01232
01233 for (int j = 0; j < ny; j++) {
01234 float x2 = my0 + mx1 * y;
01235 float y2 = my1 + mx0 * y;
01236
01237 int ii = Util::fast_floor(x2);
01238 int jj = Util::fast_floor(y2);
01239 float t = x2 - ii;
01240 float u = y2 - jj;
01241
01242 for (int i = 0; i < nx; i++) {
01243 t += mx0;
01244 u -= mx1;
01245
01246 if (t >= 1.0f) {
01247 ii++;
01248 t -= 1.0f;
01249 }
01250
01251 if (u >= 1.0f) {
01252 jj++;
01253 u -= 1.0f;
01254 }
01255
01256 if (t < 0) {
01257 ii--;
01258 t += 1.0f;
01259 }
01260
01261 if (u < 0) {
01262 jj--;
01263 u += 1.0f;
01264 }
01265
01266 if (ii >= 0 && ii <= nx - 2 && jj >= 0 && jj <= ny - 2) {
01267 int k0 = ii + jj * nx;
01268 int k1 = k0 + 1;
01269 int k2 = k0 + nx + 1;
01270 int k3 = k0 + nx;
01271
01272 float tt = 1 - t;
01273 float uu = 1 - u;
01274 int idx = i + j * nx;
01275 if (mirror) idx = nx-1-i+j*nx;
01276 result += (this_data[k0] * tt * uu + this_data[k1] * t * uu +
01277 this_data[k2] * t * u + this_data[k3] * tt * u) * with_data[idx];
01278 }
01279 }
01280 y += 1.0f;
01281 }
01282
01283 EXITFUNC;
01284 return result;
01285 }
01286
01287
01288 EMData *EMData::little_big_dot(EMData * with, bool do_sigma)
01289 {
01290 ENTERFUNC;
01291
01292 if (get_ndim() > 2) {
01293 throw ImageDimensionException("1D/2D only");
01294 }
01295
01296 EMData *ret = copy_head();
01297 ret->set_size(nx,ny,nz);
01298 ret->to_zero();
01299
01300 int nx2 = with->get_xsize();
01301 int ny2 = with->get_ysize();
01302 float em = with->get_edge_mean();
01303
01304 float *data = get_data();
01305 float *with_data = with->get_data();
01306 float *ret_data = ret->get_data();
01307
01308 float sum2 = (Util::square((float)with->get_attr("sigma")) +
01309 Util::square((float)with->get_attr("mean")));
01310 if (do_sigma) {
01311 for (int j = ny2 / 2; j < ny - ny2 / 2; j++) {
01312 for (int i = nx2 / 2; i < nx - nx2 / 2; i++) {
01313 float sum = 0;
01314 float sum1 = 0;
01315 float summ = 0;
01316 int k = 0;
01317
01318 for (int jj = j - ny2 / 2; jj < j + ny2 / 2; jj++) {
01319 for (int ii = i - nx2 / 2; ii < i + nx2 / 2; ii++) {
01320 int l = ii + jj * nx;
01321 sum1 += Util::square(data[l]);
01322 summ += data[l];
01323 sum += data[l] * with_data[k];
01324 k++;
01325 }
01326 }
01327 float tmp_f1 = (sum1 / 2.0f - sum) / (nx2 * ny2);
01328 float tmp_f2 = Util::square((float)with->get_attr("mean") -
01329 summ / (nx2 * ny2));
01330 ret_data[i + j * nx] = sum2 + tmp_f1 - tmp_f2;
01331 }
01332 }
01333 }
01334 else {
01335 for (int j = ny2 / 2; j < ny - ny2 / 2; j++) {
01336 for (int i = nx2 / 2; i < nx - nx2 / 2; i++) {
01337 float eml = 0;
01338 float dot = 0;
01339 float dot2 = 0;
01340
01341 for (int ii = i - nx2 / 2; ii < i + nx2 / 2; ii++) {
01342 eml += data[ii + (j - ny2 / 2) * nx] + data[ii + (j + ny2 / 2 - 1) * nx];
01343 }
01344
01345 for (int jj = j - ny2 / 2; jj < j + ny2 / 2; jj++) {
01346 eml += data[i - nx2 / 2 + jj * nx] + data[i + nx2 / 2 - 1 + jj * nx];
01347 }
01348
01349 eml /= (nx2 + ny2) * 2.0f;
01350 int k = 0;
01351
01352 for (int jj = j - ny2 / 2; jj < j + ny2 / 2; jj++) {
01353 for (int ii = i - nx2 / 2; ii < i + nx2 / 2; ii++) {
01354 dot += (data[ii + jj * nx] - eml) * (with_data[k] - em);
01355 dot2 += Util::square(data[ii + jj * nx] - eml);
01356 k++;
01357 }
01358 }
01359
01360 dot2 = std::sqrt(dot2);
01361
01362 if (dot2 == 0) {
01363 ret_data[i + j * nx] = 0;
01364 }
01365 else {
01366 ret_data[i + j * nx] = dot / (nx2 * ny2 * dot2 * (float)with->get_attr("sigma"));
01367 }
01368 }
01369 }
01370 }
01371
01372 ret->update();
01373
01374 EXITFUNC;
01375 return ret;
01376 }
01377
01378
01379 EMData *EMData::do_radon()
01380 {
01381 ENTERFUNC;
01382
01383 if (get_ndim() != 2) {
01384 throw ImageDimensionException("2D only");
01385 }
01386
01387 if (nx != ny) {
01388 throw ImageFormatException("square image only");
01389 }
01390
01391 EMData *result = new EMData();
01392 result->set_size(nx, ny, 1);
01393 result->to_zero();
01394 float *result_data = result->get_data();
01395
01396 EMData *this_copy = this;
01397 this_copy = copy();
01398
01399 for (int i = 0; i < nx; i++) {
01400 Transform t(Dict("type","2d","alpha",(float) M_PI * 2.0f * i / nx));
01401 this_copy->transform(t);
01402
01403 float *copy_data = this_copy->get_data();
01404
01405 for (int y = 0; y < nx; y++) {
01406 for (int x = 0; x < nx; x++) {
01407 if (Util::square(x - nx / 2) + Util::square(y - nx / 2) <= nx * nx / 4) {
01408 result_data[i + y * nx] += copy_data[x + y * nx];
01409 }
01410 }
01411 }
01412
01413 this_copy->update();
01414 }
01415
01416 result->update();
01417
01418 if( this_copy )
01419 {
01420 delete this_copy;
01421 this_copy = 0;
01422 }
01423
01424 EXITFUNC;
01425 return result;
01426 }
01427
01428 void EMData::zero_corner_circulant(const int radius)
01429 {
01430 if ( nz > 1 && nz < (2*radius+1) ) throw ImageDimensionException("Error: cannot zero corner - nz is too small");
01431 if ( ny > 1 && ny < (2*radius+1) ) throw ImageDimensionException("Error: cannot zero corner - ny is too small");
01432 if ( nx > 1 && nx < (2*radius+1) ) throw ImageDimensionException("Error: cannot zero corner - nx is too small");
01433
01434 int it_z = radius;
01435 int it_y = radius;
01436 int it_x = radius;
01437
01438 if ( nz == 1 ) it_z = 0;
01439 if ( ny == 1 ) it_y = 0;
01440 if ( nx == 1 ) it_z = 0;
01441
01442 if ( nz == 1 && ny == 1 )
01443 {
01444 for ( int x = -it_x; x <= it_x; ++x )
01445 get_value_at_wrap(x) = 0;
01446
01447 }
01448 else if ( nz == 1 )
01449 {
01450 for ( int y = -it_y; y <= it_y; ++y)
01451 for ( int x = -it_x; x <= it_x; ++x )
01452 get_value_at_wrap(x,y) = 0;
01453 }
01454 else
01455 {
01456 for( int z = -it_z; z <= it_z; ++z )
01457 for ( int y = -it_y; y <= it_y; ++y)
01458 for ( int x = -it_x; x < it_x; ++x )
01459 get_value_at_wrap(x,y,z) = 0;
01460
01461 }
01462
01463 }
01464
01465 EMData *EMData::calc_ccf(EMData * with, fp_flag fpflag,bool center)
01466 {
01467 ENTERFUNC;
01468
01469 if( with == 0 ) {
01470 #ifdef EMAN2_USING_CUDA //CUDA
01471 if(cudarwdata) {
01472 EMData* ifft = 0;
01473 bool delifft = false;
01474 int offset = 0;
01475
01476
01477 if(!is_complex()){
01478 ifft = do_fft_cuda();
01479 delifft = true;
01480 offset = 2 - nx%2;
01481 }else{
01482 ifft = this;
01483 }
01484 calc_conv_cuda(ifft->cudarwdata,ifft->cudarwdata,nx + offset, ny, nz);
01485
01486 EMData * conv = ifft->do_ift_cuda();
01487 if(delifft) delete ifft;
01488
01489 return conv;
01490 }
01491 #endif
01492 EXITFUNC;
01493 return convolution(this,this,fpflag, center);
01494 }
01495 else if ( with == this ){
01496 EXITFUNC;
01497 return correlation(this, this, fpflag,center);
01498 }
01499 else {
01500
01501 #ifdef EMAN2_USING_CUDA //CUDA
01502
01503
01504
01505 if(cudarwdata && with->cudarwdata) {
01506
01507 EMData* afft = 0;
01508 EMData* bfft = 0;
01509 bool delafft = false, delbfft = false;
01510 int offset = 0;
01511
01512
01513 if(!is_complex()){
01514 afft = do_fft_cuda();
01515 delafft = true;
01516 offset = 2 - nx%2;
01517
01518 }else{
01519 afft = this;
01520 }
01521 if(!with->is_complex()){
01522 bfft = with->do_fft_cuda();
01523
01524 delbfft = true;
01525 }else{
01526 bfft = with;
01527 }
01528
01529 calc_ccf_cuda(afft->cudarwdata,bfft->cudarwdata,nx + offset, ny, nz);
01530
01531 if(delbfft) delete bfft;
01532
01533 EMData * corr = afft->do_ift_cuda();
01534 if(delafft) delete afft;
01535
01536
01537 return corr;
01538 }
01539 #endif
01540
01541
01542 bool undoresize = false;
01543 int wnx = with->get_xsize(); int wny = with->get_ysize(); int wnz = with->get_zsize();
01544 if (!(is_complex() ^ with->is_complex()) && (wnx != nx || wny != ny || wnz != nz)) {
01545 cout << "Warning!!! resizing image before CCF calculation" << endl;
01546 Region r((wnx-nx)/2, (wny-ny)/2, (wnz-nz)/2,nx,ny,nz);
01547 with->clip_inplace(r);
01548 undoresize = true;
01549 }
01550
01551 EMData* cor = correlation(this, with, fpflag, center);
01552
01553
01554 if ( undoresize ) {
01555 Region r((nx-wnx)/2, (ny-wny)/2,(nz-wnz)/2,wnx,wny,wnz);
01556 with->clip_inplace(r);
01557 }
01558
01559 EXITFUNC;
01560 return cor;
01561 }
01562 }
01563
01564 EMData *EMData::calc_ccfx( EMData * const with, int y0, int y1, bool no_sum, bool flip)
01565 {
01566 ENTERFUNC;
01567
01568 if (!with) {
01569 LOGERR("NULL 'with' image. ");
01570 throw NullPointerException("NULL input image");
01571 }
01572
01573 if (!EMUtil::is_same_size(this, with)) {
01574 LOGERR("images not same size: (%d,%d,%d) != (%d,%d,%d)",
01575 nx, ny, nz,
01576 with->get_xsize(), with->get_ysize(), with->get_zsize());
01577 throw ImageFormatException("images not same size");
01578 }
01579 if (get_ndim() > 2) {
01580 LOGERR("2D images only");
01581 throw ImageDimensionException("2D images only");
01582 }
01583
01584 if (y1 <= y0) {
01585 y1 = ny;
01586 }
01587
01588 if (y0 >= y1) {
01589 y0 = 0;
01590 }
01591
01592 if (y0 < 0) {
01593 y0 = 0;
01594 }
01595
01596 if (y1 > ny) {
01597 y1 = ny;
01598 }
01599 if (is_complex_x() || with->is_complex_x() ) throw;
01600
01601 static int nx_fft = 0;
01602 static int ny_fft = 0;
01603 static EMData f1;
01604 static EMData f2;
01605 static EMData rslt;
01606
01607 int height = y1-y0;
01608 int width = (nx+2-(nx%2));
01609 if (width != nx_fft || height != ny_fft ) {
01610 f1.set_size(width,height);
01611 f2.set_size(width,height);
01612 rslt.set_size(nx,height);
01613 nx_fft = width;
01614 ny_fft = height;
01615 }
01616
01617 #ifdef EMAN2_USING_CUDA
01618 if (cudarwdata && with->cudarwdata) {
01619
01620 if(!f1.cudarwdata) f1.rw_alloc();
01621 if(!f2.cudarwdata) f2.rw_alloc();
01622 if(!rslt.cudarwdata) rslt.rw_alloc();
01623 cuda_dd_fft_real_to_complex_nd(cudarwdata, f1.cudarwdata, nx, 1, 1, height);
01624 cuda_dd_fft_real_to_complex_nd(with->cudarwdata, f2.cudarwdata, nx, 1, 1, height);
01625 calc_ccf_cuda(f1.cudarwdata, f2.cudarwdata, nx, ny, nz);
01626 cuda_dd_fft_complex_to_real_nd(f1.cudarwdata, rslt.cudarwdata, nx, 1, 1, height);
01627 if(no_sum){
01628 EMData* result = new EMData(rslt);
01629 return result;
01630 }
01631 EMData* cf = new EMData(0,0,nx,1,1);
01632 cf->runcuda(emdata_column_sum(rslt.cudarwdata, nx, ny));
01633
01634 EXITFUNC;
01635 return cf;
01636 }
01637 #endif
01638
01639 float *d1 = get_data();
01640 float *d2 = with->get_data();
01641 float *f1d = f1.get_data();
01642 float *f2d = f2.get_data();
01643 for (int j = 0; j < height; j++) {
01644 EMfft::real_to_complex_1d(d1 + j * nx, f1d+j*width, nx);
01645 EMfft::real_to_complex_1d(d2 + j * nx, f2d+j*width, nx);
01646 }
01647
01648 if(flip == false) {
01649 for (int j = 0; j < height; j++) {
01650 float *f1a = f1d + j * width;
01651 float *f2a = f2d + j * width;
01652
01653 for (int i = 0; i < width / 2; i++) {
01654 float re1 = f1a[2*i];
01655 float re2 = f2a[2*i];
01656 float im1 = f1a[2*i+1];
01657 float im2 = f2a[2*i+1];
01658
01659 f1d[j*width+i*2] = re1 * re2 + im1 * im2;
01660 f1d[j*width+i*2+1] = im1 * re2 - re1 * im2;
01661 }
01662 }
01663 } else {
01664 for (int j = 0; j < height; j++) {
01665 float *f1a = f1d + j * width;
01666 float *f2a = f2d + j * width;
01667
01668 for (int i = 0; i < width / 2; i++) {
01669 float re1 = f1a[2*i];
01670 float re2 = f2a[2*i];
01671 float im1 = f1a[2*i+1];
01672 float im2 = f2a[2*i+1];
01673
01674 f1d[j*width+i*2] = re1 * re2 - im1 * im2;
01675 f1d[j*width+i*2+1] = im1 * re2 + re1 * im2;
01676 }
01677 }
01678 }
01679
01680 float* rd = rslt.get_data();
01681 for (int j = y0; j < y1; j++) {
01682 EMfft::complex_to_real_1d(f1d+j*width, rd+j*nx, nx);
01683 }
01684
01685 if (no_sum) {
01686 rslt.update();
01687 EXITFUNC;
01688 return new EMData(rslt);
01689 } else {
01690 EMData *cf = new EMData(nx,1,1);
01691 cf->to_zero();
01692 float *c = cf->get_data();
01693 for (int j = 0; j < height; j++) {
01694 for(int i = 0; i < nx; ++i) {
01695 c[i] += rd[i+j*nx];
01696 }
01697 }
01698 cf->update();
01699 EXITFUNC;
01700 return cf;
01701 }
01702 }
01703
01704 EMData *EMData::make_rotational_footprint_cmc( bool unwrap) {
01705 ENTERFUNC;
01706 update_stat();
01707
01708
01709
01710
01711
01712
01713 if ( rot_fp != 0 && unwrap == true) {
01714 return new EMData(*rot_fp);
01715 }
01716
01717 static EMData obj_filt;
01718 EMData* filt = &obj_filt;
01719 filt->set_complex(true);
01720
01721
01722
01723
01724
01725
01726 if (filt->get_xsize() != nx+2-(nx%2) || filt->get_ysize() != ny ||
01727 filt->get_zsize() != nz ) {
01728 filt->set_size(nx+2-(nx%2), ny, nz);
01729 filt->to_one();
01730
01731 filt->process_inplace("filter.highpass.gauss", Dict("cutoff_abs", 1.5f/nx));
01732 }
01733
01734 EMData *ccf = this->calc_mutual_correlation(this, true,filt);
01735 ccf->sub(ccf->get_edge_mean());
01736 EMData *result = ccf->unwrap();
01737 delete ccf; ccf = 0;
01738
01739 EXITFUNC;
01740 if ( unwrap == true)
01741 {
01742
01743
01744
01745
01746
01747
01748
01749
01750 rot_fp = result;
01751 return new EMData(*rot_fp);
01752 }
01753 else return result;
01754 }
01755
01756 EMData *EMData::make_rotational_footprint( bool unwrap) {
01757 ENTERFUNC;
01758 update_stat();
01759
01760
01761
01762
01763
01764
01765 if ( rot_fp != 0 && unwrap == true) {
01766 return new EMData(*rot_fp);
01767 }
01768
01769 EMData* ccf = this->calc_ccf(this,CIRCULANT,true);
01770 ccf->sub(ccf->get_edge_mean());
01771
01772 EMData *result = ccf->unwrap();
01773 delete ccf; ccf = 0;
01774
01775 EXITFUNC;
01776 if ( unwrap == true)
01777 {
01778
01779
01780
01781
01782
01783
01784
01785 rot_fp = result;
01786 return new EMData(*rot_fp);
01787 }
01788 else return result;
01789 }
01790
01791 EMData *EMData::make_rotational_footprint_e1( bool unwrap)
01792 {
01793 ENTERFUNC;
01794
01795 update_stat();
01796
01797
01798
01799
01800
01801
01802 if ( rot_fp != 0 && unwrap == true) {
01803 return new EMData(*rot_fp);
01804 }
01805
01806 static EMData obj_filt;
01807 EMData* filt = &obj_filt;
01808 filt->set_complex(true);
01809
01810
01811
01812
01813
01814
01815 int cs = (((nx * 7 / 4) & 0xfffff8) - nx) / 2;
01816
01817 static EMData big_clip;
01818 int big_x = nx+2*cs;
01819 int big_y = ny+2*cs;
01820 int big_z = 1;
01821 if ( nz != 1 ) {
01822 big_z = nz+2*cs;
01823 }
01824
01825
01826 if ( big_clip.get_xsize() != big_x || big_clip.get_ysize() != big_y || big_clip.get_zsize() != big_z ) {
01827 big_clip.set_size(big_x,big_y,big_z);
01828 }
01829
01830
01831
01832
01833 big_clip.to_value(get_edge_mean());
01834
01835 if (nz != 1) {
01836 big_clip.insert_clip(this,IntPoint(cs,cs,cs));
01837 } else {
01838 big_clip.insert_clip(this,IntPoint(cs,cs,0));
01839 }
01840
01841
01842
01843
01844
01845 if (filt->get_xsize() != big_clip.get_xsize() +2-(big_clip.get_xsize()%2) || filt->get_ysize() != big_clip.get_ysize() ||
01846 filt->get_zsize() != big_clip.get_zsize()) {
01847 filt->set_size(big_clip.get_xsize() + 2-(big_clip.get_xsize()%2), big_clip.get_ysize(), big_clip.get_zsize());
01848 filt->to_one();
01849 filt->process_inplace("filter.highpass.gauss", Dict("cutoff_abs", 1.5f/nx));
01850 #ifdef EMAN2_USING_CUDA
01851 if(big_clip.cudarwdata)
01852 {
01853 filt->copy_to_cuda();
01854 }
01855 #endif
01856 }
01857 #ifdef EMAN2_USING_CUDA
01858 if(big_clip.cudarwdata && !filt->cudarwdata)
01859 {
01860 filt->copy_to_cuda();
01861 }
01862 #endif
01863
01864 EMData *mc = big_clip.calc_mutual_correlation(&big_clip, true,filt);
01865 mc->sub(mc->get_edge_mean());
01866
01867 static EMData sml_clip;
01868 int sml_x = nx * 3 / 2;
01869 int sml_y = ny * 3 / 2;
01870 int sml_z = 1;
01871 if ( nz != 1 ) {
01872 sml_z = nz * 3 / 2;
01873 }
01874
01875 if ( sml_clip.get_xsize() != sml_x || sml_clip.get_ysize() != sml_y || sml_clip.get_zsize() != sml_z ) {
01876 sml_clip.set_size(sml_x,sml_y,sml_z); }
01877 if (nz != 1) {
01878 sml_clip.insert_clip(mc,IntPoint(-cs+nx/4,-cs+ny/4,-cs+nz/4));
01879 } else {
01880 sml_clip.insert_clip(mc,IntPoint(-cs+nx/4,-cs+ny/4,0));
01881 }
01882
01883 delete mc; mc = 0;
01884 EMData * result = NULL;
01885
01886 if (nz == 1) {
01887 if (!unwrap) {
01888 #ifdef EMAN2_USING_CUDA
01889 if(sml_clip.cudarwdata) throw UnexpectedBehaviorException("shap masking is not yet supported by CUDA");
01890 #endif
01891 result = sml_clip.process("mask.sharp", Dict("outer_radius", -1, "value", 0));
01892
01893 }
01894 else {
01895 result = sml_clip.unwrap();
01896 }
01897 }
01898 else {
01899
01900
01901
01902 result = new EMData(sml_clip);
01903 }
01904
01905 #ifdef EMAN2_USING_CUDA
01906 sml_clip.roneedsanupdate();
01907 #endif
01908 EXITFUNC;
01909 if ( unwrap == true)
01910 {
01911
01912
01913
01914 if ( rot_fp != 0 ) throw UnexpectedBehaviorException("The rotational foot print is only expected to be cached if it is not NULL");
01915
01916
01917
01918 rot_fp = result;
01919 return new EMData(*rot_fp);
01920 }
01921 else return result;
01922 }
01923
01924 EMData *EMData::make_footprint(int type)
01925 {
01926
01927 if (type==0) {
01928 EMData *un=make_rotational_footprint_e1();
01929 if (un->get_ysize() <= 6) {
01930 throw UnexpectedBehaviorException("In EMData::make_footprint. The rotational footprint is too small");
01931 }
01932 EMData *tmp=un->get_clip(Region(0,4,un->get_xsize(),un->get_ysize()-6));
01933 EMData *cx=tmp->calc_ccfx(tmp,0,-1,1);
01934 EMData *fp=cx->get_clip(Region(0,0,cx->get_xsize()/2,cx->get_ysize()));
01935 delete un;
01936 delete tmp;
01937 delete cx;
01938 return fp;
01939 }
01940 else if (type==1 || type==2 ||type==5 || type==6) {
01941 int i,j,kx,ky,lx,ly;
01942
01943 EMData *fft=do_fft();
01944
01945
01946 int rmax=(get_xsize()+1)/2;
01947 float *rmap=(float *)malloc(rmax*rmax*sizeof(float));
01948 for (i=0; i<rmax; i++) {
01949 for (j=0; j<rmax; j++) {
01950 #ifdef _WIN32
01951 rmap[i+j*rmax]=_hypotf((float)i,(float)j);
01952 #else
01953 rmap[i+j*rmax]=hypot((float)i,(float)j);
01954 #endif //_WIN32
01955
01956 }
01957 }
01958
01959 EMData *fp=new EMData(rmax*2+2,rmax*2,1);
01960 fp->set_complex(1);
01961 fp->to_zero();
01962
01963
01964
01965
01966 for (kx=-rmax+1; kx<rmax; kx++) {
01967 for (ky=-rmax+1; ky<rmax; ky++) {
01968 for (lx=-rmax+1; lx<rmax; lx++) {
01969 for (ly=-rmax+1; ly<rmax; ly++) {
01970 int ax=kx+lx;
01971 int ay=ky+ly;
01972 if (abs(ax)>=rmax || abs(ay)>=rmax) continue;
01973 int r1=(int)floor(.5+rmap[abs(kx)+rmax*abs(ky)]);
01974 int r2=(int)floor(.5+rmap[abs(lx)+rmax*abs(ly)]);
01975
01976
01977 if (r1+r2>=rmax) continue;
01978
01979 std::complex<float> p=fft->get_complex_at(kx,ky)*fft->get_complex_at(lx,ly)*conj(fft->get_complex_at(ax,ay));
01980 fp->set_value_at(r1*2,r2,p.real()+fp->get_value_at(r1*2,r2));
01981
01982
01983 fp->set_value_at(r1*2+1,r2,fp->get_value_at(r1*2+1,r2)+1);
01984 }
01985 }
01986 }
01987 }
01988
01989
01990 if (type==5 || type==6) {
01991 for (i=0; i<rmax*2; i+=2) {
01992 for (j=0; j<rmax; j++) {
01993 float norm=fp->get_value_at(i+1,j);
01994 #ifdef _WIN32
01995 fp->set_value_at(i,rmax*2-j-1,pow(fp->get_value_at(i,j)/(norm==0.0f?1.0f:norm), 1.0f/3.0f));
01996 fp->set_value_at(i,j,pow(fp->get_value_at(i,j)/(norm==0.0f?1.0f:norm), 1.0f/3.0f));
01997 #else
01998 fp->set_value_at(i,rmax*2-j-1,cbrt(fp->get_value_at(i,j)/(norm==0?1.0:norm)));
01999 fp->set_value_at(i,j,cbrt(fp->get_value_at(i,j)/(norm==0?1.0:norm)));
02000 #endif //_WIN32
02001 fp->set_value_at(i+1,j,0.0);
02002 }
02003 }
02004 }
02005 else {
02006 for (i=0; i<rmax*2; i+=2) {
02007 for (j=0; j<rmax; j++) {
02008 float norm=fp->get_value_at(i+1,j);
02009 fp->set_value_at(i,rmax*2-j-1,fp->get_value_at(i,j)/(norm==0.0f?1.0f:norm));
02010 fp->set_value_at(i,j,fp->get_value_at(i,j)/(norm==0.0f?1.0f:norm));
02011 fp->set_value_at(i+1,j,0.0);
02012 }
02013 }
02014 }
02015
02016 free(rmap);
02017 if (type==2||type==6) {
02018 EMData *f2=fp->do_ift();
02019 if (f2->get_value_at(0,0)<0) f2->mult(-1.0f);
02020 f2->process_inplace("xform.phaseorigin.tocorner");
02021 delete fp;
02022 return f2;
02023 }
02024 return fp;
02025 }
02026 else if (type==3 || type==4) {
02027 int h,i,j,kx,ky,lx,ly;
02028
02029 EMData *fft=do_fft();
02030
02031
02032 int rmax=(get_xsize()+1)/2;
02033 float *rmap=(float *)malloc(rmax*rmax*sizeof(float));
02034 for (i=0; i<rmax; i++) {
02035 for (j=0; j<rmax; j++) {
02036 #ifdef _WIN32
02037 rmap[i+j*rmax]=_hypotf((float)i,(float)j);
02038 #else
02039 rmap[i+j*rmax]=hypot((float)i,(float)j);
02040 #endif //_WIN32
02041
02042 }
02043 }
02044
02045 EMData *fp=new EMData(rmax*2+2,rmax*2,16);
02046
02047 fp->set_complex(1);
02048 fp->to_zero();
02049
02050
02051
02052
02053 for (kx=-rmax+1; kx<rmax; kx++) {
02054 for (ky=-rmax+1; ky<rmax; ky++) {
02055 for (lx=-rmax+1; lx<rmax; lx++) {
02056 for (ly=-rmax+1; ly<rmax; ly++) {
02057 int ax=kx+lx;
02058 int ay=ky+ly;
02059 if (abs(ax)>=rmax || abs(ay)>=rmax) continue;
02060 float rr1=rmap[abs(kx)+rmax*abs(ky)];
02061 float rr2=rmap[abs(lx)+rmax*abs(ly)];
02062 int r1=(int)floor(.5+rr1);
02063 int r2=(int)floor(.5+rr2);
02064
02065
02066 if (r1+r2>=rmax || rr1==0 ||rr2==0) continue;
02067
02068 std::complex<float> p=fft->get_complex_at(kx,ky)*fft->get_complex_at(lx,ly)*conj(fft->get_complex_at(ax,ay));
02069 int dot=(int)floor((kx*lx+ky*ly)/(rr1*rr2)*7.5);
02070 if (dot<0) dot=16+dot;
02071
02072 fp->set_value_at(r1*2,r2,dot,p.real()+fp->get_value_at(r1*2,r2,dot));
02073
02074
02075 fp->set_value_at(r1*2+1,r2,dot,fp->get_value_at(r1*2+1,r2,dot)+1);
02076 }
02077 }
02078 }
02079 }
02080
02081
02082 for (i=0; i<rmax*2; i+=2) {
02083 for (j=0; j<rmax; j++) {
02084 for (h=0; h<16; h++) {
02085 float norm=fp->get_value_at(i+1,j,h);
02086
02087
02088 fp->set_value_at(i,rmax*2-j-1,h,(fp->get_value_at(i,j,h)/(norm==0.0f?1.0f:norm)));
02089 fp->set_value_at(i,j,h,(fp->get_value_at(i,j,h)/(norm==0.0f?1.0f:norm)));
02090
02091
02092 fp->set_value_at(i+1,j,h,0.0);
02093 }
02094 }
02095 }
02096
02097 free(rmap);
02098 if (type==4) {
02099 EMData *f2=fp->do_ift();
02100 if (f2->get_value_at(0,0,0)<0) f2->mult(-1.0f);
02101 f2->process_inplace("xform.phaseorigin.tocorner");
02102 delete fp;
02103 return f2;
02104 }
02105 return fp;
02106 }
02107 throw UnexpectedBehaviorException("There is not implementation for the parameters you specified");
02108 }
02109
02110
02111 EMData *EMData::calc_mutual_correlation(EMData * with, bool tocenter, EMData * filter)
02112 {
02113 ENTERFUNC;
02114
02115 if (with && !EMUtil::is_same_size(this, with)) {
02116 LOGERR("images not same size");
02117 throw ImageFormatException( "images not same size");
02118 }
02119
02120 #ifdef EMAN2_USING_CUDA
02121 if(cudarwdata && with->cudarwdata)
02122 {
02123
02124 EMData* this_fft = do_fft_cuda();
02125
02126 EMData *cf = 0;
02127 if (with && with != this) {
02128 cf = with->do_fft_cuda();
02129 }else{
02130 cf = this_fft->copy();
02131 }
02132
02133 if (filter) {
02134 if (!EMUtil::is_same_size(filter, cf)) {
02135 LOGERR("improperly sized filter");
02136 throw ImageFormatException("improperly sized filter");
02137 }
02138 mult_complex_efficient_cuda(cf->cudarwdata, filter->cudarwdata, cf->get_xsize(), cf->get_ysize(), cf->get_zsize(), 1);
02139 mult_complex_efficient_cuda(this_fft->cudarwdata, filter->cudarwdata, this_fft->get_xsize(), this_fft->get_ysize(), this_fft->get_zsize(), 1);
02140 }
02141
02142 mcf_cuda(this_fft->cudarwdata, cf->cudarwdata, this_fft->get_xsize(), this_fft->get_ysize(), this_fft->get_zsize());
02143
02144 EMData *f2 = cf->do_ift_cuda();
02145
02146 if (tocenter) {
02147 f2->process_inplace("xform.phaseorigin.tocenter");
02148 }
02149
02150 if( cf )
02151 {
02152 delete cf;
02153 cf = 0;
02154 }
02155
02156 if( this_fft )
02157 {
02158 delete this_fft;
02159 this_fft = 0;
02160 }
02161
02162 f2->set_attr("label", "MCF");
02163 f2->set_path("/tmp/eman.mcf");
02164
02165 EXITFUNC;
02166 return f2;
02167 }
02168 #endif
02169
02170 EMData *this_fft = 0;
02171 this_fft = do_fft();
02172
02173 if (!this_fft) {
02174
02175 LOGERR("FFT returns NULL image");
02176 throw NullPointerException("FFT returns NULL image");
02177 }
02178
02179 this_fft->ap2ri();
02180 EMData *cf = 0;
02181
02182 if (with && with != this) {
02183 cf = with->do_fft();
02184 if (!cf) {
02185 LOGERR("FFT returns NULL image");
02186 throw NullPointerException("FFT returns NULL image");
02187 }
02188 cf->ap2ri();
02189 }
02190 else {
02191 cf = this_fft->copy();
02192 }
02193
02194 if (filter) {
02195 if (!EMUtil::is_same_size(filter, cf)) {
02196 LOGERR("improperly sized filter");
02197 throw ImageFormatException("improperly sized filter");
02198 }
02199
02200 cf->mult_complex_efficient(*filter,true);
02201 this_fft->mult(*filter,true);
02202
02203
02204
02205
02206 }
02207
02208 float *rdata1 = this_fft->get_data();
02209 float *rdata2 = cf->get_data();
02210 size_t this_fft_size = (size_t)this_fft->get_xsize() * this_fft->get_ysize() * this_fft->get_zsize();
02211
02212 if (with == this) {
02213 for (size_t i = 0; i < this_fft_size; i += 2) {
02214 rdata2[i] = std::sqrt(rdata1[i] * rdata2[i] + rdata1[i + 1] * rdata2[i + 1]);
02215 rdata2[i + 1] = 0;
02216 }
02217
02218 this_fft->update();
02219 cf->update();
02220 }
02221 else {
02222 for (size_t i = 0; i < this_fft_size; i += 2) {
02223 rdata2[i] = (rdata1[i] * rdata2[i] + rdata1[i + 1] * rdata2[i + 1]);
02224 rdata2[i + 1] = (rdata1[i + 1] * rdata2[i] - rdata1[i] * rdata2[i + 1]);
02225 }
02226
02227
02228 for (size_t i = 0; i < this_fft_size; i += 2) {
02229 float t = Util::square(rdata2[i]) + Util::square(rdata2[i + 1]);
02230 if (t != 0) {
02231 t = pow(t, 0.25f);
02232 rdata2[i] /= t;
02233 rdata2[i + 1] /= t;
02234 }
02235 }
02236 this_fft->update();
02237 cf->update();
02238 }
02239
02240 EMData *f2 = cf->do_ift();
02241
02242 if (tocenter) {
02243 f2->process_inplace("xform.phaseorigin.tocenter");
02244 }
02245
02246 if( cf )
02247 {
02248 delete cf;
02249 cf = 0;
02250 }
02251
02252 if( this_fft )
02253 {
02254 delete this_fft;
02255 this_fft = 0;
02256 }
02257
02258 f2->set_attr("label", "MCF");
02259 f2->set_path("/tmp/eman.mcf");
02260
02261 EXITFUNC;
02262 return f2;
02263 }
02264
02265
02266 vector < float > EMData::calc_hist(int hist_size, float histmin, float histmax,const float& brt, const float& cont)
02267 {
02268 ENTERFUNC;
02269
02270 static size_t prime[] = { 1, 3, 7, 11, 17, 23, 37, 59, 127, 253, 511 };
02271
02272 if (histmin == histmax) {
02273 histmin = get_attr("minimum");
02274 histmax = get_attr("maximum");
02275 }
02276
02277 vector <float> hist(hist_size, 0.0);
02278
02279 int p0 = 0;
02280 int p1 = 0;
02281 size_t size = (size_t)nx * ny * nz;
02282 if (size < 300000) {
02283 p0 = 0;
02284 p1 = 0;
02285 }
02286 else if (size < 2000000) {
02287 p0 = 2;
02288 p1 = 3;
02289 }
02290 else if (size < 8000000) {
02291 p0 = 4;
02292 p1 = 6;
02293 }
02294 else {
02295 p0 = 7;
02296 p1 = 9;
02297 }
02298
02299 if (is_complex() && p0 > 0) {
02300 p0++;
02301 p1++;
02302 }
02303
02304 size_t di = 0;
02305
02306 size_t n = hist.size();
02307
02308 float * data = get_data();
02309 for (int k = p0; k <= p1; ++k) {
02310 if (is_complex()) {
02311 di = prime[k] * 2;
02312 }
02313 else {
02314 di = prime[k];
02315 }
02316
02317
02318 float w = (float)n / (histmax - histmin);
02319
02320 for(size_t i=0; i<=size-di; i += di) {
02321 float val;
02322 if (cont != 1.0f || brt != 0)val = cont*(data[i]+brt);
02323 else val = data[i];
02324 int j = Util::round((val - histmin) * w);
02325 if (j >= 0 && j < (int) n) {
02326 hist[j] += 1;
02327 }
02328 }
02329 }
02330
02331
02332
02333
02334
02335
02336
02337 return hist;
02338
02339 EXITFUNC;
02340 }
02341
02342
02343
02344
02345
02346 vector<float> EMData::calc_az_dist(int n, float a0, float da, float rmin, float rmax)
02347 {
02348 ENTERFUNC;
02349
02350 a0=a0*M_PI/180.0f;
02351 da=da*M_PI/180.0f;
02352
02353 if (get_ndim() > 2) {
02354 throw ImageDimensionException("no 3D image");
02355 }
02356
02357 float *yc = new float[n];
02358
02359 vector<float> vd(n);
02360 for (int i = 0; i < n; i++) {
02361 yc[i] = 0.00001f;
02362 }
02363
02364 float * data = get_data();
02365 if (is_complex()) {
02366 int c = 0;
02367 for (int y = 0; y < ny; y++) {
02368 for (int x = 0; x < nx; x += 2, c += 2) {
02369 int x1 = x / 2;
02370 int y1 = y<ny/2?y:y-ny;
02371 float r = (float)Util::hypot_fast(x1,y1);
02372
02373 if (r >= rmin && r <= rmax) {
02374 float a = 0;
02375
02376 if (y != ny / 2 || x != 0) {
02377 a = (atan2((float)y1, (float)x1) - a0) / da;
02378 }
02379
02380 int i = (int)(floor(a));
02381 a -= i;
02382
02383 if (i == 0) {
02384 vd[0] += data[c] * (1.0f - a);
02385 yc[0] += (1.0f - a);
02386 }
02387 else if (i == n - 1) {
02388 vd[n - 1] += data[c] * a;
02389 yc[n - 1] += a;
02390 }
02391 else if (i > 0 && i < (n - 1)) {
02392 float h = 0;
02393 if (is_ri()) {
02394 #ifdef _WIN32
02395 h = (float)_hypot(data[c], data[c + 1]);
02396 #else
02397 h = (float)hypot(data[c], data[c + 1]);
02398 #endif //_WIN32
02399 }
02400 else {
02401 h = data[c];
02402 }
02403
02404 vd[i] += h * (1.0f - a);
02405 yc[i] += (1.0f - a);
02406 vd[i + 1] += h * a;
02407 yc[i + 1] += a;
02408 }
02409 }
02410 }
02411 }
02412 }
02413 else {
02414 int c = 0;
02415 float half_nx = (nx - 1) / 2.0f;
02416 float half_ny = (ny - 1) / 2.0f;
02417
02418 for (int y = 0; y < ny; y++) {
02419 for (int x = 0; x < nx; x++, c++) {
02420 float y1 = y - half_ny;
02421 float x1 = x - half_nx;
02422 #ifdef _WIN32
02423 float r = (float)_hypot(x1, y1);
02424 #else
02425 float r = (float)hypot(x1, y1);
02426 #endif
02427
02428 if (r >= rmin && r <= rmax) {
02429 float a = 0;
02430 if (x1 != 0 || y1 != 0) {
02431 a = atan2(y1, x1);
02432 if (a < 0) {
02433 a += M_PI * 2;
02434 }
02435 }
02436
02437 a = (a - a0) / da;
02438 int i = static_cast < int >(floor(a));
02439 a -= i;
02440
02441 if (i == 0) {
02442 vd[0] += data[c] * (1.0f - a);
02443 yc[0] += (1.0f - a);
02444 }
02445 else if (i == n - 1) {
02446 vd[n - 1] += data[c] * a;
02447 yc[n - 1] += (a);
02448 }
02449 else if (i > 0 && i < (n - 1)) {
02450 vd[i] += data[c] * (1.0f - a);
02451 yc[i] += (1.0f - a);
02452 vd[i + 1] += data[c] * a;
02453 yc[i + 1] += a;
02454 }
02455 }
02456 }
02457 }
02458 }
02459
02460
02461 for (int i = 0; i < n; i++) {
02462 vd[i] /= yc[i];
02463 }
02464
02465 if( yc )
02466 {
02467 delete[]yc;
02468 yc = 0;
02469 }
02470
02471 return vd;
02472
02473 EXITFUNC;
02474 }
02475
02476
02477 EMData *EMData::unwrap(int r1, int r2, int xs, int dx, int dy, bool do360, bool weight_radial) const
02478 {
02479 ENTERFUNC;
02480
02481 if (get_ndim() != 2) {
02482 throw ImageDimensionException("2D image only");
02483 }
02484
02485 int p = 1;
02486 if (do360) {
02487 p = 2;
02488 }
02489
02490 if (xs < 1) {
02491 xs = (int) Util::fast_floor(p * M_PI * ny / 4);
02492 xs -= xs % 8;
02493 if (xs<=8) xs=16;
02494 }
02495
02496 if (r1 < 0) {
02497 r1 = 4;
02498 }
02499
02500 #ifdef _WIN32
02501 int rr = ny / 2 - 2 - (int) Util::fast_floor(static_cast<float>(_hypot(dx, dy)));
02502 #else
02503 int rr = ny / 2 - 2 - (int) Util::fast_floor(static_cast<float>(hypot(dx, dy)));
02504 #endif //_WIN32
02505 rr-=rr%2;
02506 if (r2 <= r1 || r2 > rr) {
02507 r2 = rr;
02508 }
02509
02510 if ( (r2-r1) < 0 ) throw UnexpectedBehaviorException("The combination of function the arguments and the image dimensions causes unexpected behavior internally. Use a larger image, or a smaller value of r1, or a combination of both");
02511
02512 #ifdef EMAN2_USING_CUDA
02513 if (isrodataongpu()){
02514
02515 EMData* result = new EMData(0,0,xs,(r2-r1),1);
02516 result->rw_alloc();
02517 bindcudaarrayA(true);
02518 emdata_unwrap(result->cudarwdata, r1, r2, xs, p, dx, dy, weight_radial, nx, ny);
02519 unbindcudaarryA();
02520 return result;
02521 }
02522 #endif
02523
02524 EMData *ret = new EMData();
02525 ret->set_size(xs, r2 - r1, 1);
02526 const float *const d = get_const_data();
02527 float *dd = ret->get_data();
02528 float pfac = (float)p/(float)xs;
02529
02530 int nxon2 = nx/2;
02531 int nyon2 = ny/2;
02532 for (int x = 0; x < xs; x++) {
02533 float ang = x * M_PI * pfac;
02534 float si = sin(ang);
02535 float co = cos(ang);
02536
02537 for (int y = 0; y < r2 - r1; y++) {
02538 float ypr1 = (float)y + r1;
02539 float xx = ypr1 * co + nxon2 + dx;
02540 float yy = ypr1 * si + nyon2 + dy;
02541
02542
02543 float t = xx - (int)xx;
02544 float u = yy - (int)yy;
02545
02546 int k = (int) xx + ((int) yy) * nx;
02547 float val = Util::bilinear_interpolate(d[k], d[k + 1], d[k + nx], d[k + nx+1], t,u);
02548 if (weight_radial) val *= ypr1;
02549 dd[x + y * xs] = val;
02550 }
02551
02552 }
02553 ret->update();
02554
02555 EXITFUNC;
02556 return ret;
02557 }
02558
02559
02560
02561 void EMData::apply_radial_func(float x0, float step, vector < float >array, bool interp)
02562 {
02563 ENTERFUNC;
02564
02565 if (!is_complex()) throw ImageFormatException("apply_radial_func requires a complex image");
02566
02567 int n = static_cast < int >(array.size());
02568
02569 if (n*step>2.0) printf("Warning, apply_radial_func takes x0 and step with respect to Nyquist (0.5)\n");
02570
02571
02572
02573 ap2ri();
02574
02575 size_t ndims = get_ndim();
02576 float * data = get_data();
02577 if (ndims == 2) {
02578 int k = 0;
02579 for (int j = 0; j < ny; j++) {
02580 for (int i = 0; i < nx; i += 2, k += 2) {
02581 float r;
02582 #ifdef _WIN32
02583 if (j<ny/2) r = (float)_hypot(i/(float)(nx*2), j/(float)ny);
02584 else r = (float)_hypot(i/(float)(nx*2), (ny-j)/(float)ny);
02585 #else
02586 if (j<ny/2) r = (float)hypot(i/(float)(nx*2), j/(float)ny);
02587 else r = (float)hypot(i/(float)(nx*2), (ny-j)/(float)ny);
02588 #endif //_WIN32
02589 r = (r - x0) / step;
02590
02591 int l = 0;
02592 if (interp) {
02593 l = (int) floor(r);
02594 }
02595 else {
02596 l = (int) floor(r + 1);
02597 }
02598
02599
02600 float f = 0;
02601 if (l >= n - 2) {
02602 f = array[n - 1];
02603 }
02604 else {
02605 if (interp) {
02606 r -= l;
02607 f = (array[l] * (1.0f - r) + array[l + 1] * r);
02608 }
02609 else {
02610 f = array[l];
02611 }
02612 }
02613
02614 data[k] *= f;
02615 data[k + 1] *= f;
02616 }
02617 }
02618 }
02619 else if (ndims == 3) {
02620 int k = 0;
02621 for (int m = 0; m < nz; m++) {
02622 float mnz;
02623 if (m<nz/2) mnz=m*m/(float)(nz*nz);
02624 else { mnz=(nz-m)/(float)nz; mnz*=mnz; }
02625
02626 for (int j = 0; j < ny; j++) {
02627 float jny;
02628 if (j<ny/2) jny= j*j/(float)(ny*ny);
02629 else { jny=(ny-j)/(float)ny; jny*=jny; }
02630
02631 for (int i = 0; i < nx; i += 2, k += 2) {
02632 float r = std::sqrt((i * i / (nx*nx*4.0f)) + jny + mnz);
02633 r = (r - x0) / step;
02634
02635 int l = 0;
02636 if (interp) {
02637 l = (int) floor(r);
02638 }
02639 else {
02640 l = (int) floor(r + 1);
02641 }
02642
02643
02644 float f = 0;
02645 if (l >= n - 2) {
02646 f = array[n - 1];
02647 }
02648 else {
02649 if (interp) {
02650 r -= l;
02651 f = (array[l] * (1.0f - r) + array[l + 1] * r);
02652 }
02653 else {
02654 f = array[l];
02655 }
02656 }
02657
02658 data[k] *= f;
02659 data[k + 1] *= f;
02660 }
02661 }
02662 }
02663
02664 }
02665
02666 update();
02667 EXITFUNC;
02668 }
02669
02670 vector<float> EMData::calc_radial_dist(int n, float x0, float dx, bool inten)
02671 {
02672 ENTERFUNC;
02673
02674 vector<float>ret(n);
02675 vector<float>norm(n);
02676
02677 int x,y,z,i;
02678 int step=is_complex()?2:1;
02679 int isinten=get_attr_default("is_intensity",0);
02680
02681 if (isinten&&!inten) { throw InvalidParameterException("Must set inten for calc_radial_dist with intensity image"); }
02682
02683 for (i=0; i<n; i++) ret[i]=norm[i]=0.0;
02684 float * data = get_data();
02685
02686
02687 if (nz==1) {
02688 for (y=i=0; y<ny; y++) {
02689 for (x=0; x<nx; x+=step,i+=step) {
02690 float r,v;
02691 if (step==2) {
02692 if (x==0 && y>ny/2) continue;
02693 r=(float)(Util::hypot_fast(x/2,y<ny/2?y:ny-y));
02694 if (!inten) {
02695 #ifdef _WIN32
02696 if (is_ri()) v=static_cast<float>(_hypot(data[i],data[i+1]));
02697 #else
02698 if (is_ri()) v=static_cast<float>(hypot(data[i],data[i+1]));
02699 #endif
02700 else v=data[i];
02701 } else {
02702 if (isinten) v=data[i];
02703 else if (is_ri()) v=data[i]*data[i]+data[i+1]*data[i+1];
02704 else v=data[i]*data[i];
02705 }
02706 }
02707 else {
02708 r=(float)(Util::hypot_fast(x-nx/2,y-ny/2));
02709 if (inten) v=data[i]*data[i];
02710 else v=data[i];
02711 }
02712 r=(r-x0)/dx;
02713 int f=int(r);
02714 r-=float(f);
02715
02716 if (f>=0 && f<n) {
02717 ret[f]+=v*(1.0f-r);
02718 norm[f]+=(1.0f-r);
02719 if (f<n-1) {
02720 ret[f+1]+=v*r;
02721 norm[f+1]+=r;
02722 }
02723 }
02724 }
02725 }
02726 }
02727 else {
02728 size_t i;
02729 for (z=i=0; z<nz; ++z) {
02730 for (y=0; y<ny; ++y) {
02731 for (x=0; x<nx; x+=step,i+=step) {
02732 float r,v;
02733 if (step==2) {
02734 if (x==0 && z<nz/2) continue;
02735 if (x==0 && z==nz/2 && y<ny/2) continue;
02736 r=Util::hypot3(x/2,y<ny/2?y:ny-y,z<nz/2?z:nz-z);
02737 if (!inten) {
02738 #ifdef _WIN32
02739 if (is_ri()) v=static_cast<float>(_hypot(data[i],data[i+1]));
02740 #else
02741 if (is_ri()) v=static_cast<float>(hypot(data[i],data[i+1]));
02742 #endif //_WIN32
02743 else v=data[i];
02744 } else {
02745 if (isinten) v=data[i];
02746 else if (is_ri()) v=data[i]*data[i]+data[i+1]*data[i+1];
02747 else v=data[i]*data[i];
02748 }
02749 }
02750 else {
02751 r=Util::hypot3(x-nx/2,y-ny/2,z-nz/2);
02752 if (inten) v=data[i]*data[i];
02753 else v=data[i];
02754 }
02755 r=(r-x0)/dx;
02756 int f=int(r);
02757 r-=float(f);
02758 if (f>=0 && f<n) {
02759 ret[f]+=v*(1.0f-r);
02760 norm[f]+=(1.0f-r);
02761 if (f<n-1) {
02762 ret[f+1]+=v*r;
02763 norm[f+1]+=r;
02764 }
02765 }
02766 }
02767 }
02768 }
02769 }
02770
02771 for (i=0; i<n; i++) ret[i]/=norm[i]?norm[i]:1.0f;
02772
02773 EXITFUNC;
02774
02775 return ret;
02776 }
02777
02778 vector<float> EMData::calc_radial_dist(int n, float x0, float dx, int nwedge, bool inten)
02779 {
02780 ENTERFUNC;
02781
02782 if (nz > 1) {
02783 LOGERR("2D images only.");
02784 throw ImageDimensionException("2D images only");
02785 }
02786
02787 vector<float>ret(n*nwedge);
02788 vector<float>norm(n*nwedge);
02789
02790 int x,y,i;
02791 int step=is_complex()?2:1;
02792 float astep=static_cast<float>(M_PI*2.0/nwedge);
02793 float* data = get_data();
02794 for (i=0; i<n*nwedge; i++) ret[i]=norm[i]=0.0;
02795
02796
02797 for (y=i=0; y<ny; y++) {
02798 for (x=0; x<nx; x+=step,i+=step) {
02799 float r,v,a;
02800 if (is_complex()) {
02801 #ifdef _WIN32
02802 r=static_cast<float>(_hypot(x/2.0,y<ny/2?y:ny-y));
02803 #else
02804 r=static_cast<float>(hypot(x/2.0,y<ny/2?y:ny-y));
02805 #endif
02806 a=atan2(float(y<ny/2?y:ny-y),x/2.0f);
02807 if (!inten) {
02808 #ifdef _WIN32
02809 if (is_ri()) v=static_cast<float>(_hypot(data[i],data[i+1]));
02810 #else
02811 if (is_ri()) v=static_cast<float>(hypot(data[i],data[i+1]));
02812 #endif //_WIN32
02813 else v=data[i];
02814 } else {
02815 if (is_ri()) v=data[i]*data[i]+data[i+1]*data[i+1];
02816 else v=data[i]*data[i];
02817 }
02818 }
02819 else {
02820 #ifdef _WIN32
02821 r=static_cast<float>(_hypot(x-nx/2,y-ny/2));
02822 #else
02823 r=static_cast<float>(hypot(x-nx/2,y-ny/2));
02824 #endif //_WIN32
02825 a=atan2(float(y-ny/2),float(x-nx/2));
02826 if (inten) v=data[i]*data[i];
02827 else v=data[i];
02828 }
02829 int bin=n*int((a+M_PI)/astep);
02830 if (bin>=nwedge) bin=nwedge-1;
02831 r=(r-x0)/dx;
02832 int f=int(r);
02833 r-=float(f);
02834 if (f>=0 && f<n) {
02835 ret[f+bin]+=v*(1.0f-r);
02836 norm[f+bin]+=(1.0f-r);
02837 if (f<n-1) {
02838 ret[f+1+bin]+=v*r;
02839 norm[f+1+bin]+=r;
02840 }
02841 }
02842 }
02843 }
02844
02845 for (i=0; i<n*nwedge; i++) ret[i]/=norm[i]?norm[i]:1.0f;
02846 EXITFUNC;
02847
02848 return ret;
02849 }
02850
02851 void EMData::cconj() {
02852 ENTERFUNC;
02853 if (!is_complex() || !is_ri())
02854 throw ImageFormatException("EMData::conj requires a complex, ri image");
02855 int nxreal = nx -2 + int(is_fftodd());
02856 int nxhalf = nxreal/2;
02857 for (int iz = 0; iz < nz; iz++)
02858 for (int iy = 0; iy < ny; iy++)
02859 for (int ix = 0; ix <= nxhalf; ix++)
02860 cmplx(ix,iy,iz) = conj(cmplx(ix,iy,iz));
02861 EXITFUNC;
02862 }
02863
02864
02865
02866
02867
02868
02869
02870
02871
02872
02873
02874
02875
02876 void EMData::update_stat() const
02877 {
02878 ENTERFUNC;
02879
02880 if (!(flags & EMDATA_NEEDUPD))
02881 {
02882 EXITFUNC;
02883 return;
02884 }
02885
02886 float* data = get_data();
02887 float max = -FLT_MAX;
02888 float min = -max;
02889
02890 double sum = 0;
02891 double square_sum = 0;
02892
02893 int step = 1;
02894 if (is_complex() && !is_ri()) {
02895 step = 2;
02896 }
02897
02898 int n_nonzero = 0;
02899
02900 size_t size = (size_t)nx*ny*nz;
02901 for (size_t i = 0; i < size; i += step) {
02902 float v = data[i];
02903 #ifdef _WIN32
02904 max = _cpp_max(max,v);
02905 min = _cpp_min(min,v);
02906 #else
02907 max=std::max<float>(max,v);
02908 min=std::min<float>(min,v);
02909 #endif //_WIN32
02910 sum += v;
02911 square_sum += v * (double)(v);
02912 if (v != 0) n_nonzero++;
02913 }
02914
02915 size_t n = size / step;
02916 double mean = sum / n;
02917
02918 #ifdef _WIN32
02919 float sigma = (float)std::sqrt( _cpp_max(0.0,(square_sum - sum*sum / n)/(n-1)));
02920 n_nonzero = _cpp_max(1,n_nonzero);
02921 double sigma_nonzero = std::sqrt( _cpp_max(0,(square_sum - sum*sum/n_nonzero)/(n_nonzero-1)));
02922 #else
02923 float sigma = (float)std::sqrt(std::max<double>(0.0,(square_sum - sum*sum / n)/(n-1)));
02924 n_nonzero = std::max<int>(1,n_nonzero);
02925 double sigma_nonzero = std::sqrt(std::max<double>(0,(square_sum - sum*sum/n_nonzero)/(n_nonzero-1)));
02926 #endif //_WIN32
02927 double mean_nonzero = sum / n_nonzero;
02928
02929 attr_dict["minimum"] = min;
02930 attr_dict["maximum"] = max;
02931 attr_dict["mean"] = (float)(mean);
02932 attr_dict["sigma"] = (float)(sigma);
02933 attr_dict["square_sum"] = (float)(square_sum);
02934 attr_dict["mean_nonzero"] = (float)(mean_nonzero);
02935 attr_dict["sigma_nonzero"] = (float)(sigma_nonzero);
02936 attr_dict["is_complex"] = (int) is_complex();
02937 attr_dict["is_complex_ri"] = (int) is_ri();
02938
02939 flags &= ~EMDATA_NEEDUPD;
02940
02941 if (rot_fp != 0)
02942 {
02943 delete rot_fp; rot_fp = 0;
02944 }
02945
02946 EXITFUNC;
02947
02948 }
02949
02950 bool EMData::operator==(const EMData& that) const {
02951 if (that.get_xsize() != nx || that.get_ysize() != ny || that.get_zsize() != nz ) return false;
02952
02953 const float* d1 = that.get_const_data();
02954 float* d2 = get_data();
02955
02956 for(size_t i =0; i < get_size(); ++i,++d1,++d2) {
02957 if ((*d1) != (*d2)) return false;
02958 }
02959 return true;
02960
02961 }
02962
02963 EMData * EMAN::operator+(const EMData & em, float n)
02964 {
02965 EMData * r = em.copy();
02966 r->add(n);
02967 return r;
02968 }
02969
02970 EMData * EMAN::operator-(const EMData & em, float n)
02971 {
02972 EMData* r = em.copy();
02973 r->sub(n);
02974 return r;
02975 }
02976
02977 EMData * EMAN::operator*(const EMData & em, float n)
02978 {
02979 EMData* r = em.copy();
02980 r ->mult(n);
02981 return r;
02982 }
02983
02984 EMData * EMAN::operator/(const EMData & em, float n)
02985 {
02986 EMData * r = em.copy();
02987 r->div(n);
02988 return r;
02989 }
02990
02991
02992 EMData * EMAN::operator+(float n, const EMData & em)
02993 {
02994 EMData * r = em.copy();
02995 r->add(n);
02996 return r;
02997 }
02998
02999 EMData * EMAN::operator-(float n, const EMData & em)
03000 {
03001 EMData * r = em.copy();
03002 r->mult(-1.0f);
03003 r->add(n);
03004 return r;
03005 }
03006
03007 EMData * EMAN::operator*(float n, const EMData & em)
03008 {
03009 EMData * r = em.copy();
03010 r->mult(n);
03011 return r;
03012 }
03013
03014 EMData * EMAN::operator/(float n, const EMData & em)
03015 {
03016 EMData * r = em.copy();
03017 r->to_one();
03018 r->mult(n);
03019 r->div(em);
03020
03021 return r;
03022 }
03023
03024 EMData * EMAN::rsub(const EMData & em, float n)
03025 {
03026 return EMAN::operator-(n, em);
03027 }
03028
03029 EMData * EMAN::rdiv(const EMData & em, float n)
03030 {
03031 return EMAN::operator/(n, em);
03032 }
03033
03034 EMData * EMAN::operator+(const EMData & a, const EMData & b)
03035 {
03036 EMData * r = a.copy();
03037 r->add(b);
03038 return r;
03039 }
03040
03041 EMData * EMAN::operator-(const EMData & a, const EMData & b)
03042 {
03043 EMData * r = a.copy();
03044 r->sub(b);
03045 return r;
03046 }
03047
03048 EMData * EMAN::operator*(const EMData & a, const EMData & b)
03049 {
03050 EMData * r = a.copy();
03051 r->mult(b);
03052 return r;
03053 }
03054
03055 EMData * EMAN::operator/(const EMData & a, const EMData & b)
03056 {
03057 EMData * r = a.copy();
03058 r->div(b);
03059 return r;
03060 }
03061
03062 void EMData::set_xyz_origin(float origin_x, float origin_y, float origin_z)
03063 {
03064 attr_dict["origin_x"] = origin_x;
03065 attr_dict["origin_y"] = origin_y;
03066 attr_dict["origin_z"] = origin_z;
03067 }
03068
03069 #if 0
03070 void EMData::calc_rcf(EMData * with, vector < float >&sum_array)
03071 {
03072 ENTERFUNC;
03073
03074 int array_size = sum_array.size();
03075 float da = 2 * M_PI / array_size;
03076 float *dat = new float[array_size + 2];
03077 float *dat2 = new float[array_size + 2];
03078 int nx2 = nx * 9 / 20;
03079
03080 float lim = 0;
03081 if (fabs(translation[0]) < fabs(translation[1])) {
03082 lim = fabs(translation[1]);
03083 }
03084 else {
03085 lim = fabs(translation[0]);
03086 }
03087
03088 nx2 -= static_cast < int >(floor(lim));
03089
03090 for (int i = 0; i < array_size; i++) {
03091 sum_array[i] = 0;
03092 }
03093
03094 float sigma = attr_dict["sigma"];
03095 float with_sigma = with->get_attr_dict().get("sigma");
03096
03097 vector<float> vdata, vdata2;
03098 for (int i = 8; i < nx2; i += 6) {
03099 vdata = calc_az_dist(array_size, 0, da, i, i + 6);
03100 vdata2 = with->calc_az_dist(array_size, 0, da, i, i + 6);
03101 Assert(vdata.size() <= array_size + 2);
03102 Assert(cdata2.size() <= array_size + 2);
03103 std::copy(vdata.begin(), vdata.end(), dat);
03104 std::copy(vdata2.begin(), vdata2.end(), dat2);
03105
03106 EMfft::real_to_complex_1d(dat, dat, array_size);
03107 EMfft::real_to_complex_1d(dat2, dat2, array_size);
03108
03109 for (int j = 0; j < array_size + 2; j += 2) {
03110 float max = dat[j] * dat2[j] + dat[j + 1] * dat2[j + 1];
03111 float max2 = dat[j + 1] * dat2[j] - dat2[j + 1] * dat[j];
03112 dat[j] = max;
03113 dat[j + 1] = max2;
03114 }
03115
03116 EMfft::complex_to_real_1d(dat, dat, array_size);
03117 float norm = array_size * array_size * (4.0f * sigma) * (4.0f * with_sigma);
03118
03119 for (int j = 0; j < array_size; j++) {
03120 sum_array[j] += dat[j] * (float) i / norm;
03121 }
03122 }
03123
03124 if( dat )
03125 {
03126 delete[]dat;
03127 dat = 0;
03128 }
03129
03130 if( dat2 )
03131 {
03132 delete[]dat2;
03133 dat2 = 0;
03134 }
03135 EXITFUNC;
03136 }
03137
03138 #endif
03139
03140 void EMData::add_incoherent(EMData * obj)
03141 {
03142 ENTERFUNC;
03143
03144 if (!obj) {
03145 LOGERR("NULL image");
03146 throw NullPointerException("NULL image");
03147 }
03148
03149 if (!obj->is_complex() || !is_complex()) {
03150 throw ImageFormatException("complex images only");
03151 }
03152
03153 if (!EMUtil::is_same_size(this, obj)) {
03154 throw ImageFormatException("images not same size");
03155 }
03156
03157 ri2ap();
03158 obj->ri2ap();
03159
03160 float *dest = get_data();
03161 float *src = obj->get_data();
03162 size_t size = (size_t)nx * ny * nz;
03163 for (size_t j = 0; j < size; j += 2) {
03164 #ifdef _WIN32
03165 dest[j] = (float) _hypot(src[j], dest[j]);
03166 #else
03167 dest[j] = (float) hypot(src[j], dest[j]);
03168 #endif //_WIN32
03169 dest[j + 1] = 0;
03170 }
03171
03172 obj->update();
03173 update();
03174 EXITFUNC;
03175 }
03176
03177
03178 float EMData::calc_dist(EMData * second_img, int y_index) const
03179 {
03180 ENTERFUNC;
03181
03182 if (get_ndim() != 1) {
03183 throw ImageDimensionException("'this' image is 1D only");
03184 }
03185
03186 if (second_img->get_xsize() != nx || ny != 1) {
03187 throw ImageFormatException("image xsize not same");
03188 }
03189
03190 if (y_index > second_img->get_ysize() || y_index < 0) {
03191 return -1;
03192 }
03193
03194 float ret = 0;
03195 float *d1 = get_data();
03196 float *d2 = second_img->get_data() + second_img->get_xsize() * y_index;
03197
03198 for (int i = 0; i < nx; i++) {
03199 ret += Util::square(d1[i] - d2[i]);
03200 }
03201 EXITFUNC;
03202 return std::sqrt(ret);
03203 }
03204
03205
03206 EMData * EMData::calc_fast_sigma_image( EMData* mask)
03207 {
03208 ENTERFUNC;
03209
03210 bool maskflag = false;
03211 if (mask == 0) {
03212 mask = new EMData(nx,ny,nz);
03213 mask->process_inplace("testimage.circlesphere");
03214 maskflag = true;
03215 }
03216
03217 if (get_ndim() != mask->get_ndim() ) throw ImageDimensionException("The dimensions do not match");
03218
03219 int mnx = mask->get_xsize(); int mny = mask->get_ysize(); int mnz = mask->get_zsize();
03220
03221 if ( mnx > nx || mny > ny || mnz > nz)
03222 throw ImageDimensionException("Can not calculate variance map using an image that is larger than this image");
03223
03224 size_t P = 0;
03225 for(size_t i = 0; i < mask->get_size(); ++i){
03226 if (mask->get_value_at(i) != 0){
03227 ++P;
03228 }
03229 }
03230 float normfac = 1.0f/(float)P;
03231
03232
03233
03234 int nxc = nx+mnx; int nyc = ny+mny; int nzc = nz+mnz;
03235
03236 Region r;
03237 if (ny == 1) r = Region((mnx-nxc)/2,nxc);
03238 else if (nz == 1) r = Region((mnx-nxc)/2, (mny-nyc)/2,nxc,nyc);
03239 else r = Region((mnx-nxc)/2, (mny-nyc)/2,(mnz-nzc)/2,nxc,nyc,nzc);
03240 mask->clip_inplace(r,0.0);
03241
03242
03243
03244
03245
03246
03247 Region r2;
03248 if (ny == 1) r2 = Region((nx-nxc)/2,nxc);
03249 else if (nz == 1) r2 = Region((nx-nxc)/2, (ny-nyc)/2,nxc,nyc);
03250 else r2 = Region((nx-nxc)/2, (ny-nyc)/2,(nz-nzc)/2,nxc,nyc,nzc);
03251 EMData* squared = get_clip(r2,get_edge_mean());
03252
03253 EMData* tmp = squared->copy();
03254 Dict pow;
03255 pow["pow"] = 2.0f;
03256 squared->process_inplace("math.pow",pow);
03257 EMData* s = mask->convolute(squared);
03258 squared->mult(normfac);
03259
03260 EMData* m = mask->convolute(tmp);
03261 m->mult(normfac);
03262 m->process_inplace("math.pow",pow);
03263 delete tmp; tmp = 0;
03264 s->sub(*m);
03265
03266 s->process_inplace("math.sqrt");
03267
03268
03269
03270
03271
03272
03273 if (maskflag) {
03274 delete mask;
03275 mask = 0;
03276 } else {
03277 Region r;
03278 if (ny == 1) r = Region((nxc-mnx)/2,mnx);
03279 else if (nz == 1) r = Region((nxc-mnx)/2, (nyc-mny)/2,mnx,mny);
03280 else r = Region((nxc-mnx)/2, (nyc-mny)/2,(nzc-mnz)/2,mnx,mny,mnz);
03281 mask->clip_inplace(r);
03282 }
03283
03284 delete squared;
03285 delete m;
03286
03287 s->process_inplace("xform.phaseorigin.tocenter");
03288 Region r3;
03289 if (ny == 1) r3 = Region((nxc-nx)/2,nx);
03290 else if (nz == 1) r3 = Region((nxc-nx)/2, (nyc-ny)/2,nx,ny);
03291 else r3 = Region((nxc-nx)/2, (nyc-ny)/2,(nzc-nz)/2,nx,ny,nz);
03292 s->clip_inplace(r3);
03293 EXITFUNC;
03294 return s;
03295 }
03296
03297
03298
03299 EMData *EMData::calc_flcf(EMData * with)
03300 {
03301 ENTERFUNC;
03302 EMData *this_copy=this;
03303 this_copy=copy();
03304
03305 int mnx = with->get_xsize(); int mny = with->get_ysize(); int mnz = with->get_zsize();
03306 int nxc = nx+mnx; int nyc = ny+mny; int nzc = nz+mnz;
03307
03308
03309 EMData* ones = new EMData(mnx,mny,mnz);
03310 ones->process_inplace("testimage.circlesphere");
03311
03312
03313 EMData* with_resized = with->copy();
03314 with_resized->process_inplace("normalize");
03315 with_resized->mult(*ones);
03316
03317 EMData* s = calc_fast_sigma_image(ones);
03318
03319 Region r1;
03320 if (ny == 1) r1 = Region((mnx-nxc)/2,nxc);
03321 else if (nz == 1) r1 = Region((mnx-nxc)/2, (mny-nyc)/2,nxc,nyc);
03322 else r1 = Region((mnx-nxc)/2, (mny-nyc)/2,(mnz-nzc)/2,nxc,nyc,nzc);
03323 with_resized->clip_inplace(r1,0.0);
03324
03325 Region r2;
03326 if (ny == 1) r2 = Region((nx-nxc)/2,nxc);
03327 else if (nz == 1) r2 = Region((nx-nxc)/2, (ny-nyc)/2,nxc,nyc);
03328 else r2 = Region((nx-nxc)/2, (ny-nyc)/2,(nz-nzc)/2,nxc,nyc,nzc);
03329 this_copy->clip_inplace(r2,0.0);
03330
03331 EMData* corr = this_copy->calc_ccf(with_resized);
03332
03333 corr->process_inplace("xform.phaseorigin.tocenter");
03334 Region r3;
03335 if (ny == 1) r3 = Region((nxc-nx)/2,nx);
03336 else if (nz == 1) r3 = Region((nxc-nx)/2, (nyc-ny)/2,nx,ny);
03337 else r3 = Region((nxc-nx)/2, (nyc-ny)/2,(nzc-nz)/2,nx,ny,nz);
03338 corr->clip_inplace(r3);
03339
03340 corr->div(*s);
03341
03342 delete with_resized; delete ones; delete this_copy; delete s;
03343 EXITFUNC;
03344 return corr;
03345 }
03346
03347 EMData *EMData::convolute(EMData * with)
03348 {
03349 ENTERFUNC;
03350
03351 EMData *f1 = do_fft();
03352 if (!f1) {
03353 LOGERR("FFT returns NULL image");
03354 throw NullPointerException("FFT returns NULL image");
03355 }
03356
03357 f1->ap2ri();
03358
03359 EMData *cf = 0;
03360 if (with) {
03361 cf = with->do_fft();
03362 if (!cf) {
03363 LOGERR("FFT returns NULL image");
03364 throw NullPointerException("FFT returns NULL image");
03365 }
03366 cf->ap2ri();
03367 }
03368 else {
03369 cf = f1->copy();
03370 }
03371
03372 if (with && !EMUtil::is_same_size(f1, cf)) {
03373 LOGERR("images not same size");
03374 throw ImageFormatException("images not same size");
03375 }
03376
03377 float *rdata1 = f1->get_data();
03378 float *rdata2 = cf->get_data();
03379 size_t cf_size = (size_t)cf->get_xsize() * cf->get_ysize() * cf->get_zsize();
03380
03381 float re,im;
03382
03383 for (size_t i = 0; i < cf_size; i += 2) {
03384 re = rdata1[i] * rdata2[i] - rdata1[i + 1] * rdata2[i + 1];
03385 im = rdata1[i + 1] * rdata2[i] + rdata1[i] * rdata2[i + 1];
03386 rdata2[i]=re;
03387 rdata2[i+1]=im;
03388 }
03389 cf->update();
03390 EMData *f2 = cf->do_ift();
03391
03392 if( cf )
03393 {
03394 delete cf;
03395 cf = 0;
03396 }
03397
03398 if( f1 )
03399 {
03400 delete f1;
03401 f1=0;
03402 }
03403
03404 EXITFUNC;
03405 return f2;
03406 }
03407
03408
03409 void EMData::common_lines(EMData * image1, EMData * image2,
03410 int mode, int steps, bool horizontal)
03411 {
03412 ENTERFUNC;
03413
03414 if (!image1 || !image2) {
03415 throw NullPointerException("NULL image");
03416 }
03417
03418 if (mode < 0 || mode > 2) {
03419 throw OutofRangeException(0, 2, mode, "invalid mode");
03420 }
03421
03422 if (!image1->is_complex()) {
03423 image1 = image1->do_fft();
03424 }
03425 if (!image2->is_complex()) {
03426 image2 = image2->do_fft();
03427 }
03428
03429 image1->ap2ri();
03430 image2->ap2ri();
03431
03432 if (!EMUtil::is_same_size(image1, image2)) {
03433 throw ImageFormatException("images not same sizes");
03434 }
03435
03436 int image2_nx = image2->get_xsize();
03437 int image2_ny = image2->get_ysize();
03438
03439 int rmax = image2_ny / 4 - 1;
03440 int array_size = steps * rmax * 2;
03441 float *im1 = new float[array_size];
03442 float *im2 = new float[array_size];
03443 for (int i = 0; i < array_size; i++) {
03444 im1[i] = 0;
03445 im2[i] = 0;
03446 }
03447
03448 set_size(steps * 2, steps * 2, 1);
03449
03450 float *image1_data = image1->get_data();
03451 float *image2_data = image2->get_data();
03452
03453 float da = M_PI / steps;
03454 float a = -M_PI / 2.0f + da / 2.0f;
03455 int jmax = 0;
03456
03457 for (int i = 0; i < steps * 2; i += 2, a += da) {
03458 float s1 = 0;
03459 float s2 = 0;
03460 int i2 = i * rmax;
03461 int j = 0;
03462
03463 for (float r = 3.0f; r < rmax - 3.0f; j += 2, r += 1.0f) {
03464 float x = r * cos(a);
03465 float y = r * sin(a);
03466
03467 if (x < 0) {
03468 x = -x;
03469 y = -y;
03470 LOGERR("CCL ERROR %d, %f !\n", i, -x);
03471 }
03472
03473 int k = (int) (floor(x) * 2 + floor(y + image2_ny / 2) * image2_nx);
03474 int l = i2 + j;
03475 float x2 = x - floor(x);
03476 float y2 = y - floor(y);
03477
03478 im1[l] = Util::bilinear_interpolate(image1_data[k],
03479 image1_data[k + 2],
03480 image1_data[k + image2_nx],
03481 image1_data[k + 2 + image2_nx], x2, y2);
03482
03483 im2[l] = Util::bilinear_interpolate(image2_data[k],
03484 image2_data[k + 2],
03485 image2_data[k + image2_nx],
03486 image2_data[k + 2 + image2_nx], x2, y2);
03487
03488 k++;
03489
03490 im1[l + 1] = Util::bilinear_interpolate(image1_data[k],
03491 image1_data[k + 2],
03492 image1_data[k + image2_nx],
03493 image1_data[k + 2 + image2_nx], x2, y2);
03494
03495 im2[l + 1] = Util::bilinear_interpolate(image2_data[k],
03496 image2_data[k + 2],
03497 image2_data[k + image2_nx],
03498 image2_data[k + 2 + image2_nx], x2, y2);
03499
03500 s1 += Util::square_sum(im1[l], im1[l + 1]);
03501 s2 += Util::square_sum(im2[l], im2[l + 1]);
03502 }
03503
03504 jmax = j - 1;
03505 float sqrt_s1 = std::sqrt(s1);
03506 float sqrt_s2 = std::sqrt(s2);
03507
03508 int l = 0;
03509 for (float r = 1; r < rmax; r += 1.0f) {
03510 int i3 = i2 + l;
03511 im1[i3] /= sqrt_s1;
03512 im1[i3 + 1] /= sqrt_s1;
03513 im2[i3] /= sqrt_s2;
03514 im2[i3 + 1] /= sqrt_s2;
03515 l += 2;
03516 }
03517 }
03518 float * data = get_data();
03519
03520 switch (mode) {
03521 case 0:
03522 for (int m1 = 0; m1 < 2; m1++) {
03523 for (int m2 = 0; m2 < 2; m2++) {
03524
03525 if (m1 == 0 && m2 == 0) {
03526 for (int i = 0; i < steps; i++) {
03527 int i2 = i * rmax * 2;
03528 for (int j = 0; j < steps; j++) {
03529 int l = i + j * steps * 2;
03530 int j2 = j * rmax * 2;
03531 data[l] = 0;
03532 for (int k = 0; k < jmax; k++) {
03533 data[l] += im1[i2 + k] * im2[j2 + k];
03534 }
03535 }
03536 }
03537 }
03538 else {
03539 int steps2 = steps * m2 + steps * steps * 2 * m1;
03540
03541 for (int i = 0; i < steps; i++) {
03542 int i2 = i * rmax * 2;
03543 for (int j = 0; j < steps; j++) {
03544 int j2 = j * rmax * 2;
03545 int l = i + j * steps * 2 + steps2;
03546 data[l] = 0;
03547
03548 for (int k = 0; k < jmax; k += 2) {
03549 i2 += k;
03550 j2 += k;
03551 data[l] += im1[i2] * im2[j2];
03552 data[l] += -im1[i2 + 1] * im2[j2 + 1];
03553 }
03554 }
03555 }
03556 }
03557 }
03558 }
03559
03560 break;
03561 case 1:
03562 for (int m1 = 0; m1 < 2; m1++) {
03563 for (int m2 = 0; m2 < 2; m2++) {
03564 int steps2 = steps * m2 + steps * steps * 2 * m1;
03565 int p1_sign = 1;
03566 if (m1 != m2) {
03567 p1_sign = -1;
03568 }
03569
03570 for (int i = 0; i < steps; i++) {
03571 int i2 = i * rmax * 2;
03572
03573 for (int j = 0; j < steps; j++) {
03574 int j2 = j * rmax * 2;
03575
03576 int l = i + j * steps * 2 + steps2;
03577 data[l] = 0;
03578 float a = 0;
03579
03580 for (int k = 0; k < jmax; k += 2) {
03581 i2 += k;
03582 j2 += k;
03583
03584 #ifdef _WIN32
03585 float a1 = (float) _hypot(im1[i2], im1[i2 + 1]);
03586 #else
03587 float a1 = (float) hypot(im1[i2], im1[i2 + 1]);
03588 #endif //_WIN32
03589 float p1 = atan2(im1[i2 + 1], im1[i2]);
03590 float p2 = atan2(im2[j2 + 1], im2[j2]);
03591
03592 data[l] += Util::angle_sub_2pi(p1_sign * p1, p2) * a1;
03593 a += a1;
03594 }
03595
03596 data[l] /= (float)(a * M_PI / 180.0f);
03597 }
03598 }
03599 }
03600 }
03601
03602 break;
03603 case 2:
03604 for (int m1 = 0; m1 < 2; m1++) {
03605 for (int m2 = 0; m2 < 2; m2++) {
03606 int steps2 = steps * m2 + steps * steps * 2 * m1;
03607
03608 for (int i = 0; i < steps; i++) {
03609 int i2 = i * rmax * 2;
03610
03611 for (int j = 0; j < steps; j++) {
03612 int j2 = j * rmax * 2;
03613 int l = i + j * steps * 2 + steps2;
03614 data[l] = 0;
03615
03616 for (int k = 0; k < jmax; k += 2) {
03617 i2 += k;
03618 j2 += k;
03619 #ifdef _WIN32
03620 data[l] += (float) (_hypot(im1[i2], im1[i2 + 1]) * _hypot(im2[j2], im2[j2 + 1]));
03621 #else
03622 data[l] += (float) (hypot(im1[i2], im1[i2 + 1]) * hypot(im2[j2], im2[j2 + 1]));
03623 #endif //_WIN32
03624 }
03625 }
03626 }
03627 }
03628 }
03629
03630 break;
03631 default:
03632 break;
03633 }
03634
03635 if (horizontal) {
03636 float *tmp_array = new float[ny];
03637 for (int i = 1; i < nx; i++) {
03638 for (int j = 0; j < ny; j++) {
03639 tmp_array[j] = get_value_at(i, j);
03640 }
03641 for (int j = 0; j < ny; j++) {
03642 set_value_at(i, j, 0, tmp_array[(j + i) % ny]);
03643 }
03644 }
03645 if( tmp_array )
03646 {
03647 delete[]tmp_array;
03648 tmp_array = 0;
03649 }
03650 }
03651
03652 if( im1 )
03653 {
03654 delete[]im1;
03655 im1 = 0;
03656 }
03657
03658 if( im2 )
03659 {
03660 delete im2;
03661 im2 = 0;
03662 }
03663
03664
03665 image1->update();
03666 image2->update();
03667 if( image1 )
03668 {
03669 delete image1;
03670 image1 = 0;
03671 }
03672 if( image2 )
03673 {
03674 delete image2;
03675 image2 = 0;
03676 }
03677 update();
03678 EXITFUNC;
03679 }
03680
03681
03682
03683 void EMData::common_lines_real(EMData * image1, EMData * image2,
03684 int steps, bool horiz)
03685 {
03686 ENTERFUNC;
03687
03688 if (!image1 || !image2) {
03689 throw NullPointerException("NULL image");
03690 }
03691
03692 if (!EMUtil::is_same_size(image1, image2)) {
03693 throw ImageFormatException("images not same size");
03694 }
03695
03696 int steps2 = steps * 2;
03697 int image_ny = image1->get_ysize();
03698 EMData *image1_copy = image1->copy();
03699 EMData *image2_copy = image2->copy();
03700
03701 float *im1 = new float[steps2 * image_ny];
03702 float *im2 = new float[steps2 * image_ny];
03703
03704 EMData *images[] = { image1_copy, image2_copy };
03705 float *ims[] = { im1, im2 };
03706
03707 for (int m = 0; m < 2; m++) {
03708 float *im = ims[m];
03709 float a = M_PI / steps2;
03710 Transform t(Dict("type","2d","alpha",-a));
03711 for (int i = 0; i < steps2; i++) {
03712 images[i]->transform(t);
03713 float *data = images[i]->get_data();
03714
03715 for (int j = 0; j < image_ny; j++) {
03716 float sum = 0;
03717 for (int k = 0; k < image_ny; k++) {
03718 sum += data[j * image_ny + k];
03719 }
03720 im[i * image_ny + j] = sum;
03721 }
03722
03723 float sum1 = 0;
03724 float sum2 = 0;
03725 for (int j = 0; j < image_ny; j++) {
03726 int l = i * image_ny + j;
03727 sum1 += im[l];
03728 sum2 += im[l] * im[l];
03729 }
03730
03731 float mean = sum1 / image_ny;
03732 float sigma = std::sqrt(sum2 / image_ny - sum1 * sum1);
03733
03734 for (int j = 0; j < image_ny; j++) {
03735 int l = i * image_ny + j;
03736 im[l] = (im[l] - mean) / sigma;
03737 }
03738
03739 images[i]->update();
03740 a += M_PI / steps;
03741 }
03742 }
03743
03744 set_size(steps2, steps2, 1);
03745 float *data1 = get_data();
03746
03747 if (horiz) {
03748 for (int i = 0; i < steps2; i++) {
03749 for (int j = 0, l = i; j < steps2; j++, l++) {
03750 if (l == steps2) {
03751 l = 0;
03752 }
03753
03754 float sum = 0;
03755 for (int k = 0; k < image_ny; k++) {
03756 sum += im1[i * image_ny + k] * im2[l * image_ny + k];
03757 }
03758 data1[i + j * steps2] = sum;
03759 }
03760 }
03761 }
03762 else {
03763 for (int i = 0; i < steps2; i++) {
03764 for (int j = 0; j < steps2; j++) {
03765 float sum = 0;
03766 for (int k = 0; k < image_ny; k++) {
03767 sum += im1[i * image_ny + k] * im2[j * image_ny + k];
03768 }
03769 data1[i + j * steps2] = sum;
03770 }
03771 }
03772 }
03773
03774 update();
03775
03776 if( image1_copy )
03777 {
03778 delete image1_copy;
03779 image1_copy = 0;
03780 }
03781
03782 if( image2_copy )
03783 {
03784 delete image2_copy;
03785 image2_copy = 0;
03786 }
03787
03788 if( im1 )
03789 {
03790 delete[]im1;
03791 im1 = 0;
03792 }
03793
03794 if( im2 )
03795 {
03796 delete[]im2;
03797 im2 = 0;
03798 }
03799 EXITFUNC;
03800 }
03801
03802
03803 void EMData::cut_slice(const EMData *const map, const Transform& transform, bool interpolate)
03804 {
03805 ENTERFUNC;
03806
03807 if (!map) throw NullPointerException("NULL image");
03808
03809 if ( get_ndim() != 2 ) throw ImageDimensionException("Can not call cut slice on an image that is not 2D");
03810 if ( map->get_ndim() != 3 ) throw ImageDimensionException("Can not cut slice from an image that is not 3D");
03811
03812 if ( is_complex() ) throw ImageFormatException("Can not call cut slice on an image that is complex");
03813 if ( map->is_complex() ) throw ImageFormatException("Can not cut slice from a complex image");
03814
03815
03816 float *sdata = map->get_data();
03817 float *ddata = get_data();
03818
03819 int map_nx = map->get_xsize();
03820 int map_ny = map->get_ysize();
03821 int map_nz = map->get_zsize();
03822 int map_nxy = map_nx * map_ny;
03823
03824 int ymax = ny/2;
03825 if ( ny % 2 == 1 ) ymax += 1;
03826 int xmax = nx/2;
03827 if ( nx % 2 == 1 ) xmax += 1;
03828 for (int y = -ny/2; y < ymax; y++) {
03829 for (int x = -nx/2; x < xmax; x++) {
03830 Vec3f coord(x,y,0);
03831 Vec3f soln = transform*coord;
03832
03833
03834
03835
03836
03837
03838
03839
03840
03841
03842 float xx = soln[0]+map_nx/2;
03843 float yy = soln[1]+map_ny/2;
03844 float zz = soln[2]+map_nz/2;
03845
03846 int l = (x+nx/2) + (y+ny/2) * nx;
03847
03848 float t = xx - floor(xx);
03849 float u = yy - floor(yy);
03850 float v = zz - floor(zz);
03851
03852 if (xx < 0 || yy < 0 || zz < 0 ) {
03853 ddata[l] = 0;
03854 continue;
03855 }
03856 if (interpolate) {
03857 if ( xx > map_nx - 1 || yy > map_ny - 1 || zz > map_nz - 1) {
03858 ddata[l] = 0;
03859 continue;
03860 }
03861 int k = (int) (Util::fast_floor(xx) + Util::fast_floor(yy) * map_nx + Util::fast_floor(zz) * map_nxy);
03862
03863
03864 if (xx < (map_nx - 1) && yy < (map_ny - 1) && zz < (map_nz - 1)) {
03865 ddata[l] = Util::trilinear_interpolate(sdata[k],
03866 sdata[k + 1], sdata[k + map_nx],sdata[k + map_nx + 1],
03867 sdata[k + map_nxy], sdata[k + map_nxy + 1], sdata[k + map_nx + map_nxy],
03868 sdata[k + map_nx + map_nxy + 1],t, u, v);
03869 }
03870 else if ( xx == (map_nx - 1) && yy == (map_ny - 1) && zz == (map_nz - 1) ) {
03871 ddata[l] += sdata[k];
03872 }
03873 else if ( xx == (map_nx - 1) && yy == (map_ny - 1) ) {
03874 ddata[l] += Util::linear_interpolate(sdata[k], sdata[k + map_nxy],v);
03875 }
03876 else if ( xx == (map_nx - 1) && zz == (map_nz - 1) ) {
03877 ddata[l] += Util::linear_interpolate(sdata[k], sdata[k + map_nx],u);
03878 }
03879 else if ( yy == (map_ny - 1) && zz == (map_nz - 1) ) {
03880 ddata[l] += Util::linear_interpolate(sdata[k], sdata[k + 1],t);
03881 }
03882 else if ( xx == (map_nx - 1) ) {
03883 ddata[l] += Util::bilinear_interpolate(sdata[k], sdata[k + map_nx], sdata[k + map_nxy], sdata[k + map_nxy + map_nx],u,v);
03884 }
03885 else if ( yy == (map_ny - 1) ) {
03886 ddata[l] += Util::bilinear_interpolate(sdata[k], sdata[k + 1], sdata[k + map_nxy], sdata[k + map_nxy + 1],t,v);
03887 }
03888 else if ( zz == (map_nz - 1) ) {
03889 ddata[l] += Util::bilinear_interpolate(sdata[k], sdata[k + 1], sdata[k + map_nx], sdata[k + map_nx + 1],t,u);
03890 }
03891
03892
03893
03894
03895
03896
03897
03898
03899
03900
03901
03902
03903 }
03904 else {
03905 if ( xx > map_nx - 1 || yy > map_ny - 1 || zz > map_nz - 1) {
03906 ddata[l] = 0;
03907 continue;
03908 }
03909 size_t k = Util::round(xx) + Util::round(yy) * map_nx + Util::round(zz) * (size_t)map_nxy;
03910 ddata[l] = sdata[k];
03911 }
03912
03913 }
03914 }
03915
03916 update();
03917
03918 EXITFUNC;
03919 }
03920
03921 EMData *EMData::unwrap_largerR(int r1,int r2,int xs, float rmax_f) {
03922 float *d,*dd;
03923 int do360=2;
03924 int rmax = (int)(rmax_f+0.5f);
03925 unsigned long i;
03926 unsigned int nvox=get_xsize()*get_ysize();
03927 float maxmap=0.0f, minmap=0.0f;
03928 float temp=0.0f, diff_den=0.0f, norm=0.0f;
03929 float cut_off_va =0.0f;
03930
03931 d=get_data();
03932 maxmap=-1000000.0f;
03933 minmap=1000000.0f;
03934 for (i=0;i<nvox;i++){
03935 if(d[i]>maxmap) maxmap=d[i];
03936 if(d[i]<minmap) minmap=d[i];
03937 }
03938 diff_den = maxmap-minmap;
03939 for(i=0;i<nvox;i++) {
03940 temp = (d[i]-minmap)/diff_den;
03941 if(cut_off_va != 0.0) {
03942 if(temp < cut_off_va)
03943 d[i] = 0.0f;
03944 else
03945 d[i] = temp-cut_off_va;
03946 }
03947 else d[i] = temp;
03948 }
03949
03950 for(i=0;i<nvox;i++) {
03951 temp=d[i];
03952 norm += temp*temp;
03953 }
03954 for(i=0;i<nvox;i++) d[i] /= norm;
03955
03956 if (xs<1) {
03957 xs = (int) floor(do360*M_PI*get_ysize()/4);
03958 xs=Util::calc_best_fft_size(xs);
03959 }
03960 if (r1<0) r1=0;
03961 float maxext=ceil(0.6f*std::sqrt((float)(get_xsize()*get_xsize()+get_ysize()*get_ysize())));
03962
03963 if (r2<r1) r2=(int)maxext;
03964 EMData *ret = new EMData;
03965
03966 ret->set_size(xs,r2+1,1);
03967
03968 dd=ret->get_data();
03969
03970 for (int i=0; i<xs; i++) {
03971 float si=sin(i*M_PI*2/xs);
03972 float co=cos(i*M_PI*2/xs);
03973 for (int r=0; r<=maxext; r++) {
03974 float x=(r+r1)*co+get_xsize()/2;
03975 float y=(r+r1)*si+get_ysize()/2;
03976 if(x<0.0 || x>=get_xsize()-1.0 || y<0.0 || y>=get_ysize()-1.0 || r>rmax){
03977 for(;r<=r2;r++)
03978 dd[i+r*xs]=0.0;
03979 break;
03980 }
03981 int x1=(int)floor(x);
03982 int y1=(int)floor(y);
03983 float t=x-x1;
03984 float u=y-y1;
03985 float f11= d[x1+y1*get_xsize()];
03986 float f21= d[(x1+1)+y1*get_xsize()];
03987 float f12= d[x1+(y1+1)*get_xsize()];
03988 float f22= d[(x1+1)+(y1+1)*get_xsize()];
03989 dd[i+r*xs] = (1-t)*(1-u)*f11+t*(1-u)*f21+t*u*f22+(1-t)*u*f12;
03990 }
03991 }
03992 update();
03993 ret->update();
03994 return ret;
03995 }
03996
03997
03998 EMData *EMData::oneDfftPolar(int size, float rmax, float MAXR){
03999 float *pcs=get_data();
04000 EMData *imagepcsfft = new EMData;
04001 imagepcsfft->set_size((size+2), (int)MAXR+1, 1);
04002 float *d=imagepcsfft->get_data();
04003
04004 EMData *data_in=new EMData;
04005 data_in->set_size(size,1,1);
04006 float *in=data_in->get_data();
04007
04008 for(int row=0; row<=(int)MAXR; ++row){
04009 if(row<=(int)rmax) {
04010 for(int i=0; i<size;++i) in[i] = pcs[i+row*size];
04011 data_in->set_complex(false);
04012 data_in->do_fft_inplace();
04013 for(int j=0;j<size+2;j++) d[j+row*(size+2)]=in[j];
04014 }
04015 else for(int j=0;j<size+2;j++) d[j+row*(size+2)]=0.0;
04016 }
04017 imagepcsfft->update();
04018 delete data_in;
04019 return imagepcsfft;
04020 }
04021
04022
04023
04024
04025
04026
04027
04028
04029
04030
04031
04032
04033
04034
04035
04036
04037
04038
04039
04040
04041
04042
04043
04044
04045
04046
04047
04048
04049
04050
04051
04052
04053
04054
04055 void EMData::uncut_slice(EMData * const map, const Transform& transform) const
04056 {
04057 ENTERFUNC;
04058
04059 if (!map) throw NullPointerException("NULL image");
04060
04061 if ( get_ndim() != 2 ) throw ImageDimensionException("Can not call cut slice on an image that is not 2D");
04062 if ( map->get_ndim() != 3 ) throw ImageDimensionException("Can not cut slice from an image that is not 3D");
04063
04064 if ( is_complex() ) throw ImageFormatException("Can not call cut slice on an image that is complex");
04065 if ( map->is_complex() ) throw ImageFormatException("Can not cut slice from a complex image");
04066
04067
04068
04069
04070
04071
04072 float *ddata = map->get_data();
04073 float *sdata = get_data();
04074
04075 int map_nx = map->get_xsize();
04076 int map_ny = map->get_ysize();
04077 int map_nz = map->get_zsize();
04078 int map_nxy = map_nx * map_ny;
04079 float map_nz_round_limit = (float) map_nz-0.5f;
04080 float map_ny_round_limit = (float) map_ny-0.5f;
04081 float map_nx_round_limit = (float) map_nx-0.5f;
04082
04083
04084
04085
04086 int ymax = ny/2;
04087 if ( ny % 2 == 1 ) ymax += 1;
04088 int xmax = nx/2;
04089 if ( nx % 2 == 1 ) xmax += 1;
04090 for (int y = -ny/2; y < ymax; y++) {
04091 for (int x = -nx/2; x < xmax; x++) {
04092 Vec3f coord(x,y,0);
04093 Vec3f soln = transform*coord;
04094
04095
04096
04097
04098
04099
04100
04101
04102 float xx = soln[0]+map_nx/2;
04103 float yy = soln[1]+map_ny/2;
04104 float zz = soln[2]+map_nz/2;
04105
04106
04107 if (xx < -0.5 || yy < -0.5 || zz < -0.5 || xx >= map_nx_round_limit || yy >= map_ny_round_limit || zz >= map_nz_round_limit) continue;
04108
04109 size_t k = Util::round(xx) + Util::round(yy) * map_nx + Util::round(zz) * (size_t)map_nxy;
04110 int l = (x+nx/2) + (y+ny/2) * nx;
04111 ddata[k] = sdata[l];
04112 }
04113 }
04114
04115 map->update();
04116 EXITFUNC;
04117 }
04118
04119
04120 void EMData::save_byteorder_to_dict(ImageIO * imageio)
04121 {
04122 string image_endian = "ImageEndian";
04123 string host_endian = "HostEndian";
04124
04125 if (imageio->is_image_big_endian()) {
04126 attr_dict[image_endian] = "big";
04127 }
04128 else {
04129 attr_dict[image_endian] = "little";
04130 }
04131
04132 if (ByteOrder::is_host_big_endian()) {
04133 attr_dict[host_endian] = "big";
04134 }
04135 else {
04136 attr_dict[host_endian] = "little";
04137 }
04138 }
04139