#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 4754 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 4774 of file processor.h.
04775 { 04776 return "Translates the origin in Fourier space from the corner to the center in y and z - works in 2D and 3D"; 04777 }
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 4764 of file processor.h.
References NAME.
04765 { 04766 return NAME; 04767 }
static Processor* EMAN::FourierToCenterProcessor::NEW | ( | ) | [inline, static] |
Definition at line 4769 of file processor.h.
04770 { 04771 return new FourierToCenterProcessor(); 04772 }
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 4608 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.
04609 { 04610 // if ( !image->is_complex() ) throw ImageFormatException("Can not Fourier origin shift an image that is not complex"); 04611 04612 int nx=image->get_xsize(); 04613 int ny=image->get_ysize(); 04614 int nz=image->get_zsize(); 04615 04616 int nxy = nx*ny; 04617 04618 if ( ny == 1 && nz == 1 ){ 04619 cout << "Warning- attempted Fourier origin shift a 1D image - no action taken" << endl; 04620 return; 04621 } 04622 04623 int yodd = (ny%2==1); 04624 int zodd = (nz%2==1); 04625 04626 float* rdata = image->get_data(); 04627 04628 float tmp[2]; 04629 float* p1; 04630 float* p2; 04631 04632 // This will tackle the 'normalization' images which come out of the Fourier reconstructor. 04633 // ie- real-space 1/2 FFt images centered on the corner 04634 if ( !image->is_complex() ) { 04635 if (nz!=1 && !yodd && !zodd) { 04636 for (int x=0; x<nx; x++) { 04637 for (int y=0; y<ny; y++) { 04638 for (int z=0; z<nz/2; z++) { 04639 int y2=(y+ny/2)%ny; 04640 int z2=(z+nz/2)%nz; // %nz should be redundant here 04641 size_t i=x+y*nx+z*nxy; 04642 size_t i2=x+y2*nx+z2*nxy; 04643 float swp=rdata[i]; 04644 rdata[i]=rdata[i2]; 04645 rdata[i2]=swp; 04646 } 04647 } 04648 } 04649 04650 return; 04651 } 04652 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"); 04653 } 04654 04655 if (yodd){ 04656 // In 3D this is swapping the bottom slice (with respect to the y direction) and the middle slice, 04657 // shifting all slices below the middle slice down one. In 2D it is equivalent, but in terms of rows. 04658 float prev[2]; 04659 size_t idx; 04660 for( int s = 0; s < nz; s++ ) { 04661 for( int c =0; c < nx; c += 2 ) { 04662 idx = s*nxy+c; 04663 prev[0] = rdata[idx]; 04664 prev[1] = rdata[idx+1]; 04665 for( int r = ny/2; r >= 0; --r ) { 04666 idx = s*nxy+r*nx+c; 04667 float* p1 = &rdata[idx]; 04668 tmp[0] = p1[0]; 04669 tmp[1] = p1[1]; 04670 04671 p1[0] = prev[0]; 04672 p1[1] = prev[1]; 04673 04674 prev[0] = tmp[0]; 04675 prev[1] = tmp[1]; 04676 } 04677 } 04678 } 04679 } 04680 04681 // 3D - Shift slices correctly in the y direction, 2D - shift rows 04682 size_t idx1, idx2; 04683 for( int s = 0; s < nz; ++s ) { 04684 for( int r = 0; r < ny/2; ++r ) { 04685 for( int c =0; c < nx; c += 2 ) { 04686 idx1 = s*nxy+r*nx+c; 04687 idx2 = s*nxy+(r+ny/2+yodd)*nx+c; 04688 p1 = &rdata[idx1]; 04689 p2 = &rdata[idx2]; 04690 04691 tmp[0] = p1[0]; 04692 tmp[1] = p1[1]; 04693 04694 p1[0] = p2[0]; 04695 p1[1] = p2[1]; 04696 04697 p2[0] = tmp[0]; 04698 p2[1] = tmp[1]; 04699 } 04700 } 04701 } 04702 04703 if ( nz != 1 ) { 04704 if (zodd){ 04705 // Swap the front slice (with respect to the z direction) and the middle slice 04706 // shifting all slices behind the middles slice towards the front slice 1 voxel. 04707 float prev[2]; 04708 size_t idx; 04709 for( int r = 0; r < ny; ++r ) { 04710 for( int c =0; c < nx; c += 2 ) { 04711 prev[0] = rdata[r*nx+c]; 04712 prev[1] = rdata[r*nx+c+1]; 04713 for( int s = nz/2; s >= 0; --s ) { 04714 idx = s*nxy+r*nx+c; 04715 float* p1 = &rdata[idx]; 04716 tmp[0] = p1[0]; 04717 tmp[1] = p1[1]; 04718 04719 p1[0] = prev[0]; 04720 p1[1] = prev[1]; 04721 04722 prev[0] = tmp[0]; 04723 prev[1] = tmp[1]; 04724 } 04725 } 04726 } 04727 } 04728 04729 // Shift slices correctly in the y direction 04730 size_t idx1, idx2; 04731 for( int s = 0; s < nz/2; ++s ) { 04732 for( int r = 0; r < ny; ++r ) { 04733 for( int c =0; c < nx; c += 2 ) { 04734 idx1 = s*nxy+r*nx+c; 04735 idx2 = (s+nz/2+zodd)*nxy+r*nx+c; 04736 p1 = &rdata[idx1]; 04737 p2 = &rdata[idx2]; 04738 04739 tmp[0] = p1[0]; 04740 tmp[1] = p1[1]; 04741 04742 p1[0] = p2[0]; 04743 p1[1] = p2[1]; 04744 04745 p2[0] = tmp[0]; 04746 p2[1] = tmp[1]; 04747 } 04748 } 04749 } 04750 } 04751 image->set_shuffled(true); 04752 }
const string FourierToCenterProcessor::NAME = "xform.fourierorigin.tocenter" [static] |