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

emdata_metadata.cpp

Go to the documentation of this file.
00001 
00005 /*
00006  * Author: Steven Ludtke, 04/10/2003 (sludtke@bcm.edu)
00007  * Copyright (c) 2000-2006 Baylor College of Medicine
00008  *
00009  * This software is issued under a joint BSD/GNU license. You may use the
00010  * source code in this file under either license. However, note that the
00011  * complete EMAN2 and SPARX software packages have some GPL dependencies,
00012  * so you are responsible for compliance with the licenses of these packages
00013  * if you opt to use BSD licensing. The warranty disclaimer below holds
00014  * in either instance.
00015  *
00016  * This complete copyright notice must be included in any revised version of the
00017  * source code. Additional authorship citations may be added, but existing
00018  * author citations must be preserved.
00019  *
00020  * This program is free software; you can redistribute it and/or modify
00021  * it under the terms of the GNU General Public License as published by
00022  * the Free Software Foundation; either version 2 of the License, or
00023  * (at your option) any later version.
00024  *
00025  * This program is distributed in the hope that it will be useful,
00026  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00027  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00028  * GNU General Public License for more details.
00029  *
00030  * You should have received a copy of the GNU General Public License
00031  * along with this program; if not, write to the Free Software
00032  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00033  *
00034  * */
00035 
00036 #include "emdata.h"
00037 #include "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 //      int ndim = get_ndim();
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 //      portable_fseek(f,loc,SEEK_SET);
00270 //      if (fread(get_data(),nx*ny,nz*4,f)!=(size_t)(nz*4)) throw FileAccessException(fsp);
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         //float sigma = get_attr("sigma");
00459         //float mean = get_attr("mean");
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) {             // threshold out noise (and negative density)
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         // initialize with n elements
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                 // Just pass on this for a while....see what happens
00736                 rdata = (float*)EMUtil::em_malloc(size);
00737         }
00738 //      rdata = static_cast < float *>(realloc(rdata, size));
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         // This is important
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 //      cuda_cache_handle = cuda_rw_cache.cache_data(this,rdata,nx,ny,nz); Let's be lazy
00805         // This is important
00806         free_memory(); // Now release CPU memory, seeing as a GPU resize invalidates it - Actually let's be lazy about it instead
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();} //this gives a spped up of 7.3% according to e2speedtest
00937         //update_stat();
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]; // should just be a memcpy
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         /*set nx, ny nz may resize the image*/
01044         // This wasn't supposed to 'clip' the image, but just redefine the size --steve
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 //              EMData * new_image = get_clip(Region((nx-newx)/2, (ny-newy)/2, (nz=newz)/2, newx, newy, newz));
01057 //              if(new_image) {
01058 //                      this->operator=(*new_image);
01059 //                      delete new_image;
01060 //                      new_image = 0;
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         /* Ignore 'read only' attribute. */
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         /* Ignore 'read only' attribute. */
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 //vector<float> EMData::get_data_pickle() const
01166 std::string EMData::get_data_pickle() const
01167 {
01168 //      vector<float> vf;
01169 //      vf.resize(nx*ny*nz);
01170 //      std::copy(rdata, rdata+nx*ny*nz, vf.begin());
01171 
01172         std::string vf((const char *)get_data(),nx*ny*nz*sizeof(float));
01173 
01174         return vf;
01175 }
01176 
01177 //void EMData::set_data_pickle(const vector<float>& vf)
01178 void EMData::set_data_pickle(std::string vf)
01179 {
01180 //      if (rdata) printf("rdata exists\n");
01181 //      rdata = (float *)malloc(nx*ny*nz*sizeof(float));
01182 //      std::copy(vf.begin(), vf.end(), rdata);
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         // yes I realize this may be slow if the map is big, but then again this function is only suited for tomo alignments, which if you have a big map will be VERY slow anyways!
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 }

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