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