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 "ctf.h"
00038 #include "portable_fileio.h"
00039 #include "imageio.h"
00040
00041 #include <cstring>
00042 #include <sstream>
00043 using std::stringstream;
00044
00045 #include <iomanip>
00046 using std::setprecision;
00047
00048
00049 using namespace EMAN;
00050
00051 EMData* EMData::get_fft_amplitude2D()
00052 {
00053 ENTERFUNC;
00054
00055
00056 if (!is_complex()) {
00057 LOGERR("complex image expected. Input image is real image.");
00058 throw ImageFormatException("complex image expected. Input image is a real image.");
00059 }
00060 if (nz>1) {
00061 LOGERR("2D image expected. Input image is 3D");
00062 throw ImageFormatException("2D odd square complex image"
00063 " expected Input image is 3D.");
00064 }
00065
00066 int nx2 = nx/2;
00067
00068 EMData *dat = copy_head();
00069
00070 dat->set_size(nx2, ny, nz);
00071 dat->to_zero();
00072
00073 float temp=0;
00074
00075 for (int j = 0; j < ny; j++) {
00076 for (int i = 0; i < nx2; i++) {
00077 temp = (*this)(2*i,j)*(*this)(2*i,j);
00078 temp += (*this)(2*i+1,j)*(*this)(2*i+1,j);
00079 (*dat)(i,j) = std::sqrt(temp);
00080 }
00081 }
00082
00083 dat->update();
00084 dat->set_complex(false);
00085 dat->set_ri(false);
00086
00087 EXITFUNC;
00088 return dat;
00089 }
00090
00091
00092 EMData* EMData::get_fft_amplitude()
00093 {
00094 ENTERFUNC;
00095
00096 if (!is_complex()) {
00097 LOGERR("complex image expected. Input image is real image.");
00098 throw ImageFormatException("complex image expected. Input image is a real image.");
00099 }
00100
00101 ri2ap();
00102
00103 int nx2 = nx - 2;
00104 EMData *dat = copy_head();
00105 dat->set_size(nx2, ny, nz);
00106 dat->to_zero();
00107
00108 float *d = dat->get_data();
00109 float *data = get_data();
00110 int ndim = get_ndim();
00111
00112 size_t idx1, idx2, idx3;
00113 if (ndim == 3) {
00114 for (int k = 1; k < nz; ++k) {
00115 for (int j = 1; j < ny; ++j) {
00116 for (int i = 0; i < nx2/2; ++i) {
00117 idx1 = k*nx2*ny+j*nx2+nx2/2+i;
00118 idx2 = k*nx*ny+j*nx+2*i;
00119 idx3 = (nz-k)*nx2*ny+(ny-j)*nx2+nx2/2-i;
00120 d[idx1] = data[idx2];
00121 d[idx3] = data[idx2];
00122 }
00123 }
00124 }
00125 }
00126 else if (ndim == 2) {
00127 for (int j = 1; j < ny; ++j) {
00128 for (int i = 0; i < nx2/2; ++i) {
00129 d[j*nx2+nx2/2+i] = data[j*nx+2*i];
00130 d[(ny-j)*nx2+nx2/2-i] = data[j*nx+2*i];
00131 }
00132 }
00133 }
00134
00135 dat->update();
00136 dat->set_complex(false);
00137 if(dat->get_ysize()==1 && dat->get_zsize()==1) {
00138 dat->set_complex_x(false);
00139 }
00140 dat->set_ri(false);
00141
00142 EXITFUNC;
00143 return dat;
00144 }
00145
00146
00147 EMData* EMData::get_fft_phase()
00148 {
00149 ENTERFUNC;
00150
00151 if (!is_complex()) {
00152 LOGERR("complex image expected. Input image is real image.");
00153 throw ImageFormatException("complex image expected. Input image is a real image.");
00154 }
00155
00156 ri2ap();
00157
00158 int nx2 = nx - 2;
00159 EMData *dat = copy_head();
00160 dat->set_size(nx2, ny, nz);
00161 dat->to_zero();
00162
00163 float *d = dat->get_data();
00164 float * data = get_data();
00165
00166 int ndim = get_ndim();
00167 size_t idx1, idx2, idx3;
00168 if (ndim == 3) {
00169 for (int k = 1; k < nz; ++k) {
00170 for (int j = 1; j < ny; ++j) {
00171 for (int i = 0; i < nx2/2; ++i) {
00172 idx1 = k*nx2*ny+j*nx2+nx2/2+i;
00173 idx2 = k*nx*ny+j*nx+2*i+1;
00174 idx3 = (nz-k)*nx2*ny+(ny-j)*nx2+nx2/2-i;
00175 d[idx1] = data[idx2];
00176 d[idx3] = -data[idx2];
00177 }
00178 }
00179 }
00180 }
00181 else if (ndim == 2) {
00182 for (int j = 1; j < ny; ++j) {
00183 for (int i = 0; i < nx2/2; ++i) {
00184 d[j*nx2+nx2/2+i] = data[j*nx+2*i+1];
00185 d[(ny-j)*nx2+nx2/2-i] = -data[j*nx+2*i+1];
00186 }
00187 }
00188 }
00189
00190 dat->update();
00191 dat->set_complex(false);
00192 if(dat->get_ysize()==1 && dat->get_zsize()==1) {
00193 dat->set_complex_x(false);
00194 }
00195 dat->set_ri(false);
00196
00197 EXITFUNC;
00198 return dat;
00199 }
00200 #ifdef EMAN2_USING_CUDA
00201 #include <cuda_runtime_api.h>
00202
00203 float* EMData::get_data() const
00204 {
00205
00206 size_t num_bytes = nx*ny*nz*sizeof(float);
00207 if ( num_bytes > 0 && gpu_rw_is_current() && (EMDATA_CPU_NEEDS_UPDATE & flags)) {
00208 cout << get_cuda_data() << endl;
00209 cout << rdata << endl;
00210 cudaError_t error = cudaMemcpy(rdata,get_cuda_data(),num_bytes,cudaMemcpyDeviceToHost);
00211 if (error != cudaSuccess ) throw UnexpectedBehaviorException("The device to host cudaMemcpy failed : " + string(cudaGetErrorString(error)));
00212 } else if ( gpu_ro_is_current() && (EMDATA_CPU_NEEDS_UPDATE & flags)) {
00213 cout << "Copy ro to cpu" << endl;
00214 copy_gpu_ro_to_cpu();
00215 }
00216 flags &= ~EMDATA_CPU_NEEDS_UPDATE;
00217
00218 return rdata;
00219
00220 }
00221 #endif
00222
00223
00224 #include <sys/stat.h>
00225
00226 void EMData::write_data(string fsp,size_t loc,const Region* area,const int file_nx, const int file_ny, const int file_nz) {
00227
00228 if (area) {
00229 struct stat fileinfo;
00230 if ( stat(fsp.c_str(),&fileinfo) != 0 ) throw UnexpectedBehaviorException("To write an image using a region the file must already exist and be the correct dimensions");
00231 }
00232
00233
00234 FILE *f = 0;
00235 f=fopen(fsp.c_str(), "rb+");
00236 if (!f) f=fopen(fsp.c_str(), "wb");
00237 if (!f) throw FileAccessException(fsp);
00238 portable_fseek(f,loc,SEEK_SET);
00239 if (!area) {
00240 if (fwrite(get_data(),nx*ny,nz*4,f)!=(size_t)(nz*4)) throw FileAccessException(fsp);
00241 } else {
00242 int fnx = nx;
00243 if (file_nx != 0) fnx = file_nx;
00244 int fny = ny;
00245 if (file_ny != 0) fny = file_ny;
00246 int fnz = nz;
00247 if (file_nz != 0) fnz = file_nz;
00248
00249 EMUtil::process_region_io(get_data(), f, ImageIO::READ_WRITE,
00250 0, 4,fnx,fny,fnz,area);
00251 }
00252 fclose(f);
00253 }
00254
00255 void EMData::read_data(string fsp,size_t loc,const Region* area, const int file_nx, const int file_ny, const int file_nz) {
00256 FILE *f = 0;
00257 f=fopen(fsp.c_str(), "rb");
00258 if (!f) throw FileAccessException(fsp);
00259 int fnx = nx;
00260 if (file_nx != 0) fnx = file_nx;
00261 int fny = ny;
00262 if (file_ny != 0) fny = file_ny;
00263 int fnz = nz;
00264 if (file_nz != 0) fnz = file_nz;
00265
00266 portable_fseek(f,loc,SEEK_SET);
00267 EMUtil::process_region_io(get_data(), f, ImageIO::READ_ONLY,
00268 0, 4,fnx,fny,fnz,area);
00269
00270
00271 fclose(f);
00272 }
00273
00274 float EMData::calc_center_density()
00275 {
00276 ENTERFUNC;
00277
00278 float center = get_attr("mean");
00279 float sigma = get_attr("sigma");
00280 float ds = sigma / 2;
00281 size_t size = nx * ny * nz;
00282 float *d = get_data();
00283 float sigma1 = sigma / 20;
00284 float sigma2 = sigma / 1000;
00285
00286 while (ds > sigma1) {
00287 double sum = 0;
00288 int norm = 0;
00289
00290 for (size_t i = 0; i < size; i++) {
00291 if (fabs(d[i] - center) < ds) {
00292 sum += d[i];
00293 norm++;
00294 }
00295 }
00296 if (!norm) {
00297 break;
00298 }
00299 float mean = (float)(sum / norm);
00300 if (fabs(mean - center) < sigma2) {
00301 ds *= 0.5f;
00302 }
00303 center = mean;
00304 }
00305 EXITFUNC;
00306
00307 return center;
00308 }
00309
00310
00311 float EMData::calc_sigma_diff()
00312 {
00313 ENTERFUNC;
00314
00315 float *d = get_data();
00316 float mean = get_attr("mean");
00317 float sigma = get_attr("sigma");
00318
00319 double sum_up = 0;
00320 double sum_down = 0;
00321 int nup = 0;
00322 int ndown = 0;
00323
00324 size_t size = nx * ny * nz;
00325
00326 for (size_t i = 0; i < size; i++) {
00327 if (d[i] > mean) {
00328 sum_up += Util::square(d[i] - mean);
00329 nup++;
00330 }
00331 else {
00332 sum_down += Util::square(mean - d[i]);
00333 ndown++;
00334 }
00335 }
00336
00337 float sigup = std::sqrt((float)sum_up / nup);
00338 float sigdown = std::sqrt((float)sum_down / ndown);
00339 float sig_diff = fabs(sigup - sigdown) / sigma;
00340
00341
00342 EXITFUNC;
00343 return sig_diff;
00344
00345 }
00346
00347
00348 IntPoint EMData::calc_min_location() const
00349 {
00350 ENTERFUNC;
00351
00352 int di = 1;
00353 if (is_complex() && !is_ri()) {
00354 di = 2;
00355 }
00356
00357 float min = FLT_MAX;
00358 int min_x = 0;
00359 int min_y = 0;
00360 int min_z = 0;
00361 int nxy = nx * ny;
00362 float * data = get_data();
00363
00364 for (int j = 0; j < nz; ++j) {
00365 size_t cur_z = j * nxy;
00366
00367 for (int k = 0; k < ny; ++k) {
00368 size_t cur_y = k * nx + cur_z;
00369
00370 for (int l = 0; l < nx; l += di) {
00371 float t = data[l + cur_y];
00372 if (t < min) {
00373 min_x = l;
00374 min_y = k;
00375 min_z = j;
00376 min = t;
00377 }
00378 }
00379 }
00380 }
00381
00382 return IntPoint(min_x, min_y, min_z);
00383 }
00384
00385
00386 IntPoint EMData::calc_max_location() const
00387 {
00388 ENTERFUNC;
00389
00390 int di = 1;
00391 if (is_complex() && !is_ri()) {
00392 di = 2;
00393 }
00394
00395 float max = -FLT_MAX;
00396 int max_x = 0;
00397 int max_y = 0;
00398 int max_z = 0;
00399 int nxy = nx * ny;
00400 float * data = get_data();
00401
00402 for (int j = 0; j < nz; ++j) {
00403 size_t cur_z = j * nxy;
00404
00405 for (int k = 0; k < ny; ++k) {
00406 size_t cur_y = k * nx + cur_z;
00407
00408 for (int l = 0; l < nx; l += di) {
00409 float t = data[l + cur_y];
00410 if (t > max) {
00411 max_x = l;
00412 max_y = k;
00413 max_z = j;
00414 max = t;
00415 }
00416 }
00417 }
00418 }
00419
00420 EXITFUNC;
00421 return IntPoint(max_x, max_y, max_z);
00422 }
00423
00424
00425 IntPoint EMData::calc_max_location_wrap(const int maxdx, const int maxdy, const int maxdz)
00426 {
00427 int maxshiftx = maxdx, maxshifty = maxdy, maxshiftz = maxdz;
00428 if (maxdx == -1) maxshiftx = get_xsize()/4;
00429 if (maxdy == -1) maxshifty = get_ysize()/4;
00430 if (maxdz == -1) maxshiftz = get_zsize()/4;
00431
00432 float max_value = -FLT_MAX;
00433
00434 IntPoint peak(0,0,0);
00435 for (int k = -maxshiftz; k <= maxshiftz; k++) {
00436 for (int j = -maxshifty; j <= maxshifty; j++) {
00437 for (int i = -maxshiftx; i <= maxshiftx; i++) {
00438
00439 float value = get_value_at_wrap(i,j,k);
00440
00441 if (value > max_value) {
00442 max_value = value;
00443 peak[0] = i;
00444 peak[1] = j;
00445 peak[2] = k;
00446 }
00447 }
00448 }
00449 }
00450
00451 return peak;
00452 }
00453
00454 FloatPoint EMData::calc_center_of_mass(float threshold)
00455 {
00456 float *data = get_data();
00457
00458
00459
00460 float m = 0.0;
00461
00462 FloatPoint com(0,0,0);
00463 for (int i = 0; i < nx; ++i) {
00464 for (int j = 0; j < ny; ++j) {
00465 int j2 = nx * j;
00466 for (int k = 0; k < nz; ++k) {
00467 size_t l = i + j2 + k * nxy;
00468 if (data[l] >= threshold) {
00469 com[0] += i * data[l];
00470 com[1] += j * data[l];
00471 com[2] += k * data[l];
00472 m += data[l];
00473 }
00474 }
00475 }
00476 }
00477
00478 com[0] /= m;
00479 com[1] /= m;
00480 com[2] /= m;
00481
00482 return com;
00483 }
00484
00485
00486 int EMData::calc_min_index() const
00487 {
00488 IntPoint min_location = calc_min_location();
00489 int i = min_location[0] + min_location[1] * nx + min_location[2] * nx * ny;
00490 return i;
00491 }
00492
00493
00494 int EMData::calc_max_index() const
00495 {
00496 IntPoint max_location = calc_max_location();
00497 int i = max_location[0] + max_location[1] * nx + max_location[2] * nx * ny;
00498 return i;
00499 }
00500
00501
00502 vector<Pixel> EMData::calc_highest_locations(float threshold) const
00503 {
00504 ENTERFUNC;
00505
00506 vector<Pixel> result;
00507
00508 int di = 1;
00509 if (is_complex() && !is_ri()) {
00510 di = 2;
00511 }
00512
00513 int nxy = nx * ny;
00514 float * data = get_data();
00515
00516 for (int j = 0; j < nz; ++j) {
00517 size_t cur_z = j * nxy;
00518
00519 for (int k = 0; k < ny; ++k) {
00520 size_t cur_y = k * nx + cur_z;
00521
00522 for (int l = 0; l < nx; l += di) {
00523 float v =data[l + cur_y];
00524 if (v > threshold) {
00525 result.push_back(Pixel(l, k, j, v));
00526 }
00527 }
00528 }
00529 }
00530
00531 std::sort(result.begin(), result.end());
00532
00533 EXITFUNC;
00534 return result;
00535 }
00536
00537 vector<Pixel> EMData::calc_n_highest_locations(int n)
00538 {
00539 ENTERFUNC;
00540
00541 vector<Pixel> result;
00542
00543 int di = 1;
00544 if (is_complex() && !is_ri()) {
00545 di = 2;
00546 }
00547
00548
00549 float * data = get_data();
00550 for ( int i=0; i<n; i++) result.push_back(Pixel(0,0,0,data[0]));
00551
00552 int nxy = nx * ny;
00553
00554 for (int j = 0; j < nz; ++j) {
00555 size_t cur_z = j * nxy;
00556
00557 for (int k = 0; k < ny; ++k) {
00558 size_t cur_y = k * nx + cur_z;
00559
00560 for (int l = 0; l < nx; l += di) {
00561 float v =data[l + cur_y];
00562 if (v<result[n-1].value) continue;
00563 for (vector<Pixel>::iterator i=result.begin(); i<result.end(); i++) {
00564 if (v>(*i).value) { result.insert(i,Pixel(l, k, j, v)); result.pop_back(); break; }
00565 }
00566 }
00567 }
00568 }
00569
00570 EXITFUNC;
00571 return result;
00572 }
00573
00574 vector<Pixel> EMData::find_pixels_with_value(float val)
00575 {
00576 ENTERFUNC;
00577
00578 if ( is_complex() ) throw ImageFormatException("Error - find_pixels_with_value real only");
00579
00580 vector<Pixel> result;
00581
00582 for (int k = 0; k < nz; k++) {
00583 for (int j = 0; j < ny; j++) {
00584 for (int i = 0; i < nx; i++) {
00585 if (get_value_at(i,j,k)==val) result.push_back(Pixel(i,j,k,val));
00586 }
00587 }
00588 }
00589
00590 EXITFUNC;
00591 return result;
00592 }
00593
00594 float EMData::get_edge_mean() const
00595 {
00596 ENTERFUNC;
00597
00598 int di = 0;
00599 double edge_sum = 0;
00600 float edge_mean = 0;
00601 size_t nxy = nx * ny;
00602 float * data = get_data();
00603 if (nz == 1) {
00604 for (int i = 0, j = (ny - 1) * nx; i < nx; ++i, ++j) {
00605 edge_sum += data[i] + data[j];
00606 }
00607 for (size_t i = 0, j = nx - 1; i < nxy; i += nx, j += nx) {
00608 edge_sum += data[i] + data[j];
00609 }
00610 edge_mean = (float)edge_sum / (nx * 2 + ny * 2);
00611 }
00612 else {
00613 if (nx == ny && nx == nz * 2 - 1) {
00614 for (size_t j = (nxy * (nz - 1)); j < nxy * nz; ++j, ++di) {
00615 edge_sum += data[j];
00616 }
00617 }
00618 else {
00619 for (size_t i = 0, j = (nxy * (nz - 1)); i < nxy; ++i, ++j, ++di) {
00620 edge_sum += data[i] + data[j];
00621 }
00622 }
00623
00624 int nxy2 = nx * (ny - 1);
00625 for (int k = 1; k < nz - 1; ++k) {
00626 size_t k2 = k * nxy;
00627 size_t k3 = k2 + nxy2;
00628 for (int i = 0; i < nx; ++i, ++di) {
00629 edge_sum += data[i + k2] + data[i + k3];
00630 }
00631 }
00632 for (int k = 1; k < nz - 1; ++k) {
00633 size_t k2 = k * nxy;
00634 size_t k3 = nx - 1 + k2;
00635 for (int i = 1; i < ny - 1; ++i, ++di) {
00636 edge_sum += data[i * nx + k2] + data[i * nx + k3];
00637 }
00638 }
00639
00640 edge_mean = (float)edge_sum / (di * 2);
00641 }
00642 EXITFUNC;
00643
00644 return edge_mean;
00645 }
00646
00647
00648 float EMData::get_circle_mean()
00649 {
00650 ENTERFUNC;
00651
00652 static bool busy = false;
00653 static EMData *mask = 0;
00654
00655 while (busy);
00656 busy = true;
00657
00658 if (!mask || !EMUtil::is_same_size(this, mask)) {
00659 if (!mask) {
00660 mask = new EMData();
00661 }
00662 mask->set_size(nx, ny, nz);
00663 mask->to_one();
00664
00665 float radius = (float)(ny / 2 - 2);
00666 mask->process_inplace("mask.sharp", Dict("inner_radius", radius - 1,
00667 "outer_radius", radius + 1));
00668
00669 }
00670 double n = 0,s=0;
00671 float *d = mask->get_data();
00672 float * data = get_data();
00673 size_t size = nx*ny*nz;
00674 for (size_t i = 0; i < size; i++) {
00675 if (d[i]) { n+=1.0; s+=data[i]; }
00676 }
00677
00678
00679 float result = (float)(s/n);
00680 busy = false;
00681
00682 EXITFUNC;
00683 return result;
00684 }
00685
00686
00687 void EMData::set_ctf(Ctf * new_ctf)
00688 {
00689 ENTERFUNC;
00690
00691 vector<float> vctf = new_ctf->to_vector();
00692 attr_dict["ctf"] = vctf;
00693
00694 EXITFUNC;
00695 }
00696
00697 Ctf * EMData::get_ctf() const
00698 {
00699 if(attr_dict.has_key("ctf")) {
00700 EMAN1Ctf * ctf = new EMAN1Ctf();
00701 ctf->from_vector(attr_dict["ctf"]);
00702
00703 return dynamic_cast<Ctf *>(ctf);
00704 }
00705 else {
00706 return 0;
00707 }
00708 }
00709
00710 #include <iostream>
00711 using std::cout;
00712 using std::endl;
00713
00714 void EMData::set_size(int x, int y, int z)
00715 {
00716 ENTERFUNC;
00717
00718 if (x <= 0) {
00719 throw InvalidValueException(x, "x size <= 0");
00720 }
00721 else if (y <= 0) {
00722 throw InvalidValueException(y, "y size <= 0");
00723 }
00724 else if (z <= 0) {
00725 throw InvalidValueException(z, "z size <= 0");
00726 }
00727
00728 int old_nx = nx;
00729
00730 size_t size = (size_t)(x) * (size_t)y * (size_t)z * sizeof(float);
00731
00732 if (rdata != 0) {
00733 rdata = (float*)EMUtil::em_realloc(rdata,size);
00734 } else {
00735
00736 rdata = (float*)EMUtil::em_malloc(size);
00737 }
00738
00739 if ( rdata == 0 )
00740 {
00741 stringstream ss;
00742 string gigs;
00743 ss << (float) size/1000000000.0;
00744 ss >> gigs;
00745 string message = "Cannot allocate " + gigs + " GB - not enough memory.";
00746 throw BadAllocException(message);
00747 }
00748
00749 #ifdef EMAN2_USING_CUDA
00750
00751 free_cuda_memory();
00752 #endif // EMAN2_USING_CUDA
00753
00754 nx = x;
00755 ny = y;
00756 nz = z;
00757 nxy = nx*ny;
00758 nxyz = nx*ny*nz;
00759
00760 if (old_nx == 0) {
00761 EMUtil::em_memset(get_data(),0,size);
00762 }
00763
00764 if (supp) {
00765 EMUtil::em_free(supp);
00766 supp = 0;
00767 }
00768
00769 update();
00770 EXITFUNC;
00771 }
00772
00773 #ifdef EMAN2_USING_CUDA
00774
00775 #include <cuda_runtime_api.h>
00776 #include "cuda/cuda_util.h"
00777
00778 void EMData::set_size_cuda(int x, int y, int z)
00779 {
00780 ENTERFUNC;
00781
00782 if (x <= 0) {
00783 throw InvalidValueException(x, "x size <= 0");
00784 }
00785 else if (y <= 0) {
00786 throw InvalidValueException(y, "y size <= 0");
00787 }
00788 else if (z <= 0) {
00789 throw InvalidValueException(z, "z size <= 0");
00790 }
00791
00792 if (cuda_cache_handle!=-1) {
00793 cuda_cache.clear_item(cuda_cache_handle);
00794 cuda_cache_handle = -1;
00795 }
00796 nx = x;
00797 ny = y;
00798 nz = z;
00799
00800 nxy = nx*ny;
00801
00802 get_cuda_data();
00803
00804
00805
00806 free_memory();
00807
00808 gpu_update();
00809
00810 EXITFUNC;
00811 }
00812
00813 #endif // EMAN2_USING_CUDA
00814
00815 MArray2D EMData::get_2dview() const
00816 {
00817 const int ndims = 2;
00818 if (get_ndim() != ndims) {
00819 throw ImageDimensionException("2D only");
00820 }
00821 boost::array<std::size_t,ndims> dims = {{nx, ny}};
00822 MArray2D marray(get_data(), dims, boost::fortran_storage_order());
00823 return marray;
00824 }
00825
00826
00827 MArray3D EMData::get_3dview() const
00828 {
00829 const int ndims = 3;
00830 boost::array<std::size_t,ndims> dims = {{nx, ny, nz}};
00831 MArray3D marray(get_data(), dims, boost::fortran_storage_order());
00832 return marray;
00833 }
00834
00835
00836 MCArray2D EMData::get_2dcview() const
00837 {
00838 const int ndims = 2;
00839 if (get_ndim() != ndims) {
00840 throw ImageDimensionException("2D only");
00841 }
00842 boost::array<std::size_t,ndims> dims = {{nx/2, ny}};
00843 std::complex<float>* cdata = reinterpret_cast<std::complex<float>*>(get_data());
00844 MCArray2D marray(cdata, dims, boost::fortran_storage_order());
00845 return marray;
00846 }
00847
00848
00849 MCArray3D EMData::get_3dcview() const
00850 {
00851 const int ndims = 3;
00852 boost::array<std::size_t,ndims> dims = {{nx/2, ny, nz}};
00853 std::complex<float>* cdata = reinterpret_cast<std::complex<float>*>(get_data());
00854 MCArray3D marray(cdata, dims, boost::fortran_storage_order());
00855 return marray;
00856 }
00857
00858
00859 MCArray3D* EMData::get_3dcviewptr() const
00860 {
00861 const int ndims = 3;
00862 boost::array<std::size_t,ndims> dims = {{nx/2, ny, nz}};
00863 std::complex<float>* cdata = reinterpret_cast<std::complex<float>*>(get_data());
00864 MCArray3D* marray = new MCArray3D(cdata, dims,
00865 boost::fortran_storage_order());
00866 return marray;
00867 }
00868
00869
00870 MArray2D EMData::get_2dview(int x0, int y0) const
00871 {
00872 const int ndims = 2;
00873 if (get_ndim() != ndims) {
00874 throw ImageDimensionException("2D only");
00875 }
00876 boost::array<std::size_t,ndims> dims = {{nx, ny}};
00877 MArray2D marray(get_data(), dims, boost::fortran_storage_order());
00878 boost::array<std::size_t,ndims> bases={{x0, y0}};
00879 marray.reindex(bases);
00880 return marray;
00881 }
00882
00883
00884 MArray3D EMData::get_3dview(int x0, int y0, int z0) const
00885 {
00886 const int ndims = 3;
00887 boost::array<std::size_t,ndims> dims = {{nx, ny, nz}};
00888 MArray3D marray(get_data(), dims, boost::fortran_storage_order());
00889 boost::array<std::size_t,ndims> bases={{x0, y0, z0}};
00890 marray.reindex(bases);
00891 return marray;
00892 }
00893
00894
00895 MCArray2D EMData::get_2dcview(int x0, int y0) const
00896 {
00897 const int ndims = 2;
00898 if (get_ndim() != ndims) {
00899 throw ImageDimensionException("2D only");
00900 }
00901 boost::array<std::size_t,ndims> dims = {{nx/2, ny}};
00902 std::complex<float>* cdata = reinterpret_cast<std::complex<float>*>(get_data());
00903 MCArray2D marray(cdata, dims, boost::fortran_storage_order());
00904 boost::array<std::size_t,ndims> bases={{x0, y0}};
00905 marray.reindex(bases);
00906 return marray;
00907 }
00908
00909
00910 MCArray3D EMData::get_3dcview(int x0, int y0, int z0) const
00911 {
00912 const int ndims = 3;
00913 boost::array<std::size_t,ndims> dims = {{nx/2, ny, nz}};
00914 std::complex<float>* cdata = reinterpret_cast<std::complex<float>*>(get_data());
00915 MCArray3D marray(cdata, dims, boost::fortran_storage_order());
00916 boost::array<std::size_t,ndims> bases={{x0, y0, z0}};
00917 marray.reindex(bases);
00918 return marray;
00919 }
00920
00921 int greaterthan( const void* p1, const void* p2 )
00922 {
00923 float* v1 = (float*) p1;
00924 float* v2 = (float*) p2;
00925
00926 if ( *v1 < *v2 ) return 0;
00927 else return 1;
00928 }
00929
00930
00931 EMObject EMData::get_attr(const string & key) const
00932 {
00933 ENTERFUNC;
00934
00935 size_t size = nx * ny * nz;
00936 if ((flags & EMDATA_NEEDUPD) && (key != "is_fftpad")){update_stat();}
00937
00938
00939 if (key == "kurtosis") {
00940 float mean = attr_dict["mean"];
00941 float sigma = attr_dict["sigma"];
00942
00943 float *data = get_data();
00944 double kurtosis_sum = 0;
00945
00946 for (size_t k = 0; k < size; k++) {
00947 float t = (data[k] - mean) / sigma;
00948 float tt = t * t;
00949 kurtosis_sum += tt * tt;
00950 }
00951
00952 float kurtosis = (float)(kurtosis_sum / size - 3.0);
00953 return kurtosis;
00954 }
00955 else if (key == "skewness") {
00956 float mean = attr_dict["mean"];
00957 float sigma = attr_dict["sigma"];
00958
00959 float *data = get_data();
00960 double skewness_sum = 0;
00961 for (size_t k = 0; k < size; k++) {
00962 float t = (data[k] - mean) / sigma;
00963 skewness_sum += t * t * t;
00964 }
00965 float skewness = (float)(skewness_sum / size);
00966 return skewness;
00967 }
00968 else if (key == "median")
00969 {
00970 if ( is_complex() ) throw ImageFormatException("Error - can not calculate the median of a complex image");
00971 size_t n = size;
00972 float* tmp = new float[n];
00973 float* d = get_data();
00974 if (tmp == 0 ) throw BadAllocException("Error - could not create deep copy of image data");
00975 for(size_t i=0; i < n; ++i) tmp[i] = d[i];
00976 qsort(tmp, n, sizeof(float), &greaterthan);
00977 float median;
00978 if (n%2==1) median = tmp[n/2];
00979 else median = (tmp[n/2-1]+tmp[n/2])/2.0f;
00980 delete [] tmp;
00981 return median;
00982 }
00983 else if (key == "nonzero_median")
00984 {
00985 if ( is_complex() ) throw ImageFormatException("Error - can not calculate the median of a complex image");
00986 vector<float> tmp;
00987 size_t n = size;
00988 float* d = get_data();
00989 for( size_t i = 0; i < n; ++i ) {
00990 if ( d[i] != 0 ) tmp.push_back(d[i]);
00991 }
00992 sort(tmp.begin(), tmp.end());
00993 unsigned int vsize = tmp.size();
00994 float median;
00995 if (vsize%2==1) median = tmp[vsize/2];
00996 else median = (tmp[vsize/2-1]+tmp[vsize/2])/2.0f;
00997 return median;
00998 }
00999 else if (key == "changecount") return EMObject(changecount);
01000 else if (key == "nx") return nx;
01001 else if (key == "ny") return ny;
01002 else if (key == "nz") return nz;
01003
01004 if(attr_dict.has_key(key)) {
01005 return attr_dict[key];
01006 }
01007 else {
01008 throw NotExistingObjectException(key, "The requested key does not exist");
01009 }
01010
01011 EXITFUNC;
01012 }
01013
01014 EMObject EMData::get_attr_default(const string & key, const EMObject & em_obj) const
01015 {
01016 ENTERFUNC;
01017
01018 if(attr_dict.has_key(key)) {
01019 return get_attr(key);
01020 }
01021 else {
01022 return em_obj;
01023 }
01024
01025 EXITFUNC;
01026 }
01027
01028 Dict EMData::get_attr_dict() const
01029 {
01030 update_stat();
01031
01032 Dict tmp=Dict(attr_dict);
01033 tmp["nx"]=nx;
01034 tmp["ny"]=ny;
01035 tmp["nz"]=nz;
01036 tmp["changecount"]=changecount;
01037
01038 return tmp;
01039 }
01040
01041 void EMData::set_attr_dict(const Dict & new_dict)
01042 {
01043
01044
01045 if( ( new_dict.has_key("nx") && nx!=(int)new_dict["nx"] )
01046 || ( new_dict.has_key("ny") && ny!=(int)new_dict["ny"] )
01047 || ( new_dict.has_key("nz") && nz!=(int)new_dict["nz"] ) ) {
01048
01049 int newx, newy, newz;
01050 newx = new_dict.has_key("nx") ? (int)new_dict["nx"] : nx;
01051 newy = new_dict.has_key("ny") ? (int)new_dict["ny"] : ny;
01052 newz = new_dict.has_key("nz") ? (int)new_dict["nz"] : nz;
01053
01054 set_size(newx,newy,newz);
01055
01056
01057
01058
01059
01060
01061
01062 }
01063
01064 vector<string> new_keys = new_dict.keys();
01065 vector<string>::const_iterator it;
01066 for(it = new_keys.begin(); it!=new_keys.end(); ++it) {
01067 this->set_attr(*it, new_dict[*it]);
01068 }
01069 }
01070
01071 void EMData::set_attr_dict_explicit(const Dict & new_dict)
01072 {
01073 attr_dict = new_dict;
01074 }
01075
01076 void EMData::del_attr(const string & attr_name)
01077 {
01078 attr_dict.erase(attr_name);
01079 }
01080
01081 void EMData::del_attr_dict(const vector<string> & del_keys)
01082 {
01083 vector<string>::const_iterator it;
01084 for(it=del_keys.begin(); it!=del_keys.end(); ++it) {
01085 this->del_attr(*it);
01086 }
01087 }
01088
01089 void EMData::set_attr(const string & key, EMObject val)
01090 {
01091 if( key == "nx" && nx != (int)val) { set_size((int)val,ny,nz); return; }
01092 if( key == "ny" && ny != (int)val) { set_size(nx,(int)val,nz); return; }
01093 if( key == "nz" && nz != (int)val) { set_size(nx,ny,(int)val); return; }
01094
01095
01096 if(key == "sigma" ||
01097 key == "sigma_nonzero" ||
01098 key == "square_sum" ||
01099 key == "maximum" ||
01100 key == "minimum" ||
01101 key == "mean" ||
01102 key == "mean_nonzero" )
01103 {
01104 LOGWARN("Ignore setting read only attribute %s", key.c_str());
01105 return;
01106 }
01107
01108 attr_dict[key] = val;
01109
01110
01111
01112 }
01113
01114 void EMData::set_attr_python(const string & key, EMObject val)
01115 {
01116 if( key == "nx" && nx != (int)val) { set_size((int)val,ny,nz); return; }
01117 if( key == "ny" && ny != (int)val) { set_size(nx,(int)val,nz); return; }
01118 if( key == "nz" && nz != (int)val) { set_size(nx,ny,(int)val); return; }
01119
01120
01121 if(key == "sigma" ||
01122 key == "sigma_nonzero" ||
01123 key == "square_sum" ||
01124 key == "maximum" ||
01125 key == "minimum" ||
01126 key == "mean" ||
01127 key == "mean_nonzero" )
01128 {
01129 LOGWARN("Ignore setting read only attribute %s", key.c_str());
01130 return;
01131 }
01132
01133 EMObject::ObjectType argtype = val.get_type();
01134 if (argtype == EMObject::EMDATA) {
01135 EMData* e = (EMData*) val;
01136 e = e->copy();
01137 EMObject v(e);
01138 attr_dict[key] = v;
01139 }
01140 else if (argtype == EMObject::TRANSFORM) {
01141 Transform* t = new Transform(*((Transform*) val));
01142 EMObject v(t);
01143 attr_dict[key] = v;
01144 delete t; t=0;
01145 } else {
01146 attr_dict[key] = val;
01147 }
01148
01149 }
01150
01151 void EMData::scale_pixel(float scale) const
01152 {
01153 attr_dict["apix_x"] = ((float) attr_dict["apix_x"]) * scale;
01154 attr_dict["apix_y"] = ((float) attr_dict["apix_y"]) * scale;
01155 attr_dict["apix_z"] = ((float) attr_dict["apix_z"]) * scale;
01156 if (attr_dict.has_key("ctf")) {
01157 Ctf *ctf=(Ctf *)attr_dict["ctf"];
01158 ctf->apix*=scale;
01159 attr_dict["ctf"]=ctf;
01160 if(ctf) {delete ctf; ctf=0;}
01161 }
01162 }
01163
01164
01165
01166 std::string EMData::get_data_pickle() const
01167 {
01168
01169
01170
01171
01172 std::string vf((const char *)get_data(),nx*ny*nz*sizeof(float));
01173
01174 return vf;
01175 }
01176
01177
01178 void EMData::set_data_pickle(std::string vf)
01179 {
01180
01181
01182
01183 EMUtil::em_memcpy(get_data(),vf.data(),nx*ny*nz*sizeof(float));
01184
01185 }
01186
01187 int EMData::get_supp_pickle() const
01188 {
01189 return 0;
01190 }
01191
01192 void EMData::set_supp_pickle(int)
01193 {
01194 this->supp = 0;
01195 }
01196
01197 float EMData::get_amplitude_thres(float thres)
01198 {
01199
01200 if (thres < 0 || thres > 1){
01201 LOGERR("threshold bust be between 0 and 1.");
01202 throw InvalidValueException(thres, "thres: 0 <= thres <= 1");
01203 }
01204
01205 EMData * amps = get_fft_amplitude();
01206 vector<float> ampvector = amps->get_data_as_vector();
01207
01208 sort (ampvector.begin(), ampvector.end());
01209 int thresidx = int(thres * ampvector.size());
01210 float thresamp = ampvector[thresidx];
01211
01212 return thresamp;
01213 }
01214
01215 vector<Vec3i > find_region(EMData* image,const vector<Vec3i >& coords, const float value, vector<Vec3i >& region)
01216 {
01217 static vector<Vec3i> two_six_connected;
01218 if (two_six_connected.size() == 0) {
01219 for(int i = -1; i <= 1; ++i) {
01220 for(int j = -1; j <= 1; ++j) {
01221 for(int k = -1; k <= 1; ++k) {
01222 if ( j != 0 || i != 0 || k != 0) {
01223 two_six_connected.push_back(Vec3i(i,j,k));
01224 }
01225 }
01226 }
01227 }
01228 }
01229
01230 vector<Vec3i> ret;
01231 for(vector<Vec3i>::const_iterator it = two_six_connected.begin(); it != two_six_connected.end(); ++it ) {
01232 for(vector<Vec3i>::const_iterator it2 = coords.begin(); it2 != coords.end(); ++it2 ) {
01233 if (image->get_value_at((*it2)[0],(*it2)[1],(*it2)[2]) != value) throw;
01234 Vec3i c = (*it)+(*it2);
01235
01236 if ( c[0] < 0 || c[0] >= image->get_xsize()) continue;
01237 if ( c[1] < 0 || c[1] >= image->get_ysize()) continue;
01238 if ( c[2] < 0 || c[2] >= image->get_zsize()) continue;
01239
01240 if( image->get_value_at(c[0],c[1],c[2]) == value ) {
01241 if (find(ret.begin(),ret.end(),c) == ret.end()) {
01242 if (find(region.begin(),region.end(),c) == region.end()) {
01243 region.push_back(c);
01244 ret.push_back(c);
01245 }
01246 }
01247 }
01248 }
01249 }
01250 return ret;
01251 }
01252
01253 vector<Vec3i> EMData::mask_contig_region(const float& value, const Vec3i& seed) {
01254 Vec3i coord(seed[0],seed[1],seed[2]);
01255 vector<Vec3i> region;
01256 region.push_back(coord);
01257 vector<Vec3i> find_region_input = region;
01258 while (true) {
01259 vector<Vec3i> v = find_region(this,find_region_input, value, region);
01260 if (v.size() == 0 ) break;
01261 else find_region_input = v;
01262 }
01263 return region;
01264 }