39using std::stringstream;
42using std::setprecision;
45#ifdef EMAN2_USING_CUDA
56 LOGERR(
"complex image expected. Input image is real image.");
60 LOGERR(
"2D image expected. Input image is 3D");
62 " expected Input image is 3D.");
69 dat->set_size(nx2,
ny,
nz);
74 for (
int j = 0; j <
ny; j++) {
75 for (
int i = 0; i < nx2; i++) {
76 temp = (*this)(2*i,j)*(*
this)(2*i,j);
77 temp += (*this)(2*i+1,j)*(*
this)(2*i+1,j);
83 dat->set_complex(
false);
96 LOGERR(
"complex image expected. Input image is real image.");
104 dat->set_size(nx2,
ny,
nz);
107 float *d = dat->get_data();
111 size_t idx1, idx2, idx3;
113 for (
int k = 1; k <
nz; ++k) {
114 for (
int j = 1; j <
ny; ++j) {
115 for (
int i = 0; i < nx2/2; ++i) {
116 idx1 = (size_t)k*nx2*
ny+j*nx2+nx2/2+i;
117 idx2 = (size_t)k*
nx*
ny+j*
nx+2*i;
118 idx3 = (size_t)(
nz-k)*nx2*
ny+(
ny-j)*nx2+nx2/2-i;
119 d[idx1] = data[idx2];
120 d[idx3] = data[idx2];
125 else if (ndim == 2) {
126 for (
int j = 1; j <
ny; ++j) {
127 for (
int i = 0; i < nx2/2; ++i) {
128 d[j*nx2+nx2/2+i] = data[j*
nx+2*i];
129 d[(
ny-j)*nx2+nx2/2-i] = data[j*
nx+2*i];
135 dat->set_complex(
false);
136 if(dat->get_ysize()==1 && dat->get_zsize()==1) {
137 dat->set_complex_x(
false);
151 LOGERR(
"complex image expected. Input image is real image.");
159 dat->set_size(nx2,
ny,
nz);
162 float *d = dat->get_data();
166 size_t idx1, idx2, idx3;
168 for (
int k = 1; k <
nz; ++k) {
169 for (
int j = 1; j <
ny; ++j) {
170 for (
int i = 0; i < nx2/2; ++i) {
171 idx1 = (size_t)k*nx2*
ny+j*nx2+nx2/2+i;
172 idx2 = (size_t)k*
nx*
ny+j*
nx+2*i+1;
173 idx3 = (size_t)(
nz-k)*nx2*
ny+(
ny-j)*nx2+nx2/2-i;
174 d[idx1] = data[idx2];
175 d[idx3] = -data[idx2];
180 else if (ndim == 2) {
181 for (
int j = 1; j <
ny; ++j) {
182 for (
int i = 0; i < nx2/2; ++i) {
183 d[j*nx2+nx2/2+i] = data[j*
nx+2*i+1];
184 d[(
ny-j)*nx2+nx2/2-i] = -data[j*
nx+2*i+1];
190 dat->set_complex(
false);
191 if(dat->get_ysize()==1 && dat->get_zsize()==1) {
192 dat->set_complex_x(
false);
202void EMData::write_data(
string fsp,
size_t loc,
const Region* area,
const int file_nx,
const int file_ny,
const int file_nz) {
205 struct stat fileinfo;
206 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");
211 f=fopen(fsp.c_str(),
"rb+");
212 if (!f) f=fopen(fsp.c_str(),
"wb");
219 if (file_nx != 0) fnx = file_nx;
221 if (file_ny != 0) fny = file_ny;
223 if (file_nz != 0) fnz = file_nz;
226 0, 4,fnx,fny,fnz,area);
232void EMData::read_data(
string fsp,
size_t loc,
const Region* area,
const int file_nx,
const int file_ny,
const int file_nz) {
234 f=fopen(fsp.c_str(),
"rb");
237 if (file_nx != 0) fnx = file_nx;
239 if (file_ny != 0) fny = file_ny;
241 if (file_nz != 0) fnz = file_nz;
245 0, 4,fnx,fny,fnz,area);
257 float ds = sigma / 2;
258 size_t size = (size_t)
nx *
ny *
nz;
260 float sigma1 = sigma / 20;
261 float sigma2 = sigma / 1000;
263 while (ds > sigma1) {
267 for (
size_t i = 0; i < size; ++i) {
268 if (fabs(d[i] - center) < ds) {
276 float mean = (float)(sum / norm);
277 if (fabs(mean - center) < sigma2) {
301 size_t size = (size_t)
nx *
ny *
nz;
303 for (
size_t i = 0; i < size; ++i) {
314 float sigup =
std::sqrt((
float)sum_up / nup);
315 float sigdown =
std::sqrt((
float)sum_down / ndown);
316 float sig_diff = fabs(sigup - sigdown) / sigma;
341 for (
int j = 0; j <
nz; ++j) {
342 size_t cur_z = (size_t)j *
nxy;
344 for (
int k = 0; k <
ny; ++k) {
345 size_t cur_y = k *
nx + cur_z;
347 for (
int l = 0; l <
nx; l += di) {
348 float t = data[l + cur_y];
359 return IntPoint(min_x, min_y, min_z);
372 float max = -FLT_MAX;
379 for (
int j = 0; j <
nz; ++j) {
380 size_t cur_z = (size_t)j *
nxy;
382 for (
int k = 0; k <
ny; ++k) {
383 size_t cur_y = k *
nx + cur_z;
385 for (
int l = 0; l <
nx; l += di) {
386 float t = data[l + cur_y];
398 return IntPoint(max_x, max_y, max_z);
404 int maxshiftx = maxdx, maxshifty = maxdy, maxshiftz = maxdz;
405 if (maxdx == -1) maxshiftx =
get_xsize()/4;
406 if (maxdy == -1) maxshifty =
get_ysize()/4;
407 if (maxdz == -1) maxshiftz =
get_zsize()/4;
409 float max_value = -FLT_MAX;
413#ifdef EMAN2_USING_CUDA
414 if(EMData::usecuda == 1 && cudarwdata){
427 for (
int k = -maxshiftz; k <= maxshiftz; k++) {
428 for (
int j = -maxshifty; j <= maxshifty; j++) {
429 for (
int i = -maxshiftx; i <= maxshiftx; i++) {
433 if (value > max_value) {
442 if (value) *value=max_value;
449 int maxshiftx = maxdx, maxshifty = maxdy, maxshiftz = maxdz;
450 if (maxdx == -1) maxshiftx =
get_xsize()/4;
451 if (maxdy == -1) maxshifty =
get_ysize()/4;
452 if (maxdz == -1) maxshiftz =
get_zsize()/4;
454 float max_value = -FLT_MAX;
456 maxshiftz=maxshiftz*is3d;
477 for (
int k = -maxshiftz; k <= maxshiftz; k++) {
478 for (
int j = -maxshifty; j <= maxshifty; j++) {
479 for (
int i = -maxshiftx; i <= maxshiftx; i++) {
483 if (value > max_value) {
495 float cmx = 0.0;
float cmy = 0.0f;
float cmz = 0.0f;
497 for (
float x =
float(peak[0])-2.0f;
x <= float(peak[0])+2.0f;
x++) {
498 for (
float y =
float(peak[1])-2.0f;
y <= float(peak[1])+2.0f;
y++) {
499 for (
float z =
float(peak[2])-is3d*2.0f; z <= float(peak[2])+is3d*2.0f; z++) {
517 vector<float> mydata;
518 mydata.push_back(cmx);
519 mydata.push_back(cmy);
520 mydata.push_back(cmz);
521 mydata.push_back(max_value);
581 for (
int i = 0; i <
nx; ++i) {
582 for (
int j = 0; j <
ny; ++j) {
584 for (
int k = 0; k <
nz; ++k) {
585 size_t l = i + j2 + (size_t)k *
nxy;
586 if (data[l] >= threshold) {
587 com[0] += i * data[l];
588 com[1] += j * data[l];
589 com[2] += k * data[l];
607 size_t i = min_location[0] + min_location[1] *
nx + (size_t)min_location[2] *
nx *
ny;
615 size_t i = max_location[0] + max_location[1] *
nx + (size_t)max_location[2] *
nx *
ny;
624 vector<Pixel> result;
634 for (
int j = 0; j <
nz; ++j) {
635 size_t cur_z = (size_t)j *
nxy;
637 for (
int k = 0; k <
ny; ++k) {
638 size_t cur_y = k *
nx + cur_z;
640 for (
int l = 0; l <
nx; l += di) {
641 float v =data[l + cur_y];
643 result.push_back(
Pixel(l, k, j, v));
649 std::sort(result.begin(), result.end());
650 std::reverse(result.begin(), result.end());
660 vector<Pixel> result;
669 for (
int i=0; i<n; i++) result.push_back(
Pixel(0,0,0,-data[0]));
673 for (
int j = 0; j <
nz; ++j) {
674 size_t cur_z = (size_t)j *
nxy;
676 for (
int k = 0; k <
ny; ++k) {
677 size_t cur_y = k *
nx + cur_z;
679 for (
int l = 0; l <
nx; l += di) {
680 float v =data[l + cur_y];
681 if (v<result[n-1].value)
continue;
682 for (vector<Pixel>::iterator i=result.begin(); i<result.end(); i++) {
683 if (v>(*i).value) { result.insert(i,
Pixel(l, k, j, v)); result.pop_back();
break; }
699 vector<Pixel> result;
701 for (
int k = 0; k <
nz; k++) {
702 for (
int j = 0; j <
ny; j++) {
703 for (
int i = 0; i <
nx; i++) {
716#ifdef EMAN2_USING_CUDA
717 if(EMData::usecuda == 1 && cudarwdata){
729 for (
int i = 0, j = (
ny - 1) *
nx; i <
nx; ++i, ++j) {
730 edge_sum += data[i] + data[j];
732 for (
size_t i = 0, j =
nx - 1; i <
nxy; i +=
nx, j +=
nx) {
733 edge_sum += data[i] + data[j];
735 edge_mean = (float)edge_sum / (
nx * 2 +
ny * 2);
739 for (
size_t j = (
nxy * (
nz - 1)); j <
nxy *
nz; ++j, ++di) {
744 for (
size_t i = 0, j = (
nxy * (
nz - 1)); i <
nxy; ++i, ++j, ++di) {
745 edge_sum += data[i] + data[j];
749 int nxy2 =
nx * (
ny - 1);
750 for (
int k = 1; k <
nz - 1; ++k) {
752 size_t k3 = k2 + nxy2;
753 for (
int i = 0; i <
nx; ++i, ++di) {
754 edge_sum += data[i + k2] + data[i + k3];
757 for (
int k = 1; k <
nz - 1; ++k) {
759 size_t k3 =
nx - 1 + k2;
760 for (
int i = 1; i <
ny - 1; ++i, ++di) {
761 edge_sum += data[i *
nx + k2] + data[i *
nx + k3];
765 edge_mean = (float)edge_sum / (di * 2);
777 static bool busy =
false;
787 mask->set_size(
nx,
ny,
nz);
790 float radius = (float)(
ny / 2 - 2);
791 mask->process_inplace(
"mask.sharp",
Dict(
"inner_radius", radius - 1,
792 "outer_radius", radius + 1));
796 float *d = mask->get_data();
798 size_t size = (size_t)
nx*
ny*
nz;
799 for (
size_t i = 0; i < size; ++i) {
800 if (d[i]) { n+=1.0; s+=data[i]; }
804 float result = (float)(s/n);
816 vector<float> vctf = new_ctf->
to_vector();
828 return dynamic_cast<Ctf *
>(ctf);
860 size_t size = (size_t)
x*
y*z*
sizeof(
float);
882 ss << (float) size/1000000000.0;
884 string message =
"Cannot allocate " + gigs +
" GB - not enough memory.";
895#ifdef EMAN2_USING_CUDA
921#ifdef EMAN2_USING_CUDA
923void EMData::set_size_cuda(
int x,
int y,
int z)
958 boost::array<std::size_t,ndims> dims = {{(size_t)
nx, (
size_t)
ny}};
967 boost::array<std::size_t,ndims> dims = {{(size_t)
nx, (
size_t)
ny, (size_t)
nz}};
979 boost::array<std::size_t,ndims> dims = {{(size_t)
nx/2, (
size_t)
ny}};
980 std::complex<float>* cdata =
reinterpret_cast<std::complex<float>*
>(
get_data());
981 MCArray2D marray(cdata, dims, boost::fortran_storage_order());
989 boost::array<std::size_t,ndims> dims = {{(size_t)
nx/2, (
size_t)
ny, (size_t)
nz}};
990 std::complex<float>* cdata =
reinterpret_cast<std::complex<float>*
>(
get_data());
991 MCArray3D marray(cdata, dims, boost::fortran_storage_order());
998 float* v1 = (
float*) p1;
999 float* v2 = (
float*) p2;
1001 if ( *v1 < *v2 )
return 0;
1012 size_t size = (size_t)
nx *
ny *
nz;
1013 if (key ==
"kurtosis") {
1018 double kurtosis_sum = 0;
1020 for (
size_t k = 0; k < size; ++k) {
1021 float t = (data[k] - mean) / sigma;
1023 kurtosis_sum += tt * tt;
1026 float kurtosis = (float)(kurtosis_sum / size - 3.0);
1029 else if (key ==
"skewness") {
1034 double skewness_sum = 0;
1035 for (
size_t k = 0; k < size; ++k) {
1036 float t = (data[k] - mean) / sigma;
1037 skewness_sum += t * t * t;
1039 float skewness = (float)(skewness_sum / size);
1042 else if (key ==
"moment_inertia") {
1046 for (
int y=0;
y<
ny;
y++) {
1047 for (
int x=0;
x<
nx;
x++) {
1055 for (
int z=0; z<
nz; z++) {
1056 for (
int y=0;
y<
ny;
y++) {
1057 for (
int x=0;
x<
nx;
x++) {
1065 return (
float)moment;
1067 else if (key ==
"radius_gyration") {
1072 for (
int y=0;
y<
ny;
y++) {
1073 for (
int x=0;
x<
nx;
x++) {
1082 for (
int z=0; z<
nz; z++) {
1083 for (
int y=0;
y<
ny;
y++) {
1084 for (
int x=0;
x<
nx;
x++) {
1095 else if (key ==
"median")
1099 float* tmp =
new float[n];
1101 if (tmp == 0 )
throw BadAllocException(
"Error - could not create deep copy of image data");
1106 if (n%2==1) median = tmp[n/2];
1107 else median = (tmp[n/2-1]+tmp[n/2])/2.0f;
1111 else if (key ==
"nonzero_median")
1117 for(
size_t i = 0; i < n; ++i ) {
1118 if ( d[i] != 0 ) tmp.push_back(d[i]);
1120 sort(tmp.begin(), tmp.end());
1121 unsigned int vsize = tmp.size();
1123 if (vsize%2==1) median = tmp[vsize/2];
1124 else median = (tmp[vsize/2-1]+tmp[vsize/2])/2.0f;
1128 else if (key ==
"nx") {
1131 else if (key ==
"ny") {
1134 else if (key ==
"nz") {
1182 LOGWARN(
"Warning: Ignored setting dimension size by modifying attribute!!!");
1183 const_cast<Dict&
>(new_dict).erase(
"nx");
1184 const_cast<Dict&
>(new_dict).erase(
"ny");
1185 const_cast<Dict&
>(new_dict).erase(
"nz");
1188 vector<string> new_keys = new_dict.
keys();
1189 vector<string>::const_iterator it;
1190 for(it = new_keys.begin(); it!=new_keys.end(); ++it) {
1191 this->
set_attr(*it, new_dict[*it]);
1207 vector<string>::const_iterator it;
1208 for(it=del_keys.begin(); it!=del_keys.end(); ++it) {
1216 if(key ==
"nx" || key ==
"ny" || key ==
"nz")
1218 printf(
"Ignore setting dimension attribute %s. Use set_size if you need resize this EMData object.", key.c_str());
1224 if(key ==
"sigma" ||
1225 key ==
"sigma_nonzero" ||
1226 key ==
"square_sum" ||
1230 key ==
"mean_nonzero" )
1232 LOGWARN(
"Ignore setting read only attribute %s", key.c_str());
1243 if(key ==
"nx" || key ==
"ny" || key ==
"nz")
1245 printf(
"Ignore setting dimension attribute %s. Use set_size if you need resize this EMData object.", key.c_str());
1250 if(key ==
"sigma" ||
1251 key ==
"sigma_nonzero" ||
1252 key ==
"square_sum" ||
1256 key ==
"mean_nonzero" )
1258 LOGWARN(
"Ignore setting read only attribute %s", key.c_str());
1289 if(ctf) {
delete ctf; ctf=0;}
1329 if (thres < 0 || thres > 1){
1330 LOGERR(
"threshold bust be between 0 and 1.");
1335 vector<float> ampvector = amps->get_data_as_vector();
1337 sort (ampvector.begin(), ampvector.end());
1338 int thresidx = int(thres * ampvector.size());
1339 float thresamp = ampvector[thresidx];
1344vector<Vec3i >
find_region(
EMData* image,
const vector<Vec3i >& coords,
const float value, vector<Vec3i >& region)
1346 static vector<Vec3i> two_six_connected;
1347 if (two_six_connected.size() == 0) {
1348 for(
int i = -1; i <= 1; ++i) {
1349 for(
int j = -1; j <= 1; ++j) {
1350 for(
int k = -1; k <= 1; ++k) {
1351 if ( j != 0 || i != 0 || k != 0) {
1352 two_six_connected.push_back(
Vec3i(i,j,k));
1360 for(vector<Vec3i>::const_iterator it = two_six_connected.begin(); it != two_six_connected.end(); ++it ) {
1361 for(vector<Vec3i>::const_iterator it2 = coords.begin(); it2 != coords.end(); ++it2 ) {
1362 if (image->get_value_at((*it2)[0],(*it2)[1],(*it2)[2]) != value)
throw;
1363 Vec3i c = (*it)+(*it2);
1365 if ( c[0] < 0 || c[0] >= image->get_xsize())
continue;
1366 if ( c[1] < 0 || c[1] >= image->get_ysize())
continue;
1367 if ( c[2] < 0 || c[2] >= image->get_zsize())
continue;
1369 if( image->get_value_at(c[0],c[1],c[2]) == value ) {
1370 if (find(ret.begin(),ret.end(),c) == ret.end()) {
1371 if (find(region.begin(),region.end(),c) == region.end()) {
1372 region.push_back(c);
1383 Vec3i coord(seed[0],seed[1],seed[2]);
1384 vector<Vec3i> region;
1385 region.push_back(coord);
1386 vector<Vec3i> find_region_input = region;
1388 vector<Vec3i> v =
find_region(
this,find_region_input, value, region);
1389 if (v.size() == 0 )
break;
1390 else find_region_input = v;
Ctf is the base class for all CTF model.
virtual vector< float > to_vector() const =0
Dict is a dictionary to store <string, EMObject> pair.
void erase(const string &key)
Remove a particular key.
bool has_key(const string &key) const
Ask the Dictionary if it as a particular key.
vector< string > keys() const
Get a vector containing all of the (string) keys in this dictionary.
EMAN1Ctf is the CTF model used in EMAN1.
void from_vector(const vector< float > &vctf)
EMData stores an image's data and defines core image processing routines.
void scale(float scale_factor)
scale the image by a factor.
EMData()
For all image I/O.
float * supp
supplementary data array
float * rdata
image real data
Dict attr_dict
to store all image header info
int flags
CTF data All CTF data become attribute ctf(vector<float>) in attr_dict –Grant Tang.
EMObject is a wrapper class for types including int, float, double, etc as defined in ObjectType.
ObjectType get_type() const
Get the ObjectType This is an enumerated type first declared in the class EMObjectTypes.
static void process_region_io(void *cdata, FILE *file, int rw_mode, int image_index, size_t mode_size, int nx, int ny, int nz=1, const Region *area=0, bool need_flip=false, ImageType imgtype=IMAGE_UNKNOWN, int pre_row=0, int post_row=0)
Process image region IO.
static void em_memset(void *data, const int value, const size_t size)
static void em_memcpy(void *dst, const void *const src, const size_t size)
static bool is_same_size(const EMData *image1, const EMData *image2)
Check whether two EMData images are of the same size.
static void em_free(void *data)
static void * em_realloc(void *data, const size_t new_size)
static void * em_malloc(const size_t size)
FloatPoint defines a float-coordinate point in a 1D/2D/3D space.
IntPoint defines an integer-coordinate point in a 1D/2D/3D space.
Pixel describes a 3D pixel's coordinates and its intensity value.
Region defines a 2D or 3D rectangular region specified by its origin coordinates and all edges' sizes...
static int hypot3sq(int x, int y, int z)
Euclidean distance function squared in 3D: f(x,y,z) = (x*x + y*y + z*z);.
static int square(int n)
Calculate a number's square.
static int hypot2sq(int x, int y)
Euclidean distance function squared in 2D: f(x,y) = (x*x + y*y);.
CudaPeakInfo * calc_max_location_wrap_cuda(const float *in, const int nx, const int ny, const int nz, const int maxdx, const int maxdy, const int maxdz)
float get_edgemean_cuda(const float *data, const int nx, const int ny, const int nz)
EMData * copy() const
This file is a part of "emdata.h", to use functions in this file, you should "#include "emdata....
float get_value_at_wrap(int x, int y, int z) const
Get the pixel density value at coordinates (x,y,z).
EMData * sqrt() const
return square root of current image
float get_value_at(int x, int y, int z) const
Get the pixel density value at coordinates (x,y,z).
EMData * copy_head() const
Make an image with a copy of the current image's header.
#define InvalidValueException(val, desc)
#define ImageFormatException(desc)
#define NotExistingObjectException(objname, desc)
#define BadAllocException(desc)
#define ImageDimensionException(desc)
#define UnexpectedBehaviorException(desc)
#define FileAccessException(filename)
boost::multi_array_ref< std::complex< float >, 3 > MCArray3D
boost::multi_array_ref< float, 3 > MArray3D
boost::multi_array_ref< float, 2 > MArray2D
boost::multi_array_ref< std::complex< float >, 2 > MCArray2D
int portable_fseek(FILE *fp, off_t offset, int whence)