#include <processor.h>
Inheritance diagram for EMAN::FourierToCenterProcessor:
Public Member Functions | |
virtual void | process_inplace (EMData *image) |
Fourier origin shift the image in the forward direction. | |
virtual string | get_name () const |
Get the processor's name. | |
virtual string | get_desc () const |
Get the descrition of this specific processor. | |
Static Public Member Functions | |
Processor * | NEW () |
Static Public Attributes | |
const string | NAME = "xform.fourierorigin.tocenter" |
After this you operate on the Fourier image in convenient format, then you call FourierToCornerProcessor (above) and then inverse FT to get to the original image
Definition at line 4717 of file processor.h.
|
Get the descrition of this specific processor. This function must be overwritten by a subclass.
Implements EMAN::Processor. Definition at line 4737 of file processor.h. 04738 { 04739 return "Translates the origin in Fourier space from the corner to the center in y and z - works in 2D and 3D"; 04740 }
|
|
Get the processor's name. Each processor is identified by a unique name.
Implements EMAN::Processor. Definition at line 4727 of file processor.h. 04728 {
04729 return NAME;
04730 }
|
|
Definition at line 4732 of file processor.h. 04733 { 04734 return new FourierToCenterProcessor(); 04735 }
|
|
Fourier origin shift the image in the forward direction.
Implements EMAN::Processor. Definition at line 4558 of file processor.cpp. References EMAN::EMData::get_data(), EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::EMData::get_zsize(), ImageFormatException, EMAN::EMData::is_complex(), nx, ny, rdata, EMAN::EMData::set_shuffled(), x, and y. 04559 { 04560 // if ( !image->is_complex() ) throw ImageFormatException("Can not Fourier origin shift an image that is not complex"); 04561 04562 int nx=image->get_xsize(); 04563 int ny=image->get_ysize(); 04564 int nz=image->get_zsize(); 04565 04566 int nxy = nx*ny; 04567 04568 if ( ny == 1 && nz == 1 ){ 04569 cout << "Warning- attempted Fourier origin shift a 1D image - no action taken" << endl; 04570 return; 04571 } 04572 04573 int yodd = (ny%2==1); 04574 int zodd = (nz%2==1); 04575 04576 float* rdata = image->get_data(); 04577 04578 float tmp[2]; 04579 float* p1; 04580 float* p2; 04581 04582 // This will tackle the 'normalization' images which come out of the Fourier reconstructor. 04583 // ie- real-space 1/2 FFt images centered on the corner 04584 if ( !image->is_complex() ) { 04585 if (nz!=1 && !yodd && !zodd) { 04586 for (int x=0; x<nx; x++) { 04587 for (int y=0; y<ny; y++) { 04588 for (int z=0; z<nz/2; z++) { 04589 int y2=(y+ny/2)%ny; 04590 int z2=(z+nz/2)%nz; // %nz should be redundant here 04591 size_t i=x+y*nx+(size_t)z*nxy; 04592 size_t i2=x+y2*nx+(size_t)z2*nxy; 04593 float swp=rdata[i]; 04594 rdata[i]=rdata[i2]; 04595 rdata[i2]=swp; 04596 } 04597 } 04598 } 04599 04600 return; 04601 } 04602 else throw ImageFormatException("Can not Fourier origin shift an image that is not complex unless it is even in ny,nz and nx=ny/2+1"); 04603 } 04604 04605 if (yodd){ 04606 // In 3D this is swapping the bottom slice (with respect to the y direction) and the middle slice, 04607 // shifting all slices below the middle slice down one. In 2D it is equivalent, but in terms of rows. 04608 float prev[2]; 04609 size_t idx; 04610 for( int s = 0; s < nz; s++ ) { 04611 for( int c =0; c < nx; c += 2 ) { 04612 idx = (size_t)s*nxy+c; 04613 prev[0] = rdata[idx]; 04614 prev[1] = rdata[idx+1]; 04615 for( int r = ny/2; r >= 0; --r ) { 04616 idx = (size_t)s*nxy+r*nx+c; 04617 float* p1 = &rdata[idx]; 04618 tmp[0] = p1[0]; 04619 tmp[1] = p1[1]; 04620 04621 p1[0] = prev[0]; 04622 p1[1] = prev[1]; 04623 04624 prev[0] = tmp[0]; 04625 prev[1] = tmp[1]; 04626 } 04627 } 04628 } 04629 } 04630 04631 // 3D - Shift slices correctly in the y direction, 2D - shift rows 04632 size_t idx1, idx2; 04633 for( int s = 0; s < nz; ++s ) { 04634 for( int r = 0; r < ny/2; ++r ) { 04635 for( int c =0; c < nx; c += 2 ) { 04636 idx1 = (size_t)s*nxy+r*nx+c; 04637 idx2 = (size_t)s*nxy+(r+ny/2+yodd)*nx+c; 04638 p1 = &rdata[idx1]; 04639 p2 = &rdata[idx2]; 04640 04641 tmp[0] = p1[0]; 04642 tmp[1] = p1[1]; 04643 04644 p1[0] = p2[0]; 04645 p1[1] = p2[1]; 04646 04647 p2[0] = tmp[0]; 04648 p2[1] = tmp[1]; 04649 } 04650 } 04651 } 04652 04653 if ( nz != 1 ) { 04654 if (zodd){ 04655 // Swap the front slice (with respect to the z direction) and the middle slice 04656 // shifting all slices behind the middles slice towards the front slice 1 voxel. 04657 float prev[2]; 04658 size_t idx; 04659 for( int r = 0; r < ny; ++r ) { 04660 for( int c =0; c < nx; c += 2 ) { 04661 prev[0] = rdata[r*nx+c]; 04662 prev[1] = rdata[r*nx+c+1]; 04663 for( int s = nz/2; s >= 0; --s ) { 04664 idx = (size_t)s*nxy+r*nx+c; 04665 float* p1 = &rdata[idx]; 04666 tmp[0] = p1[0]; 04667 tmp[1] = p1[1]; 04668 04669 p1[0] = prev[0]; 04670 p1[1] = prev[1]; 04671 04672 prev[0] = tmp[0]; 04673 prev[1] = tmp[1]; 04674 } 04675 } 04676 } 04677 } 04678 04679 // Shift slices correctly in the y direction 04680 size_t idx1, idx2; 04681 for( int s = 0; s < nz/2; ++s ) { 04682 for( int r = 0; r < ny; ++r ) { 04683 for( int c =0; c < nx; c += 2 ) { 04684 idx1 = (size_t)s*nxy+r*nx+c; 04685 idx2 = (size_t)(s+nz/2+zodd)*nxy+r*nx+c; 04686 p1 = &rdata[idx1]; 04687 p2 = &rdata[idx2]; 04688 04689 tmp[0] = p1[0]; 04690 tmp[1] = p1[1]; 04691 04692 p1[0] = p2[0]; 04693 p1[1] = p2[1]; 04694 04695 p2[0] = tmp[0]; 04696 p2[1] = tmp[1]; 04697 } 04698 } 04699 } 04700 } 04701 image->set_shuffled(true); 04702 }
|
|
Definition at line 168 of file processor.cpp. |