#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 | |
static Processor * | NEW () |
Static Public Attributes | |
static 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 4795 of file processor.h.
virtual string EMAN::FourierToCenterProcessor::get_desc | ( | ) | const [inline, virtual] |
Get the descrition of this specific processor.
This function must be overwritten by a subclass.
Implements EMAN::Processor.
Definition at line 4815 of file processor.h.
04816 { 04817 return "Translates the origin in Fourier space from the corner to the center in y and z - works in 2D and 3D"; 04818 }
virtual string EMAN::FourierToCenterProcessor::get_name | ( | ) | const [inline, virtual] |
Get the processor's name.
Each processor is identified by a unique name.
Implements EMAN::Processor.
Definition at line 4805 of file processor.h.
References NAME.
04806 { 04807 return NAME; 04808 }
static Processor* EMAN::FourierToCenterProcessor::NEW | ( | ) | [inline, static] |
Definition at line 4810 of file processor.h.
04811 { 04812 return new FourierToCenterProcessor(); 04813 }
void FourierToCenterProcessor::process_inplace | ( | EMData * | image | ) | [virtual] |
Fourier origin shift the image in the forward direction.
image | the image to operate on |
ImageFormatException | if the image is not complex |
Implements EMAN::Processor.
Definition at line 4651 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(), rdata, EMAN::EMData::set_shuffled(), and x.
04652 { 04653 // if ( !image->is_complex() ) throw ImageFormatException("Can not Fourier origin shift an image that is not complex"); 04654 04655 int nx=image->get_xsize(); 04656 int ny=image->get_ysize(); 04657 int nz=image->get_zsize(); 04658 04659 int nxy = nx*ny; 04660 04661 if ( ny == 1 && nz == 1 ){ 04662 cout << "Warning- attempted Fourier origin shift a 1D image - no action taken" << endl; 04663 return; 04664 } 04665 04666 int yodd = (ny%2==1); 04667 int zodd = (nz%2==1); 04668 04669 float* rdata = image->get_data(); 04670 04671 float tmp[2]; 04672 float* p1; 04673 float* p2; 04674 04675 // This will tackle the 'normalization' images which come out of the Fourier reconstructor. 04676 // ie- real-space 1/2 FFt images centered on the corner 04677 if ( !image->is_complex() ) { 04678 if (nz!=1 && !yodd && !zodd) { 04679 for (int x=0; x<nx; x++) { 04680 for (int y=0; y<ny; y++) { 04681 for (int z=0; z<nz/2; z++) { 04682 int y2=(y+ny/2)%ny; 04683 int z2=(z+nz/2)%nz; // %nz should be redundant here 04684 size_t i=x+y*nx+(size_t)z*nxy; 04685 size_t i2=x+y2*nx+(size_t)z2*nxy; 04686 float swp=rdata[i]; 04687 rdata[i]=rdata[i2]; 04688 rdata[i2]=swp; 04689 } 04690 } 04691 } 04692 04693 return; 04694 } 04695 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"); 04696 } 04697 04698 if (yodd){ 04699 // In 3D this is swapping the bottom slice (with respect to the y direction) and the middle slice, 04700 // shifting all slices below the middle slice down one. In 2D it is equivalent, but in terms of rows. 04701 float prev[2]; 04702 size_t idx; 04703 for( int s = 0; s < nz; s++ ) { 04704 for( int c =0; c < nx; c += 2 ) { 04705 idx = (size_t)s*nxy+c; 04706 prev[0] = rdata[idx]; 04707 prev[1] = rdata[idx+1]; 04708 for( int r = ny/2; r >= 0; --r ) { 04709 idx = (size_t)s*nxy+r*nx+c; 04710 float* p1 = &rdata[idx]; 04711 tmp[0] = p1[0]; 04712 tmp[1] = p1[1]; 04713 04714 p1[0] = prev[0]; 04715 p1[1] = prev[1]; 04716 04717 prev[0] = tmp[0]; 04718 prev[1] = tmp[1]; 04719 } 04720 } 04721 } 04722 } 04723 04724 // 3D - Shift slices correctly in the y direction, 2D - shift rows 04725 size_t idx1, idx2; 04726 for( int s = 0; s < nz; ++s ) { 04727 for( int r = 0; r < ny/2; ++r ) { 04728 for( int c =0; c < nx; c += 2 ) { 04729 idx1 = (size_t)s*nxy+r*nx+c; 04730 idx2 = (size_t)s*nxy+(r+ny/2+yodd)*nx+c; 04731 p1 = &rdata[idx1]; 04732 p2 = &rdata[idx2]; 04733 04734 tmp[0] = p1[0]; 04735 tmp[1] = p1[1]; 04736 04737 p1[0] = p2[0]; 04738 p1[1] = p2[1]; 04739 04740 p2[0] = tmp[0]; 04741 p2[1] = tmp[1]; 04742 } 04743 } 04744 } 04745 04746 if ( nz != 1 ) { 04747 if (zodd){ 04748 // Swap the front slice (with respect to the z direction) and the middle slice 04749 // shifting all slices behind the middles slice towards the front slice 1 voxel. 04750 float prev[2]; 04751 size_t idx; 04752 for( int r = 0; r < ny; ++r ) { 04753 for( int c =0; c < nx; c += 2 ) { 04754 prev[0] = rdata[r*nx+c]; 04755 prev[1] = rdata[r*nx+c+1]; 04756 for( int s = nz/2; s >= 0; --s ) { 04757 idx = (size_t)s*nxy+r*nx+c; 04758 float* p1 = &rdata[idx]; 04759 tmp[0] = p1[0]; 04760 tmp[1] = p1[1]; 04761 04762 p1[0] = prev[0]; 04763 p1[1] = prev[1]; 04764 04765 prev[0] = tmp[0]; 04766 prev[1] = tmp[1]; 04767 } 04768 } 04769 } 04770 } 04771 04772 // Shift slices correctly in the y direction 04773 size_t idx1, idx2; 04774 for( int s = 0; s < nz/2; ++s ) { 04775 for( int r = 0; r < ny; ++r ) { 04776 for( int c =0; c < nx; c += 2 ) { 04777 idx1 = (size_t)s*nxy+r*nx+c; 04778 idx2 = (size_t)(s+nz/2+zodd)*nxy+r*nx+c; 04779 p1 = &rdata[idx1]; 04780 p2 = &rdata[idx2]; 04781 04782 tmp[0] = p1[0]; 04783 tmp[1] = p1[1]; 04784 04785 p1[0] = p2[0]; 04786 p1[1] = p2[1]; 04787 04788 p2[0] = tmp[0]; 04789 p2[1] = tmp[1]; 04790 } 04791 } 04792 } 04793 } 04794 image->set_shuffled(true); 04795 }
const string FourierToCenterProcessor::NAME = "xform.fourierorigin.tocenter" [static] |