#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 | |
Processor * | NEW () |
Static Public Attributes | |
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 4679 of file processor.h.
|
Get the descrition of this specific processor. This function must be overwritten by a subclass.
Implements EMAN::Processor. Definition at line 4699 of file processor.h. 04700 { 04701 return "Translates the origin in Fourier space from the corner to the center in y and z - works in 2D and 3D"; 04702 }
|
|
Get the processor's name. Each processor is identified by a unique name.
Implements EMAN::Processor. Definition at line 4689 of file processor.h. 04690 {
04691 return NAME;
04692 }
|
|
Definition at line 4694 of file processor.h. 04695 { 04696 return new FourierToCenterProcessor(); 04697 }
|
|
Fourier origin shift the image in the forward direction.
Implements EMAN::Processor. Definition at line 4530 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(), x, and y. 04531 { 04532 // if ( !image->is_complex() ) throw ImageFormatException("Can not Fourier origin shift an image that is not complex"); 04533 04534 int nx=image->get_xsize(); 04535 int ny=image->get_ysize(); 04536 int nz=image->get_zsize(); 04537 04538 int nxy = nx*ny; 04539 04540 if ( ny == 1 && nz == 1 ){ 04541 cout << "Warning- attempted Fourier origin shift a 1D image - no action taken" << endl; 04542 return; 04543 } 04544 04545 int yodd = (ny%2==1); 04546 int zodd = (nz%2==1); 04547 04548 float* rdata = image->get_data(); 04549 04550 float tmp[2]; 04551 float* p1; 04552 float* p2; 04553 04554 // This will tackle the 'normalization' images which come out of the Fourier reconstructor. 04555 // ie- real-space 1/2 FFt images centered on the corner 04556 if ( !image->is_complex() ) { 04557 if (nz!=1 && !yodd && !zodd) { 04558 for (int x=0; x<nx; x++) { 04559 for (int y=0; y<ny; y++) { 04560 for (int z=0; z<nz/2; z++) { 04561 int y2=(y+ny/2)%ny; 04562 int z2=(z+nz/2)%nz; // %nz should be redundant here 04563 size_t i=x+y*nx+(size_t)z*nxy; 04564 size_t i2=x+y2*nx+(size_t)z2*nxy; 04565 float swp=rdata[i]; 04566 rdata[i]=rdata[i2]; 04567 rdata[i2]=swp; 04568 } 04569 } 04570 } 04571 04572 return; 04573 } 04574 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"); 04575 } 04576 04577 if (yodd){ 04578 // In 3D this is swapping the bottom slice (with respect to the y direction) and the middle slice, 04579 // shifting all slices below the middle slice down one. In 2D it is equivalent, but in terms of rows. 04580 float prev[2]; 04581 size_t idx; 04582 for( int s = 0; s < nz; s++ ) { 04583 for( int c =0; c < nx; c += 2 ) { 04584 idx = (size_t)s*nxy+c; 04585 prev[0] = rdata[idx]; 04586 prev[1] = rdata[idx+1]; 04587 for( int r = ny/2; r >= 0; --r ) { 04588 idx = (size_t)s*nxy+r*nx+c; 04589 float* p1 = &rdata[idx]; 04590 tmp[0] = p1[0]; 04591 tmp[1] = p1[1]; 04592 04593 p1[0] = prev[0]; 04594 p1[1] = prev[1]; 04595 04596 prev[0] = tmp[0]; 04597 prev[1] = tmp[1]; 04598 } 04599 } 04600 } 04601 } 04602 04603 // 3D - Shift slices correctly in the y direction, 2D - shift rows 04604 size_t idx1, idx2; 04605 for( int s = 0; s < nz; ++s ) { 04606 for( int r = 0; r < ny/2; ++r ) { 04607 for( int c =0; c < nx; c += 2 ) { 04608 idx1 = (size_t)s*nxy+r*nx+c; 04609 idx2 = (size_t)s*nxy+(r+ny/2+yodd)*nx+c; 04610 p1 = &rdata[idx1]; 04611 p2 = &rdata[idx2]; 04612 04613 tmp[0] = p1[0]; 04614 tmp[1] = p1[1]; 04615 04616 p1[0] = p2[0]; 04617 p1[1] = p2[1]; 04618 04619 p2[0] = tmp[0]; 04620 p2[1] = tmp[1]; 04621 } 04622 } 04623 } 04624 04625 if ( nz != 1 ) { 04626 if (zodd){ 04627 // Swap the front slice (with respect to the z direction) and the middle slice 04628 // shifting all slices behind the middles slice towards the front slice 1 voxel. 04629 float prev[2]; 04630 size_t idx; 04631 for( int r = 0; r < ny; ++r ) { 04632 for( int c =0; c < nx; c += 2 ) { 04633 prev[0] = rdata[r*nx+c]; 04634 prev[1] = rdata[r*nx+c+1]; 04635 for( int s = nz/2; s >= 0; --s ) { 04636 idx = (size_t)s*nxy+r*nx+c; 04637 float* p1 = &rdata[idx]; 04638 tmp[0] = p1[0]; 04639 tmp[1] = p1[1]; 04640 04641 p1[0] = prev[0]; 04642 p1[1] = prev[1]; 04643 04644 prev[0] = tmp[0]; 04645 prev[1] = tmp[1]; 04646 } 04647 } 04648 } 04649 } 04650 04651 // Shift slices correctly in the y direction 04652 size_t idx1, idx2; 04653 for( int s = 0; s < nz/2; ++s ) { 04654 for( int r = 0; r < ny; ++r ) { 04655 for( int c =0; c < nx; c += 2 ) { 04656 idx1 = (size_t)s*nxy+r*nx+c; 04657 idx2 = (size_t)(s+nz/2+zodd)*nxy+r*nx+c; 04658 p1 = &rdata[idx1]; 04659 p2 = &rdata[idx2]; 04660 04661 tmp[0] = p1[0]; 04662 tmp[1] = p1[1]; 04663 04664 p1[0] = p2[0]; 04665 p1[1] = p2[1]; 04666 04667 p2[0] = tmp[0]; 04668 p2[1] = tmp[1]; 04669 } 04670 } 04671 } 04672 } 04673 image->set_shuffled(true); 04674 }
|
|
Definition at line 162 of file processor.cpp. |