EMAN2
emdata_core.cpp
Go to the documentation of this file.
1/*
2 * Author: Steven Ludtke, 04/10/2003 (sludtke@bcm.edu)
3 * Copyright (c) 2000-2006 Baylor College of Medicine
4 *
5 * This software is issued under a joint BSD/GNU license. You may use the
6 * source code in this file under either license. However, note that the
7 * complete EMAN2 and SPARX software packages have some GPL dependencies,
8 * so you are responsible for compliance with the licenses of these packages
9 * if you opt to use BSD licensing. The warranty disclaimer below holds
10 * in either instance.
11 *
12 * This complete copyright notice must be included in any revised version of the
13 * source code. Additional authorship citations may be added, but existing
14 * author citations must be preserved.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 *
30 * */
31
32#include "emdata.h"
33#include "ctf.h"
34#include "emfft.h"
35#include "cmp.h"
36
37using namespace EMAN;
38
39// debug only
40#include <iostream>
41#include <cstring>
42
43using std::cout;
44using std::endl;
45
46#ifdef EMAN2_USING_CUDA
47#include "cuda/cuda_processor.h"
48#include "cuda/cuda_cmp.h"
49#endif // EMAN2_USING_CUDA
50
52{
54 if (rdata) {
56 rdata = 0;
57 }
58
59 if (supp) {
61 supp = 0;
62 }
63
64 if (rot_fp != 0)
65 {
66 delete rot_fp;
67 rot_fp = 0;
68 }
69 /*
70 nx = 0;
71 ny = 0;
72 nz = 0;
73 nxy = 0;
74 */
75
77}
78
80{
82 if (rdata) {
84 rdata = 0;
85 }
87}
88
89EMData * EMData::copy() const
90{
92
93 EMData *ret = new EMData(*this);
94
96 return ret;
97}
98
99
101{
102 ENTERFUNC;
103 EMData *ret = new EMData();
104 ret->attr_dict = attr_dict;
105
106 ret->set_size(nx, ny, nz);
107 ret->flags = flags;
108
110
111 ret->path = path;
112 ret->pathnum = pathnum;
113
114// should these be here? d.woolford I did not comment them out, merely place them here (commented out) to draw attention
115// ret->xoff = xoff;
116// ret->yoff = yoff;
117// ret->zoff = zoff;
118// ret->changecount = changecount;
119
120 ret->update();
121
122 EXITFUNC;
123 return ret;
124}
125
126std::complex<float> EMData::get_complex_at(const int &x,const int &y) const{
127 if (abs(x)>=nx/2 || abs(y)>ny/2) return std::complex<float>(0,0);
128 if (x>=0 && y>=0) return std::complex<float>(rdata[ x*2+y*nx],rdata[x*2+y*nx+1]);
129 if (x>0 && y<0) return std::complex<float>(rdata[ x*2+(ny+y)*nx],rdata[x*2+(ny+y)*nx+1]);
130 if (x<0 && y>0) return std::complex<float>( rdata[-x*2+(ny-y)*nx],-rdata[-x*2+(ny-y)*nx+1]);
131 return std::complex<float>(rdata[-x*2-y*nx],-rdata[-x*2-y*nx+1]);
132}
133
134std::complex<float> EMData::get_complex_at(const int &x,const int &y,const int &z) const{
135 if (abs(x)>=nx/2 || abs(y)>ny/2 || abs(z)>nz/2) return std::complex<float>(0,0);
136
137 if (x<0) {
138 int idx=-x*2+(y<=0?-y:ny-y)*nx+(z<=0?-z:nz-z)*nxy;
139 return std::complex<float>(rdata[idx],-rdata[idx+1]);
140 }
141
142 int idx=x*2+(y<0?ny+y:y)*nx+(z<0?nz+z:z)*nxy;
143 return std::complex<float>(rdata[idx],rdata[idx+1]);
144}
145
146size_t EMData::get_complex_index(const int &x,const int &y,const int &z) const {
147 if (abs(x)>=nx/2 || abs(y)>ny/2 || abs(z)>nz/2) return nxyz;
148 if (x<0) {
149 return -x*2+(y<=0?-y:ny-y)*(size_t)nx+(z<=0?-z:nz-z)*(size_t)nxy;
150 }
151 return x*2+(y<0?ny+y:y)*(size_t)nx+(z<0?nz+z:z)*(size_t)nxy;
152}
153
154size_t EMData::get_complex_index(int x,int y,int z,const int &subx0,const int &suby0,const int &subz0,const int &fullnx,const int &fullny,const int &fullnz) const {
155if (abs(x)>=fullnx/2 || abs(y)>fullny/2 || abs(z)>fullnz/2) return nxyz;
156
157if (x<0) {
158 x*=-1;
159 y*=-1;
160 z*=-1;
161}
162if (y<0) y=fullny+y;
163if (z<0) z=fullnz+z;
164
165if (x<subx0||y<suby0||z<subz0||x>=subx0+nx||y>=suby0+ny||z>=subz0+nz) return nxyz;
166
167return (x-subx0)*2+(y-suby0)*(size_t)nx+(z-subz0)*(size_t)nx*(size_t)ny;
168}
169
170
171void EMData::set_complex_at(const int &x,const int &y,const std::complex<float> &val) {
172 if (abs(x)>=nx/2 || abs(y)>ny/2) return;
173 if (x==0) {
174 if (y==0) { rdata[0]=val.real(); rdata[1]=0; }
175 else if (y==ny/2 || y==-ny/2) { rdata[ny/2*nx]=val.real(); rdata[ny/2*nx+1]=0; }
176 else if (y>0) {
177 rdata[y*nx]=rdata[(ny-y)*nx]=val.real();
178 rdata[y*nx+1]=val.imag();
179 rdata[(ny-y)*nx+1]=-val.imag();
180 }
181 else {
182 rdata[(ny+y)*nx]=rdata[-y*nx]=val.real();
183 rdata[(ny+y)*nx+1]=val.imag();
184 rdata[-y*nx+1]=-val.imag();
185 }
186 }
187 else if (x==nx/2-1) {
188 if (y==0) { rdata[nx-2]=val.real(); rdata[nx-1]=0; }
189 else if (y==ny/2 || y==-ny/2) { rdata[ny/2*nx+nx-2]=val.real(); rdata[ny/2*nx+nx-1]=0; }
190 else if (y>0) {
191 rdata[y*nx+nx-2]=rdata[(ny-y)*nx+nx-2]=val.real();
192 rdata[y*nx+nx-1]=val.imag();
193 rdata[(ny-y)*nx+nx-1]=-val.imag();
194 }
195 else {
196 rdata[(ny+y)*nx+nx-2]=rdata[-y*nx+nx-2]=val.real();
197 rdata[(ny+y)*nx+nx-1]=val.imag();
198 rdata[-y*nx+nx-1]=-val.imag();
199 }
200 }
201 else if (x>0 && y>=0) { rdata[ x*2+y*nx]=val.real(); rdata[x*2+y*nx+1]=val.imag(); }
202 else if (x>0 && y<0) { rdata[ x*2+(ny+y)*nx]=val.real(); rdata[x*2+(ny+y)*nx+1]=val.imag(); /*printf("%d %d %d %f\n",x,y,x*2+(ny+y)*nx,val.real());*/ }
203 else if (x<0 && y>0) { rdata[-x*2+(ny-y)*nx]=val.real(); rdata[-x*2+(ny-y)*nx+1]=-val.imag(); }
204 else { rdata[-x*2-y*nx]=val.real(); rdata[-x*2+-y*nx+1]=-val.imag(); }
205 return;
206}
207
208void EMData::set_complex_at(const int &x,const int &y,const int &z,const std::complex<float> &val) {
209if (abs(x)>=nx/2 || abs(y)>ny/2 || abs(z)>nz/2) return;
210
211size_t idx;
212
213// for x=0, we need to insert the value in 2 places
214// complex conjugate insertion. Removed due to ambiguity with returned index
215if (x==0) {
216 if (y==0 && z==0) {
217 rdata[0]=(float)val.real();
218 rdata[1]=0;
219 return;
220 }
221 // complex conjugate in x=0 plane
222 size_t idx=(y<=0?-y:ny-y)*(size_t)nx+(z<=0?-z:nz-z)*(size_t)nxy;
223 rdata[idx]=(float)val.real();
224 rdata[idx+1]=(float)-val.imag();
225}
226if (abs(x)==nx/2-1) {
227 if (y==0 && z==0) {
228 rdata[nx-2]=(float)val.real();
229 rdata[nx-1]=0;
230 return;
231 }
232 // complex conjugate in x=0 plane
233 size_t idx=nx-2+(y<=0?-y:ny-y)*(size_t)nx+(z<=0?-z:nz-z)*(size_t)nxy;
234 rdata[idx]=(float)val.real();
235 rdata[idx+1]=(float)-val.imag();
236}
237if (x<0) {
238 idx=-x*2+(y<=0?-y:ny-y)*(size_t)nx+(z<=0?-z:nz-z)*(size_t)nxy;
239 rdata[idx]=(float)val.real();
240 rdata[idx+1]=-(float)val.imag();
241 return;
242}
243
244idx=x*2+(y<0?ny+y:y)*(size_t)nx+(z<0?nz+z:z)*(size_t)nxy;
245rdata[idx]=(float)val.real();
246rdata[idx+1]=(float)val.imag();
247
248return;
249}
250
251size_t EMData::add_complex_at(const int &x,const int &y,const int &z,const std::complex<float> &val) {
252if (abs(x)>=nx/2 || abs(y)>ny/2 || abs(z)>nz/2) return nxyz;
253
254//if (x==0 && abs(y)==16 && abs(z)==1) printf("## %d %d %d\n",x,y,z);
255size_t idx;
256// for x=0, we need to insert the value in 2 places
257if (x==0) {
258 if (y==0 && z==0) {
259 rdata[0]+=(float)val.real();
260 rdata[1]=0;
261 return 0;
262 }
263 // complex conjugate in x=0 plane
264 size_t idx=(y<=0?-y:ny-y)*(size_t)nx+(z<=0?-z:nz-z)*(size_t)nxy;
265// if (idx==16*34+1*34*32) printf("a %d %d %d\t%1.5f+%1.5fi\t%1.5f+%1.5fi\n",x,y,z,val.real(),val.imag(),rdata[idx],rdata[idx+1]);
266 rdata[idx]+=(float)val.real();
267 rdata[idx+1]+=(float)-val.imag();
268}
269if (abs(x)==nx/2-1) {
270 if (y==0 && z==0) {
271 rdata[nx-2]+=(float)val.real();
272 rdata[nx-1]=0;
273 return nx-2;
274 }
275 // complex conjugate in x=0 plane
276 size_t idx=nx-2+(y<=0?-y:ny-y)*(size_t)nx+(z<=0?-z:nz-z)*(size_t)nxy;
277// if (idx==16*34+1*34*32) printf("b %d %d %d\t%1.5f+%1.5fi\t%1.5f+%1.5fi\n",x,y,z,val.real(),val.imag(),rdata[idx],rdata[idx+1]);
278 rdata[idx]+=(float)val.real();
279 rdata[idx+1]+=(float)-val.imag();
280}
281if (x<0) {
282 idx=-x*2+(y<=0?-y:ny-y)*(size_t)nx+(z<=0?-z:nz-z)*(size_t)nxy;
283// if (idx==16*34+1*34*32) printf("c %d %d %d\t%1.5f+%1.5fi\t%1.5f+%1.5fi\n",x,y,z,val.real(),val.imag(),rdata[idx],rdata[idx+1]);
284 rdata[idx]+=(float)val.real();
285 rdata[idx+1]+=-(float)val.imag();
286 return idx;
287}
288
289idx=x*2+(y<0?ny+y:y)*(size_t)nx+(z<0?nz+z:z)*(size_t)nxy;
290//if (idx==16*34+1*34*32) printf("d %d %d %d\t%1.5f+%1.5fi\t%1.5f+%1.5fi\n",x,y,z,val.real(),val.imag(),rdata[idx],rdata[idx+1]);
291rdata[idx]+=(float)val.real();
292rdata[idx+1]+=(float)val.imag();
293
294return idx;
295}
296
297size_t EMData::add_complex_at(int x,int y,int z,const int &subx0,const int &suby0,const int &subz0,const int &fullnx,const int &fullny,const int &fullnz,const std::complex<float> &val) {
298if (abs(x)>=fullnx/2 || abs(y)>fullny/2 || abs(z)>fullnz/2) return nxyz;
299//if (x==0 && (y!=0 || z!=0)) add_complex_at(0,-y,-z,subx0,suby0,subz0,fullnx,fullny,fullnz,conj(val));
300// complex conjugate insertion. Removed due to ambiguity with returned index
301/*if (x==0&& (y!=0 || z!=0)) {
302 int yy=y<=0?-y:fullny-y;
303 int zz=z<=0?-z:fullnz-z;
304
305 if (yy<suby0||zz<subz0||yy>=suby0+ny||zz>=subz0+nz) return nx*ny*nz;
306
307 size_t idx=(yy-suby0)*nx+(zz-subz0)*nx*ny;
308 rdata[idx]+=(float)val.real();
309 rdata[idx+1]+=(float)-val.imag();
310}*/
311float cc=1.0;
312if (x<0) {
313 x*=-1;
314 y*=-1;
315 z*=-1;
316 cc=-1.0;
317}
318if (y<0) y=fullny+y;
319if (z<0) z=fullnz+z;
320
321if (x<subx0||y<suby0||z<subz0||x>=subx0+nx||y>=suby0+ny||z>=subz0+nz) return nxyz;
322
323size_t idx=(x-subx0)*2+(y-suby0)*(size_t)nx+(z-subz0)*(size_t)nx*ny;
324rdata[idx]+=(float)val.real();
325rdata[idx+1]+=cc*(float)val.imag();
326return idx;
327}
328
329
330void EMData::add(float f,int keepzero)
331{
332 ENTERFUNC;
333
334 float * data = get_data();
335 if( is_real() )
336 {
337 if (f != 0) {
338
339 size_t size = nxyz;
340 if (keepzero) {
341 for (size_t i = 0; i < size; i++) {
342 if (data[i]) data[i] += f;
343 }
344 }
345 else {
346 for (size_t i = 0; i < size; i++) {
347 data[i] += f;
348 }
349 }
350 update();
351 }
352 }
353 else if( is_complex() )
354 {
355 if( f!=0 )
356 {
357 update();
358 size_t size = (size_t)nx*ny*nz; //size of data
359 if( keepzero )
360 {
361 for(size_t i=0; i<size; i+=2)
362 {
363 if (data[i]) data[i] += f;
364 }
365 }
366 else
367 {
368 for(size_t i=0; i<size; i+=2)
369 {
370 data[i] += f;
371 }
372 }
373 }
374 }
375 else
376 {
377 throw ImageFormatException("This image is neither a real nor a complex image.");
378 }
379 update();
380 EXITFUNC;
381}
382
383
384//for add operation, real and complex image is the same
385void EMData::add(const EMData & image)
386{
387 ENTERFUNC;
388 if (nx != image.get_xsize() || ny != image.get_ysize() || nz != image.get_zsize()) {
389 throw ImageFormatException( "images not same sizes");
390 }
391 else if( (is_real()^image.is_real()) == true )
392 {
393 throw ImageFormatException( "not support add between real image and complex image");
394 }
395 else {
396
397 const float *src_data = image.get_data();
398 size_t size = nxyz;
399 float* data = get_data();
400
401 for (size_t i = 0; i < size; i++) {
402 data[i] += src_data[i];
403 }
404 update();
405 }
406 EXITFUNC;
407}
408
409//for add operation, real and complex image is the same
410void EMData::addsquare(const EMData & image)
411{
412 ENTERFUNC;
413 if (nx != image.get_xsize() || ny != image.get_ysize() || nz != image.get_zsize()) {
414 throw ImageFormatException( "images not same sizes");
415 }
416 else if( this->is_complex() || image.is_complex() )
417 {
418 throw ImageFormatException( "Cannot addsquare() with complex images");
419 }
420 else {
421
422 const float *src_data = image.get_data();
423 size_t size = nxyz;
424 float* data = get_data();
425
426 for (size_t i = 0; i < size; i++) {
427 data[i] += src_data[i]*src_data[i];
428 }
429 update();
430 }
431 EXITFUNC;
432}
433
434//for add operation, real and complex image is the same
435void EMData::subsquare(const EMData & image)
436{
437 ENTERFUNC;
438 if (nx != image.get_xsize() || ny != image.get_ysize() || nz != image.get_zsize()) {
439 throw ImageFormatException( "images not same sizes");
440 }
441 else if( this->is_complex() || image.is_complex() )
442 {
443 throw ImageFormatException( "Cannot addsquare() with complex images");
444 }
445 else {
446
447 const float *src_data = image.get_data();
448 size_t size = nxyz;
449 float* data = get_data();
450
451 for (size_t i = 0; i < size; i++) {
452 data[i] -= src_data[i]*src_data[i];
453 }
454 update();
455 }
456 EXITFUNC;
457}
458
459
460void EMData::sub(float f)
461{
462 ENTERFUNC;
463
464#ifdef EMAN2_USING_CUDA
465 if (EMData::usecuda == 1 && cudarwdata) {
466 if(f != 0){
467 subtract_cuda(cudarwdata, f, nx, ny, nz);
468 }
469 EXITFUNC;
470 return;
471 }
472#endif // EMAN2_USING_CUDA
473
474 float* data = get_data();
475 if( is_real() )
476 {
477 if (f != 0) {
478 size_t size = nxyz;
479 for (size_t i = 0; i < size; i++) {
480 data[i] -= f;
481 }
482 }
483 update();
484 }
485 else if( is_complex() )
486 {
487 if( f != 0 )
488 {
489 size_t size = nxyz;
490 for( size_t i=0; i<size; i+=2 )
491 {
492 data[i] -= f;
493 }
494 }
495 update();
496 }
497 else
498 {
499 throw ImageFormatException("This image is neither a real nor a complex image.");
500 }
501
502 EXITFUNC;
503}
504
505
506//for sub operation, real and complex image is the same
507void EMData::sub(const EMData & em)
508{
509 ENTERFUNC;
510
511 if (nx != em.get_xsize() || ny != em.get_ysize() || nz != em.get_zsize()) {
512 throw ImageFormatException("images not same sizes");
513 }
514 else if( (is_real()^em.is_real()) == true )
515 {
516 throw ImageFormatException( "not support sub between real image and complex image");
517 }
518 else {
519 const float *src_data = em.get_data();
520 size_t size = nxyz;
521 float* data = get_data();
522
523 for (size_t i = 0; i < size; i++) {
524 data[i] -= src_data[i];
525 }
526 update();
527 }
528 EXITFUNC;
529}
530
531
532void EMData::mult(float f)
533{
534 ENTERFUNC;
535
536// this will cause a crash if CUDA is used(no rdata) and a complex map is given.....
537 if (is_complex()) {
538 ap2ri();
539 }
540 if (f != 1.0) {
541#ifdef EMAN2_USING_CUDA
542 if (EMData::usecuda == 1 && cudarwdata) { //doesn't make any sense to use RO, esp on compute devices >= 2.0
543 //cout << "CUDA mult" << endl;
544 emdata_processor_mult(cudarwdata,f,nx,ny,nz);
545 EXITFUNC;
546 return;
547 }
548#endif // EMAN2_USING_CUDA
549 float* data = get_data();
550 size_t size = nxyz;
551 for (size_t i = 0; i < size; i++) {
552 data[i] *= f;
553 }
554 update();
555 }
556 EXITFUNC;
557}
558
559
560void EMData::mult(const EMData & em, bool prevent_complex_multiplication)
561{
562 ENTERFUNC;
563
564 if (nx != em.get_xsize() || ny != em.get_ysize() || nz != em.get_zsize()) {
565 throw ImageFormatException( "can not multiply images that are not the same size");
566 }
567 else if( (is_real()^em.is_real()) == true )
568 {
569 throw ImageFormatException( "can not multiply real and complex images.");
570 }
571 else
572 {
573 const float *src_data = em.get_data();
574 size_t size = nxyz;
575 float* data = get_data();
576 if( is_real() || prevent_complex_multiplication )
577 {
578 for (size_t i = 0; i < size; i++) {
579 data[i] *= src_data[i];
580 }
581 }
582 else mult_ri(em);
583 update();
584 }
585
586 EXITFUNC;
587}
588
589// This implements complex RI multiplication, but does no checking of data types for efficiency
590// calling is_ri can be very expensive.
591void EMData::mult_ri(const EMData &em) {
592 typedef std::complex<float> comp;
593 const float *src_data = em.get_data();
594 float* data = get_data();
595 for( size_t i = 0; i < nxyz; i+=2 )
596 {
597 comp c_src( src_data[i], src_data[i+1] );
598 comp c_rdat( data[i], data[i+1] );
599 comp c_result = c_src * c_rdat;
600 data[i] = c_result.real();
601 data[i+1] = c_result.imag();
602 }
603 update();
604}
605
606
607void EMData::mult_complex_efficient(const EMData & em, const int radius)
608{
609 ENTERFUNC;
610
611 if( is_real() || em.is_real() )throw ImageFormatException( "can call mult_complex_efficient unless both images are complex");
612
613
614 const float *src_data = em.get_data();
615
616 size_t i_radius = radius;
617 size_t k_radius = 1;
618 size_t j_radius = 1;
619 int ndim = get_ndim();
620
621 if (ndim != em.get_ndim()) throw ImageDimensionException("Can't do that");
622
623 if ( ndim == 3 ) {
624 k_radius = radius;
625 j_radius = radius;
626 } else if ( ndim == 2 ) {
627 j_radius = radius;
628 }
629
630
631 int s_nx = em.get_xsize();
632 int s_nxy = s_nx*em.get_ysize();
633
634 size_t r_size = nxyz;
635 int s_size = s_nxy*em.get_zsize();
636 float* data = get_data();
637
638 for (size_t k = 0; k < k_radius; ++k ) {
639 for (size_t j = 0; j < j_radius; j++) {
640 for (size_t i = 0; i < i_radius; i++) {
641 int r_idx = k*nxy + j*nx + i;
642 int s_idx = k*s_nxy + j*s_nx + i;
643 data[r_idx] *= src_data[s_idx];
644 data[r_size-r_idx-1] *= src_data[s_size-s_idx-1];
645 }
646 }
647 }
648
649 update();
650
651 EXITFUNC;
652}
653
654
655void EMData::div(float f)
656{
657 ENTERFUNC;
658 if ( f == 0 ) {
659 throw InvalidValueException(f,"Can not divide by zero");
660 }
661 mult(1.0f/f);
662 EXITFUNC;
663}
664
665void EMData::div(const EMData & em)
666{
667 ENTERFUNC;
668
669 if (nx != em.get_xsize() || ny != em.get_ysize() || nz != em.get_zsize()) {
670 throw ImageFormatException( "images not same sizes");
671 }
672 else if( (is_real()^em.is_real()) == true )
673 {
674 throw ImageFormatException( "not support division between real image and complex image");
675 }
676 else {
677 const float *src_data = em.get_data();
678 size_t size = nxyz;
679 float* data = get_data();
680
681 if( is_real() )
682 {
683 for (size_t i = 0; i < size; i++) {
684 if(src_data[i] != 0) {
685 data[i] /= src_data[i];
686 }
687 else {
688 if (data[i]==0) continue;
689 throw InvalidValueException(src_data[i], "divide by zero");
690 }
691 }
692 }
693 else
694 {
695 typedef std::complex<float> comp;
696 for( size_t i = 0; i < size; i+=2 )
697 {
698 comp c_src( src_data[i], src_data[i+1] );
699 comp c_rdat( data[i], data[i+1] );
700 comp c_result = c_rdat / c_src;
701 data[i] = c_result.real();
702 data[i+1] = c_result.imag();
703 }
704 }
705 update();
706 }
707
708 EXITFUNC;
709}
710
711void EMData::update_min(const EMData & em)
712{
713 ENTERFUNC;
714
715 if (nx != em.get_xsize() || ny != em.get_ysize() || nz != em.get_zsize()) {
716 throw ImageFormatException( "images not same sizes");
717 }
718 if( !is_real() || !em.is_real() )
719 {
720 throw ImageFormatException( "update_min does not support complex images");
721 }
722
723 for (size_t i = 0; i < nxyz; i++) set_value_at_index(i,Util::get_min(get_value_at_index(i),em.get_value_at_index(i)));
724
725 update();
726
727 EXITFUNC;
728}
729
730
731// just a shortcut for cmp("dot")
732float EMData::dot(EMData * with)
733{
734 ENTERFUNC;
735 if (!with) {
736 throw NullPointerException("Null EMData Image");
737 }
738 DotCmp dot_cmp;
739 float r = -dot_cmp.cmp(this, with);
740 EXITFUNC;
741 return r;
742}
743
744
745EMData *EMData::get_row(int row_index) const
746{
747 ENTERFUNC;
748
749 if (get_ndim() > 2) {
750 throw ImageDimensionException("1D/2D image only");
751 }
752
753 EMData *ret = new EMData();
754 ret->set_size(nx, 1, 1);
755 memcpy(ret->get_data(), get_data() + nx * row_index, nx * sizeof(float));
756 ret->update();
757 EXITFUNC;
758 return ret;
759}
760
761
762void EMData::set_row(const EMData * d, int row_index)
763{
764 ENTERFUNC;
765
766 if (get_ndim() > 2) {
767 throw ImageDimensionException("1D/2D image only");
768 }
769 if (d->get_ndim() != 1) {
770 throw ImageDimensionException("1D image only");
771 }
772
773 float *dst = get_data();
774 float *src = d->get_data();
775 memcpy(dst + nx * row_index, src, nx * sizeof(float));
776 update();
777 EXITFUNC;
778}
779
780EMData *EMData::get_col(int col_index) const
781{
782 ENTERFUNC;
783
784 if (get_ndim() != 2) {
785 throw ImageDimensionException("2D image only");
786 }
787
788 EMData *ret = new EMData();
789 ret->set_size(ny, 1, 1);
790 float *dst = ret->get_data();
791 float *src = get_data();
792
793 for (int i = 0; i < ny; i++) {
794 dst[i] = src[i * nx + col_index];
795 }
796
797 ret->update();
798 EXITFUNC;
799 return ret;
800}
801
802
803void EMData::set_col(const EMData * d, int n)
804{
805 ENTERFUNC;
806
807 if (get_ndim() != 2) {
808 throw ImageDimensionException("2D image only");
809 }
810 if (d->get_ndim() != 1) {
811 throw ImageDimensionException("1D image only");
812 }
813
814 float *dst = get_data();
815 float *src = d->get_data();
816
817 for (int i = 0; i < ny; i++) {
818 dst[i * nx + n] = src[i];
819 }
820
821 update();
822 EXITFUNC;
823}
824
826{
827 if (x < 0) x = nx + x;
828 return get_data()[x];
829}
830
832{
833 if (x < 0) x = nx + x;
834 if (y < 0) y = ny + y;
835
836 return get_data()[x + y * nx];
837}
838
839float& EMData::get_value_at_wrap(int x, int y, int z)
840{
841
842#ifdef EMAN2_USING_CUDA
843 if(EMData::usecuda == 1 && cudarwdata){
844 float result = get_value_at_wrap_cuda(cudarwdata, x, y, z, nx, ny, nz); // this should work....
845 return result;
846 }
847#endif
848 int lx = x;
849 int ly = y;
850 int lz = z;
851
852 if (lx < 0) lx = nx + lx;
853 if (ly < 0) ly = ny + ly;
854 if (lz < 0) lz = nz + lz;
855
856 return get_data()[lx + ly * (size_t)nx + lz * (size_t)nxy];
857}
858
859float EMData::get_value_at_wrap(int x) const
860{
861 if (x < 0) x = nx - x;
862 return get_data()[x];
863}
864
865float EMData::get_value_at_wrap(int x, int y) const
866{
867 if (x < 0) x = nx - x;
868 if (y < 0) y = ny - y;
869
870 return get_data()[x + y * nx];
871}
872
873float EMData::get_value_at_wrap(int x, int y, int z) const
874{
875 ptrdiff_t lx = x;
876 ptrdiff_t ly = y;
877 ptrdiff_t lz = z;
878 if (lx < 0) lx = nx + lx;
879 if (ly < 0) ly = ny + ly;
880 if (lz < 0) lz = nz + lz;
881
882 return get_data()[lx + ly * nx + lz * nxy];
883}
884
885float EMData::sget_value_at(int x, int y, int z) const
886{
887 if (x < 0 || x >= nx || y < 0 || y >= ny || z < 0 || z >= nz) {
888 return 0;
889 }
890 return get_data()[(size_t)x + (size_t)y * (size_t)nx + (size_t)z * (size_t)nxy];
891}
892
893
894float EMData::sget_value_at(int x, int y) const
895{
896 if (x < 0 || x >= nx || y < 0 || y >= ny) {
897 return 0;
898 }
899 return get_data()[x + y * nx];
900}
901
902
903float EMData::sget_value_at(size_t i) const
904{
905 size_t size = nx*ny;
906 size *= nz;
907 if (i >= size) {
908 return 0;
909 }
910 return get_data()[i];
911}
912
913
914float EMData::sget_value_at_interp(float xx, float yy) const
915{
916 int x = static_cast < int >(Util::fast_floor(xx));
917 int y = static_cast < int >(Util::fast_floor(yy));
918
919 float p1 = sget_value_at(x, y);
920 float p2 = sget_value_at(x + 1, y);
921 float p3 = sget_value_at(x, y + 1);
922 float p4 = sget_value_at(x + 1, y + 1);
923
924 float result = Util::bilinear_interpolate(p1, p2, p3, p4, xx - x, yy - y);
925 return result;
926}
927
928std::complex<float> EMData::get_complex_at_interp(float xx, float yy) const
929{
930 int x = static_cast < int >(Util::fast_floor(xx));
931 int y = static_cast < int >(Util::fast_floor(yy));
932
933 std::complex<float> p1 = get_complex_at(x, y);
934 std::complex<float> p2 = get_complex_at(x + 1, y);
935 std::complex<float> p3 = get_complex_at(x, y + 1);
936 std::complex<float> p4 = get_complex_at(x + 1, y + 1);
937
938 return Util::bilinear_interpolate_cmplx(p1, p2, p3, p4, xx - x, yy - y);
939}
940
941std::complex<float> EMData::get_complex_at_ginterp(float xx, float yy) const
942{
943 int x = static_cast < int >(Util::fast_floor(xx));
944 int y = static_cast < int >(Util::fast_floor(yy));
945
946 std::complex<float> p1 = get_complex_at(x, y);
947 std::complex<float> p2 = get_complex_at(x + 1, y);
948 std::complex<float> p3 = get_complex_at(x, y + 1);
949 std::complex<float> p4 = get_complex_at(x + 1, y + 1);
950
951 return Util::gauss_interpolate_cmplx(p1, p2, p3, p4, xx - x, yy - y);
952}
953
954std::complex<float> EMData::get_complex_at_3ginterp(float xx, float yy) const
955{
956 int x0 = static_cast < int >(Util::fast_floor(xx-0.5));
957 int y0 = static_cast < int >(Util::fast_floor(yy-0.5));
958
959 std::complex<float> p[9];
960 for (int y=0,i=0; y<3; y++) {
961 for (int x=0; x<3; x++,i++) {
962 p[i]=get_complex_at(x+x0,y+y0);
963 }
964 }
965
966 return Util::gauss3_interpolate_cmplx(p, xx-x0, yy-y0);
967}
968
969
970float EMData::sget_value_at_interp(float xx, float yy, float zz) const
971{
972 int x = (int) Util::fast_floor(xx);
973 int y = (int) Util::fast_floor(yy);
974 int z = (int) Util::fast_floor(zz);
975
976 float p1 = sget_value_at(x, y, z);
977 float p2 = sget_value_at(x + 1, y, z);
978 float p3 = sget_value_at(x, y + 1, z);
979 float p4 = sget_value_at(x + 1, y + 1, z);
980
981 float p5 = sget_value_at(x, y, z + 1);
982 float p6 = sget_value_at(x + 1, y, z + 1);
983 float p7 = sget_value_at(x, y + 1, z + 1);
984 float p8 = sget_value_at(x + 1, y + 1, z + 1);
985
986 float result = Util::trilinear_interpolate(p1, p2, p3, p4, p5, p6, p7, p8,
987 xx - x, yy - y, zz - z);
988
989 return result;
990}
991
992
993EMData & EMData::operator+=(float n)
994{
995 add(n);
996 update();
997 return *this;
998}
999
1000
1001EMData & EMData::operator-=(float n)
1002{
1003 *this += (-n);
1004 return *this;
1005}
1006
1007
1008EMData & EMData::operator*=(float n)
1009{
1010 mult(n);
1011 update();
1012 return *this;
1013}
1014
1015
1016EMData & EMData::operator/=(float n)
1017{
1018 if (n == 0) {
1019 LOGERR("divided by zero");
1020 return *this;
1021 }
1022 *this *= (1.0f / n);
1023 return *this;
1024}
1025
1026
1027EMData & EMData::operator+=(const EMData & em)
1028{
1029 add(em);
1030 update();
1031 return *this;
1032}
1033
1034
1035EMData & EMData::operator-=(const EMData & em)
1036{
1037 sub(em);
1038 update();
1039 return *this;
1040}
1041
1042
1043EMData & EMData::operator*=(const EMData & em)
1044{
1045 mult(em);
1046 update();
1047 return *this;
1048}
1049
1050
1051EMData & EMData::operator/=(const EMData & em)
1052{
1053 div(em);
1054 update();
1055 return *this;
1056}
1057
1058
1059EMData * EMData::power(int n) const
1060{
1061 ENTERFUNC;
1062
1063 if( n<0 ) {
1064 throw InvalidValueException(n, "the power of negative integer not supported.");
1065 }
1066
1067 EMData * r = this->copy();
1068 if( n == 0 ) {
1069 r->to_one();
1070 }
1071 else if( n>1 ) {
1072 for( int i=1; i<n; i++ ) {
1073 *r *= *this;
1074 }
1075 }
1076
1077 r->update();
1078 return r;
1079
1080 EXITFUNC;
1081}
1082
1083
1085{
1086 ENTERFUNC;
1087
1088 if (is_complex()) {
1089 throw ImageFormatException("real image only");
1090 }
1091
1092 EMData * r = this->copy();
1093 float * new_data = r->get_data();
1094 float * data = get_data();
1095 size_t size = nxyz;
1096 for (size_t i = 0; i < size; ++i) {
1097 if(data[i] < 0) {
1098 throw InvalidValueException(data[i], "pixel value must be non-negative for logrithm");
1099 }
1100 else {
1101 if(data[i]) { //do nothing with pixel has value zero
1102 new_data[i] = std::sqrt(data[i]);
1103 }
1104 }
1105 }
1106
1107 r->update();
1108 return r;
1109
1110 EXITFUNC;
1111}
1112
1113
1115{
1116 ENTERFUNC;
1117
1118 if (is_complex()) {
1119 throw ImageFormatException("real image only");
1120 }
1121
1122 EMData * r = this->copy();
1123 float * new_data = r->get_data();
1124 float * data = get_data();
1125 size_t size = nxyz;
1126 for (size_t i = 0; i < size; ++i) {
1127 if(data[i] < 0) {
1128 throw InvalidValueException(data[i], "pixel value must be non-negative for logrithm");
1129 }
1130 else {
1131 if(data[i]) { //do nothing with pixel has value zero
1132 new_data[i] = std::log(data[i]);
1133 }
1134 }
1135 }
1136
1137 r->update();
1138 return r;
1139
1140 EXITFUNC;
1141}
1142
1143
1145{
1146 ENTERFUNC;
1147
1148 if (is_complex()) {
1149 throw ImageFormatException("real image only");
1150 }
1151
1152 EMData * r = this->copy();
1153 float * new_data = r->get_data();
1154 float * data = get_data();
1155 size_t size = nxyz;
1156 for (size_t i = 0; i < size; ++i) {
1157 if(data[i] < 0) {
1158 throw InvalidValueException(data[i], "pixel value must be non-negative for logrithm");
1159 }
1160 else {
1161 if(data[i]) { //do nothing with pixel has value zero
1162 new_data[i] = std::log10(data[i]);
1163 }
1164 }
1165 }
1166
1167 r->update();
1168 return r;
1169
1170 EXITFUNC;
1171}
1172
1173
1174EMData * EMData::real() const //real part has half of x dimension for a complex image
1175{
1176 ENTERFUNC;
1177
1178 EMData * e = new EMData();
1179
1180 if( is_real() ) // a real image, return a copy of itself
1181 {
1182 e = this->copy();
1183 }
1184 else //for a complex image
1185 {
1186 if( !is_ri() )
1187 {
1188 delete e;
1189 throw InvalidCallException("This image is in amplitude/phase format, this function call require a complex image in real/imaginary format.");
1190 }
1191 int nx = get_xsize();
1192 int ny = get_ysize();
1193 int nz = get_zsize();
1194 e->set_size(nx/2, ny, nz);
1195 float * edata = e->get_data();
1196 float * data = get_data();
1197 size_t idx1, idx2;
1198 for( int i=0; i<nx; ++i )
1199 {
1200 for( int j=0; j<ny; ++j )
1201 {
1202 for( int k=0; k<nz; ++k )
1203 {
1204 if( i%2 == 0 )
1205 {
1206 //complex data in format [real, complex, real, complex...]
1207 idx1 = i/2+j*(nx/2)+k*(nx/2)*ny;
1208 idx2 = i+j*nx+k*nx*ny;
1209 edata[idx1] = data[idx2];
1210 }
1211 }
1212 }
1213 }
1214 }
1215
1216 e->set_complex(false);
1217 if(e->get_ysize()==1 && e->get_zsize()==1) {
1218 e->set_complex_x(false);
1219 }
1220 e->update();
1221 return e;
1222
1223 EXITFUNC;
1224}
1225
1226
1227EMData * EMData::imag() const
1228{
1229 ENTERFUNC;
1230
1231 EMData * e = new EMData();
1232
1233 if( is_real() ) { //a real image has no imaginary part, throw exception
1234 throw InvalidCallException("No imaginary part for a real image, this function call require a complex image.");
1235 }
1236 else { //for complex image
1237 if( !is_ri() ) {
1238 throw InvalidCallException("This image is in amplitude/phase format, this function call require a complex image in real/imaginary format.");
1239 }
1240 int nx = get_xsize();
1241 int ny = get_ysize();
1242 int nz = get_zsize();
1243 e->set_size(nx/2, ny, nz);
1244 float * edata = e->get_data();
1245 float * data = get_data();
1246 for( int i=0; i<nx; i++ ) {
1247 for( int j=0; j<ny; j++ ) {
1248 for( int k=0; k<nz; k++ ) {
1249 if( i%2 == 1 ) {
1250 //complex data in format [real, complex, real, complex...]
1251 edata[i/2+j*(nx/2)+k*(nx/2)*ny] = data[i+j*nx+k*nx*ny];
1252 }
1253 }
1254 }
1255 }
1256 }
1257
1258 e->set_complex(false);
1259 if(e->get_ysize()==1 && e->get_zsize()==1) {
1260 e->set_complex_x(false);
1261 }
1262 e->update();
1263 return e;
1264
1265 EXITFUNC;
1266}
1267
1268EMData * EMData::absi() const//abs has half of x dimension for a complex image
1269{
1270 ENTERFUNC;
1271
1272 EMData * e = new EMData();
1273
1274 if( is_real() ) // a real image
1275 {
1276 e = this->copy();
1277 int nx = get_xsize();
1278 int ny = get_ysize();
1279 int nz = get_zsize();
1280 float *edata = e->get_data();
1281 float * data = get_data();
1282 size_t idx;
1283 for( int i=0; i<nx; ++i ) {
1284 for( int j=0; j<ny; ++j ) {
1285 for( int k=0; k<nz; ++k ) {
1286 idx = i+j*nx+k*nx*ny;
1287 edata[idx] = std::abs(data[idx]);
1288 }
1289 }
1290 }
1291 }
1292 else //for a complex image
1293 {
1294 if( !is_ri() )
1295 {
1296 throw InvalidCallException("This image is in amplitude/phase format, this function call require a complex image in real/imaginary format.");
1297 }
1298 int nx = get_xsize();
1299 int ny = get_ysize();
1300 int nz = get_zsize();
1301 e->set_size(nx/2, ny, nz);
1302 float * edata = e->get_data();
1303 float * data = get_data();
1304 size_t idx1, idx2;
1305 for( int i=0; i<nx; ++i )
1306 {
1307 for( int j=0; j<ny; ++j )
1308 {
1309 for( int k=0; k<nz; ++k )
1310 {
1311 if( i%2 == 0 )
1312 {
1313 idx1 = i/2+j*(nx/2)+k*(nx/2)*ny;
1314 idx2 = i+j*nx+k*nx*ny;
1315 //complex data in format [real, complex, real, complex...]
1316 edata[idx1] =
1317 std::sqrt(data[idx2]*data[idx2]+data[idx2+1]*data[idx2+1]);
1318 }
1319 }
1320 }
1321 }
1322 }
1323
1324 e->set_complex(false);
1325 if(e->get_ysize()==1 && e->get_zsize()==1) {
1326 e->set_complex_x(false);
1327 }
1328 e->update();
1329 return e;
1330
1331 EXITFUNC;
1332}
1333
1334
1335EMData * EMData::amplitude() const
1336{
1337 ENTERFUNC;
1338
1339 EMData * e = new EMData();
1340
1341 if( is_real() ) {
1342 throw InvalidCallException("No imaginary part for a real image, this function call require a complex image.");
1343 }
1344 else {
1345 if(is_ri()) {
1346 throw InvalidCallException("This image is in real/imaginary format, this function call require a complex image in amplitude/phase format.");
1347 }
1348
1349 int nx = get_xsize();
1350 int ny = get_ysize();
1351 int nz = get_zsize();
1352 e->set_size(nx/2, ny, nz);
1353 float * edata = e->get_data();
1354 float * data = get_data();
1355 size_t idx1, idx2;
1356 for( int i=0; i<nx; ++i )
1357 {
1358 for( int j=0; j<ny; ++j )
1359 {
1360 for( int k=0; k<nz; ++k )
1361 {
1362 if( i%2 == 0 )
1363 {
1364 idx1 = i/2+j*(nx/2)+k*(nx/2)*ny;
1365 idx2 = i+j*nx+k*nx*ny;
1366 //complex data in format [amp, phase, amp, phase...]
1367 edata[idx1] = data[idx2];
1368 }
1369 }
1370 }
1371 }
1372 }
1373
1374 e->set_complex(false);
1375 if(e->get_ysize()==1 && e->get_zsize()==1) {
1376 e->set_complex_x(false);
1377 }
1378 e->update();
1379 return e;
1380
1381 EXITFUNC;
1382}
1383
1385{
1386 ENTERFUNC;
1387
1388 EMData * e = new EMData();
1389
1390 if( is_real() ) {
1391 delete e;
1392 throw InvalidCallException("No imaginary part for a real image, this function call require a complex image.");
1393 }
1394 else {
1395 if(is_ri()) {
1396 delete e;
1397 throw InvalidCallException("This image is in real/imaginary format, this function call require a complex image in amplitude/phase format.");
1398 }
1399
1400 int nx = get_xsize();
1401 int ny = get_ysize();
1402 int nz = get_zsize();
1403 e->set_size(nx/2, ny, nz);
1404 float * edata = e->get_data();
1405 float * data = get_data();
1406 size_t idx1, idx2;
1407 for( int i=0; i<nx; ++i ) {
1408 for( int j=0; j<ny; ++j ) {
1409 for( int k=0; k<nz; ++k ) {
1410 if( i%2 == 1 ) {
1411 idx1 = i/2+j*(nx/2)+k*(nx/2)*ny;
1412 idx2 = i+j*nx+k*nx*ny;
1413 //complex data in format [real, complex, real, complex...]
1414 edata[idx1] = data[idx2];
1415 }
1416 }
1417 }
1418 }
1419 }
1420
1421 e->set_complex(false);
1422 if(e->get_ysize()==1 && e->get_zsize()==1) {
1423 e->set_complex_x(false);
1424 }
1425 e->update();
1426 return e;
1427
1428 EXITFUNC;
1429}
1430
1431EMData * EMData::real2complex(const float img) const
1432{
1433 ENTERFUNC;
1434
1435 if( is_complex() ) {
1436 throw InvalidCallException("This function call only apply to real image");
1437 }
1438
1439 EMData * e = new EMData();
1440 int nx = get_xsize();
1441 int ny = get_ysize();
1442 int nz = get_zsize();
1443 e->set_size(nx*2, ny, nz);
1444
1445 for( int k=0; k<nz; ++k ) {
1446 for( int j=0; j<ny; ++j ) {
1447 for( int i=0; i<nx; ++i ) {
1448 (*e)(i*2,j,k) = (*this)(i,j,k);
1449 (*e)(i*2+1,j,k) = img;
1450 }
1451 }
1452 }
1453
1454 e->set_complex(true);
1455 if(e->get_ysize()==1 && e->get_zsize()==1) {
1456 e->set_complex_x(true);
1457 }
1458 e->set_ri(true);
1459 e->update();
1460 return e;
1461
1462 EXITFUNC;
1463}
1464
1466{
1467 ENTERFUNC;
1468
1469 if (is_complex()) {
1470 set_ri(true);
1471 }
1472 else {
1473 set_ri(false);
1474 }
1475
1476 //EMUtil::em_memset(get_data(), 0, nxyz * sizeof(float));
1477 to_value(0.0);
1478 update();
1479 EXITFUNC;
1480}
1481
1483{
1484 ENTERFUNC;
1485
1486 if (is_complex()) {
1487 set_ri(true);
1488 }
1489 else {
1490 set_ri(false);
1491 }
1492 to_value(1.0);
1493
1494 update();
1495 EXITFUNC;
1496}
1497
1498void EMData::to_value(const float& value)
1499{
1500 ENTERFUNC;
1501
1502#ifdef EMAN2_USING_CUDA
1503 if(EMData::usecuda == 1 && cudarwdata){
1504 to_value_cuda(cudarwdata, value, nx, ny, nz);
1505 return;
1506 }
1507#endif // EMAN2_USING_CUDA
1508 float* data = get_data();
1509
1510 //the em_memset has segfault for >8GB image, use std::fill() instead, though may be slower
1511// if ( value != 0 ) std::fill(data,data+get_size(),value);
1512// else EMUtil::em_memset(data, 0, nxyz * sizeof(float)); // This might be faster, I don't know
1513
1514 std::fill(data,data+get_size(),value);
1515
1516 update();
1517 EXITFUNC;
1518}
1519
1520
Use dot product of 2 same-size images to do the comparison.
Definition: cmp.h:269
float cmp(EMData *image, EMData *with) const
To compare 'image' with another image passed in through its parameters.
Definition: cmp.cpp:417
EMData stores an image's data and defines core image processing routines.
Definition: emdata.h:82
int pathnum
Definition: emdata.h:858
EMData * rot_fp
This is a cached rotational footprint, can save much time.
Definition: emdata.h:861
EMData()
For all image I/O.
Definition: emdata.cpp:70
float * supp
supplementary data array
Definition: emdata.h:837
float * rdata
image real data
Definition: emdata.h:835
Dict attr_dict
to store all image header info
Definition: emdata.h:833
string path
Definition: emdata.h:857
int nx
image size
Definition: emdata.h:848
int flags
CTF data All CTF data become attribute ctf(vector<float>) in attr_dict –Grant Tang.
Definition: emdata.h:844
Vec3f all_translation
translation from the original location
Definition: emdata.h:854
size_t nxyz
Definition: emdata.h:849
static void em_free(void *data)
Definition: emutil.h:380
static int fast_floor(float x)
A fast way to calculate a floor, which is largest integral value not greater than argument.
Definition: util.h:874
static std::complex< float > gauss3_interpolate_cmplx(std::complex< float > *p, float t, float u)
Calculate 3x3 Gaussian interpolation.
Definition: util.h:589
static std::complex< float > gauss_interpolate_cmplx(std::complex< float > p1, std::complex< float > p2, std::complex< float > p3, std::complex< float > p4, float t, float u)
Calculate 2x2 Gaussian interpolation.
Definition: util.h:573
static std::complex< float > bilinear_interpolate_cmplx(std::complex< float > p1, std::complex< float > p2, std::complex< float > p3, std::complex< float > p4, float t, float u)
Calculate bilinear interpolation.
Definition: util.h:558
static float trilinear_interpolate(float p1, float p2, float p3, float p4, float p5, float p6, float p7, float p8, float t, float u, float v)
Calculate trilinear interpolation.
Definition: util.h:619
static int get_min(int f1, int f2)
Get the minimum of 2 numbers.
Definition: util.h:922
static float bilinear_interpolate(float p1, float p2, float p3, float p4, float t, float u)
Calculate bilinear interpolation.
Definition: util.h:543
float get_value_at_wrap_cuda(float *data, int tx, int ty, int tz, int nx, int ny, int nz)
void emdata_processor_mult(float *data, const float &mult, const int nx, const int ny, const int nz)
void subtract_cuda(float *data, float f, const int nx, const int ny, const int nz)
void to_value_cuda(float *data, const float value, const int nx, const int ny, const int nz)
void addsquare(const EMData &image)
add the squared value of each pixel from a same-size image to this image.
float sget_value_at_interp(float x, float y) const
Get pixel density value at interpolation of (x,y).
void set_value_at_index(size_t i, float v)
Set the pixel density value at index.
Definition: emdata_core.h:621
std::complex< float > get_complex_at_interp(float x, float y) const
Gets bilinear interpolated complex values.
EMData * copy() const
This file is a part of "emdata.h", to use functions in this file, you should "#include "emdata....
size_t add_complex_at(const int &x, const int &y, const int &z, const std::complex< float > &val)
Add complex<float> value at x,y,z.
void to_zero()
Set all the pixel value = 0.
EMData & operator+=(float n)
size_t get_complex_index(const int &x, const int &y, const int &z) const
Get complex<float> index for coords x,y,z.
EMData * get_col(int col_index) const
Get one column of a 2D images.
EMData * log() const
return natural logarithm image for a image
void mult(int n)
multiply an integer number to each pixel value of the image.
Definition: emdata_core.h:97
EMData * absi() const
For a real image, it returns a same size image with abs() of each pixel.
void to_value(const float &value)
set all the pixel values to a value.
EMData * power(int n) const
return a image to the power of n
float get_value_at_wrap(int x, int y, int z) const
Get the pixel density value at coordinates (x,y,z).
void add(float f, int keepzero=0)
add a number to each pixel value of the image.
void sub(float f)
subtract a float number to each pixel value of the image.
EMData * sqrt() const
return square root of current image
void to_one()
set all the pixel values = 1.
EMData * real2complex(float img=0.0f) const
create a complex image from a real image, this complex image is in real/imaginary format
float sget_value_at(Vec3i v)
Vec3i version of save routines below.
Definition: emdata_core.h:465
EMData * log10() const
return base 10 logarithm image for a image
float dot(EMData *with)
Dot product 2 images.
EMData * amplitude() const
return amplitude part of a complex image as a real image format
void set_row(const EMData *data, int row_index)
Set one row of a 1D/2D image.
void mult_ri(const EMData &image)
multiply each complex RI pixel of this image with each pixel of some other same-size image.
EMData * imag() const
return imaginary part of a complex image as a real image format.
std::complex< float > get_complex_at_3ginterp(float x, float y) const
Gets 3x3 Gaussian interpolated complex values note that with Gaussian interpolation,...
float get_value_at_index(size_t i) const
Get the pixel density value at index i.
Definition: emdata_core.h:229
void set_complex_at(const int &x, const int &y, const std::complex< float > &val)
Set complex<float> value at x,y.
void free_memory()
Free memory associated with this EMData Called in destructor and in assignment operator.
EMData * real() const
return real part of a complex image as a real image format, if this image is a real image,...
void mult_complex_efficient(const EMData &em, const int radius)
std::complex< float > get_complex_at(const int &x, const int &y) const
Get complex<float> value at x,y.
void subsquare(const EMData &image)
subtract the squared value of each pixel from a same-size image to this image.
EMData & operator*=(float n)
void update_min(const EMData &image)
Replaces the value of each pixel with the minimum of the current value and the value in the provided ...
EMData * phase() const
return phase part of a complex image as a real image format
void div(float f)
make each pixel value divided by a float number.
EMData * copy_head() const
Make an image with a copy of the current image's header.
std::complex< float > get_complex_at_ginterp(float x, float y) const
Gets 2x2 Gaussian interpolated complex values note that with Gaussian interpolation,...
void free_rdata()
Free rdata memory associated with this EMData Called in CUDA.
Definition: emdata_core.cpp:79
void set_col(const EMData *data, int col_index)
Set one column of a 2D image.
EMData & operator/=(float n)
EMData & operator-=(float n)
EMData * get_row(int row_index) const
Get one row of a 1D/2D image.
bool is_real() const
Is this a real image?
int get_ysize() const
Get the image y-dimensional size.
void set_ri(bool is_ri)
Mark this image as a real/imaginary format complex image.
bool is_ri() const
Is this image a real/imaginary format complex image?
bool is_complex() const
Is this a complex image?
int get_zsize() const
Get the image z-dimensional size.
int get_xsize() const
Get the image x-dimensional size.
int get_ndim() const
Get image dimension.
void update()
Mark EMData as changed, statistics, etc will be updated at need.
float * get_data() const
Get the image pixel density data in a 1D float array.
size_t get_size() const
Get the number of allocated floats in the image (nx*ny*nz)
void ap2ri()
convert the complex image from amplitude/phase to real/imaginary
#define InvalidValueException(val, desc)
Definition: exception.h:285
#define ImageFormatException(desc)
Definition: exception.h:147
#define ImageDimensionException(desc)
Definition: exception.h:166
#define InvalidCallException(desc)
Definition: exception.h:348
#define NullPointerException(desc)
Definition: exception.h:241
#define LOGERR
Definition: log.h:51
#define ENTERFUNC
Definition: log.h:48
#define EXITFUNC
Definition: log.h:49
E2Exception class.
Definition: aligner.h:40
#define y(i, j)
Definition: projector.cpp:1516
#define x(i)
Definition: projector.cpp:1517