EMAN2
Public Member Functions | Static Public Member Functions | Static Public Attributes
EMAN::FourierToCenterProcessor Class Reference

Translates the origin in Fourier space from the corner to the center in y and z Handles 2D and 3D, and handles all combinations of even and oddness Typically you call this function after Fourier transforming a real space image. More...

#include <processor.h>

Inheritance diagram for EMAN::FourierToCenterProcessor:
Inheritance graph
[legend]
Collaboration diagram for EMAN::FourierToCenterProcessor:
Collaboration graph
[legend]

List of all members.

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 ProcessorNEW ()

Static Public Attributes

static const string NAME = "xform.fourierorigin.tocenter"

Detailed Description

Translates the origin in Fourier space from the corner to the center in y and z Handles 2D and 3D, and handles all combinations of even and oddness Typically you call this function after Fourier transforming a real space image.

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

Author:
David Woolford <woolford@bcm.edu>
Date:
October 2007

Definition at line 5048 of file processor.h.


Member Function Documentation

virtual string EMAN::FourierToCenterProcessor::get_desc ( ) const [inline, virtual]

Get the descrition of this specific processor.

This function must be overwritten by a subclass.

Returns:
The description of this processor.

Implements EMAN::Processor.

Definition at line 5068 of file processor.h.

                        {
                                return "Translates the origin in Fourier space from the corner to the center in y and z - works in 2D and 3D";
                        }
virtual string EMAN::FourierToCenterProcessor::get_name ( ) const [inline, virtual]

Get the processor's name.

Each processor is identified by a unique name.

Returns:
The processor's name.

Implements EMAN::Processor.

Definition at line 5058 of file processor.h.

References NAME.

                        {
                                return NAME;
                        }
static Processor* EMAN::FourierToCenterProcessor::NEW ( ) [inline, static]

Definition at line 5063 of file processor.h.

                        {
                                return new FourierToCenterProcessor();
                        }
void FourierToCenterProcessor::process_inplace ( EMData image) [virtual]

Fourier origin shift the image in the forward direction.

Parameters:
imagethe image to operate on
Exceptions:
ImageFormatExceptionif the image is not complex

Implements EMAN::Processor.

Definition at line 4865 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(), and x.

{
//      if ( !image->is_complex() ) throw ImageFormatException("Can not Fourier origin shift an image that is not complex");

        int nx=image->get_xsize();
        int ny=image->get_ysize();
        int nz=image->get_zsize();

        int nxy = nx*ny;

        if ( ny == 1 && nz == 1 ){
                cout << "Warning- attempted     Fourier origin shift a 1D image - no action taken" << endl;
                return;
        }

        int yodd = (ny%2==1);
        int zodd = (nz%2==1);

        float* rdata = image->get_data();

        float tmp[2];
        float* p1;
        float* p2;

        // This will tackle the 'normalization' images which come out of the Fourier reconstructor.
        // ie- real-space 1/2 FFt images centered on the corner
        if ( !image->is_complex() ) {
                if (nz!=1 && !yodd && !zodd) {
                        for (int x=0; x<nx; x++) {
                                for (int y=0; y<ny; y++) {
                                        for (int z=0; z<nz/2; z++) {
                                                int y2=(y+ny/2)%ny;
                                                int z2=(z+nz/2)%nz;             // %nz should be redundant here
                                                size_t i=x+y*nx+(size_t)z*nxy;
                                                size_t i2=x+y2*nx+(size_t)z2*nxy;
                                                float swp=rdata[i];
                                                rdata[i]=rdata[i2];
                                                rdata[i2]=swp;
                                        }
                                }
                        }

                        return;
                }
                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");
        }

        if (yodd){
                // In 3D this is swapping the bottom slice (with respect to the y direction) and the middle slice,
                // shifting all slices below the middle slice down one. In 2D it is equivalent, but in terms of rows.
                float prev[2];
                size_t idx;
                for( int s = 0; s < nz; s++ ) {
                        for( int c =0; c < nx; c += 2 ) {
                                idx = (size_t)s*nxy+c;
                                prev[0] = rdata[idx];
                                prev[1] = rdata[idx+1];
                                for( int r = ny/2; r >= 0; --r ) {
                                        idx = (size_t)s*nxy+r*nx+c;
                                        float* p1 = &rdata[idx];
                                        tmp[0] = p1[0];
                                        tmp[1] = p1[1];

                                        p1[0] = prev[0];
                                        p1[1] = prev[1];

                                        prev[0] = tmp[0];
                                        prev[1] = tmp[1];
                                }
                        }
                }
        }

        // 3D - Shift slices correctly in the y direction, 2D - shift rows
        size_t idx1, idx2;
        for( int s = 0; s < nz; ++s ) {
                for( int r = 0; r < ny/2; ++r ) {
                        for( int c =0; c < nx; c += 2 ) {
                                idx1 = (size_t)s*nxy+r*nx+c;
                                idx2 = (size_t)s*nxy+(r+ny/2+yodd)*nx+c;
                                p1 = &rdata[idx1];
                                p2 = &rdata[idx2];

                                tmp[0] = p1[0];
                                tmp[1] = p1[1];

                                p1[0] = p2[0];
                                p1[1] = p2[1];

                                p2[0] = tmp[0];
                                p2[1] = tmp[1];
                        }
                }
        }

        if ( nz != 1 )  {
                if (zodd){
                        // Swap the front slice (with respect to the z direction) and the middle slice
                        // shifting all slices behind the middles slice towards the front slice 1 voxel.
                        float prev[2];
                        size_t idx;
                        for( int r = 0; r < ny; ++r ) {
                                for( int c =0; c < nx; c += 2 ) {
                                        prev[0] = rdata[r*nx+c];
                                        prev[1] = rdata[r*nx+c+1];
                                        for( int s = nz/2; s >= 0; --s ) {
                                                idx = (size_t)s*nxy+r*nx+c;
                                                float* p1 = &rdata[idx];
                                                tmp[0] = p1[0];
                                                tmp[1] = p1[1];

                                                p1[0] = prev[0];
                                                p1[1] = prev[1];

                                                prev[0] = tmp[0];
                                                prev[1] = tmp[1];
                                        }
                                }
                        }
                }

                // Shift slices correctly in the y direction
                size_t idx1, idx2;
                for( int s = 0; s < nz/2; ++s ) {
                        for( int r = 0; r < ny; ++r ) {
                                for( int c =0; c < nx; c += 2 ) {
                                        idx1 = (size_t)s*nxy+r*nx+c;
                                        idx2 = (size_t)(s+nz/2+zodd)*nxy+r*nx+c;
                                        p1 = &rdata[idx1];
                                        p2 = &rdata[idx2];

                                        tmp[0] = p1[0];
                                        tmp[1] = p1[1];

                                        p1[0] = p2[0];
                                        p1[1] = p2[1];

                                        p2[0] = tmp[0];
                                        p2[1] = tmp[1];
                                }
                        }
                }
        }
        image->set_shuffled(true);
}

Member Data Documentation

const string FourierToCenterProcessor::NAME = "xform.fourierorigin.tocenter" [static]

Definition at line 5073 of file processor.h.

Referenced by get_name().


The documentation for this class was generated from the following files: