#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 4748 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 4768 of file processor.h.
04769 { 04770 return "Translates the origin in Fourier space from the corner to the center in y and z - works in 2D and 3D"; 04771 }
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 4758 of file processor.h.
References NAME.
04759 { 04760 return NAME; 04761 }
static Processor* EMAN::FourierToCenterProcessor::NEW | ( | ) | [inline, static] |
Definition at line 4763 of file processor.h.
04764 { 04765 return new FourierToCenterProcessor(); 04766 }
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 4573 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.
04574 { 04575 // if ( !image->is_complex() ) throw ImageFormatException("Can not Fourier origin shift an image that is not complex"); 04576 04577 int nx=image->get_xsize(); 04578 int ny=image->get_ysize(); 04579 int nz=image->get_zsize(); 04580 04581 int nxy = nx*ny; 04582 04583 if ( ny == 1 && nz == 1 ){ 04584 cout << "Warning- attempted Fourier origin shift a 1D image - no action taken" << endl; 04585 return; 04586 } 04587 04588 int yodd = (ny%2==1); 04589 int zodd = (nz%2==1); 04590 04591 float* rdata = image->get_data(); 04592 04593 float tmp[2]; 04594 float* p1; 04595 float* p2; 04596 04597 // This will tackle the 'normalization' images which come out of the Fourier reconstructor. 04598 // ie- real-space 1/2 FFt images centered on the corner 04599 if ( !image->is_complex() ) { 04600 if (nz!=1 && !yodd && !zodd) { 04601 for (int x=0; x<nx; x++) { 04602 for (int y=0; y<ny; y++) { 04603 for (int z=0; z<nz/2; z++) { 04604 int y2=(y+ny/2)%ny; 04605 int z2=(z+nz/2)%nz; // %nz should be redundant here 04606 size_t i=x+y*nx+(size_t)z*nxy; 04607 size_t i2=x+y2*nx+(size_t)z2*nxy; 04608 float swp=rdata[i]; 04609 rdata[i]=rdata[i2]; 04610 rdata[i2]=swp; 04611 } 04612 } 04613 } 04614 04615 return; 04616 } 04617 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"); 04618 } 04619 04620 if (yodd){ 04621 // In 3D this is swapping the bottom slice (with respect to the y direction) and the middle slice, 04622 // shifting all slices below the middle slice down one. In 2D it is equivalent, but in terms of rows. 04623 float prev[2]; 04624 size_t idx; 04625 for( int s = 0; s < nz; s++ ) { 04626 for( int c =0; c < nx; c += 2 ) { 04627 idx = (size_t)s*nxy+c; 04628 prev[0] = rdata[idx]; 04629 prev[1] = rdata[idx+1]; 04630 for( int r = ny/2; r >= 0; --r ) { 04631 idx = (size_t)s*nxy+r*nx+c; 04632 float* p1 = &rdata[idx]; 04633 tmp[0] = p1[0]; 04634 tmp[1] = p1[1]; 04635 04636 p1[0] = prev[0]; 04637 p1[1] = prev[1]; 04638 04639 prev[0] = tmp[0]; 04640 prev[1] = tmp[1]; 04641 } 04642 } 04643 } 04644 } 04645 04646 // 3D - Shift slices correctly in the y direction, 2D - shift rows 04647 size_t idx1, idx2; 04648 for( int s = 0; s < nz; ++s ) { 04649 for( int r = 0; r < ny/2; ++r ) { 04650 for( int c =0; c < nx; c += 2 ) { 04651 idx1 = (size_t)s*nxy+r*nx+c; 04652 idx2 = (size_t)s*nxy+(r+ny/2+yodd)*nx+c; 04653 p1 = &rdata[idx1]; 04654 p2 = &rdata[idx2]; 04655 04656 tmp[0] = p1[0]; 04657 tmp[1] = p1[1]; 04658 04659 p1[0] = p2[0]; 04660 p1[1] = p2[1]; 04661 04662 p2[0] = tmp[0]; 04663 p2[1] = tmp[1]; 04664 } 04665 } 04666 } 04667 04668 if ( nz != 1 ) { 04669 if (zodd){ 04670 // Swap the front slice (with respect to the z direction) and the middle slice 04671 // shifting all slices behind the middles slice towards the front slice 1 voxel. 04672 float prev[2]; 04673 size_t idx; 04674 for( int r = 0; r < ny; ++r ) { 04675 for( int c =0; c < nx; c += 2 ) { 04676 prev[0] = rdata[r*nx+c]; 04677 prev[1] = rdata[r*nx+c+1]; 04678 for( int s = nz/2; s >= 0; --s ) { 04679 idx = (size_t)s*nxy+r*nx+c; 04680 float* p1 = &rdata[idx]; 04681 tmp[0] = p1[0]; 04682 tmp[1] = p1[1]; 04683 04684 p1[0] = prev[0]; 04685 p1[1] = prev[1]; 04686 04687 prev[0] = tmp[0]; 04688 prev[1] = tmp[1]; 04689 } 04690 } 04691 } 04692 } 04693 04694 // Shift slices correctly in the y direction 04695 size_t idx1, idx2; 04696 for( int s = 0; s < nz/2; ++s ) { 04697 for( int r = 0; r < ny; ++r ) { 04698 for( int c =0; c < nx; c += 2 ) { 04699 idx1 = (size_t)s*nxy+r*nx+c; 04700 idx2 = (size_t)(s+nz/2+zodd)*nxy+r*nx+c; 04701 p1 = &rdata[idx1]; 04702 p2 = &rdata[idx2]; 04703 04704 tmp[0] = p1[0]; 04705 tmp[1] = p1[1]; 04706 04707 p1[0] = p2[0]; 04708 p1[1] = p2[1]; 04709 04710 p2[0] = tmp[0]; 04711 p2[1] = tmp[1]; 04712 } 04713 } 04714 } 04715 } 04716 image->set_shuffled(true); 04717 }
const string FourierToCenterProcessor::NAME = "xform.fourierorigin.tocenter" [static] |