#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 4713 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 4733 of file processor.h. 04734 { 04735 return "Translates the origin in Fourier space from the corner to the center in y and z - works in 2D and 3D"; 04736 }
|
|
Get the processor's name. Each processor is identified by a unique name.
Implements EMAN::Processor. Definition at line 4723 of file processor.h. 04724 {
04725 return NAME;
04726 }
|
|
Definition at line 4728 of file processor.h. 04729 { 04730 return new FourierToCenterProcessor(); 04731 }
|
|
Fourier origin shift the image in the forward direction.
Implements EMAN::Processor. Definition at line 4470 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. 04471 { 04472 // if ( !image->is_complex() ) throw ImageFormatException("Can not Fourier origin shift an image that is not complex"); 04473 04474 int nx=image->get_xsize(); 04475 int ny=image->get_ysize(); 04476 int nz=image->get_zsize(); 04477 04478 int nxy = nx*ny; 04479 04480 if ( ny == 1 && nz == 1 ){ 04481 cout << "Warning- attempted Fourier origin shift a 1D image - no action taken" << endl; 04482 return; 04483 } 04484 04485 int yodd = (ny%2==1); 04486 int zodd = (nz%2==1); 04487 04488 float* rdata = image->get_data(); 04489 04490 float tmp[2]; 04491 float* p1; 04492 float* p2; 04493 04494 // This will tackle the 'normalization' images which come out of the Fourier reconstructor. 04495 // ie- real-space 1/2 FFt images centered on the corner 04496 if ( !image->is_complex() ) { 04497 if (nz!=1 && !yodd && !zodd) { 04498 for (int x=0; x<nx; x++) { 04499 for (int y=0; y<ny; y++) { 04500 for (int z=0; z<nz/2; z++) { 04501 int y2=(y+ny/2)%ny; 04502 int z2=(z+nz/2)%nz; // %nz should be redundant here 04503 size_t i=x+y*nx+z*nxy; 04504 size_t i2=x+y2*nx+z2*nxy; 04505 float swp=rdata[i]; 04506 rdata[i]=rdata[i2]; 04507 rdata[i2]=swp; 04508 } 04509 } 04510 } 04511 04512 return; 04513 } 04514 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"); 04515 } 04516 04517 if (yodd){ 04518 // In 3D this is swapping the bottom slice (with respect to the y direction) and the middle slice, 04519 // shifting all slices below the middle slice down one. In 2D it is equivalent, but in terms of rows. 04520 float prev[2]; 04521 size_t idx; 04522 for( int s = 0; s < nz; s++ ) { 04523 for( int c =0; c < nx; c += 2 ) { 04524 idx = s*nxy+c; 04525 prev[0] = rdata[idx]; 04526 prev[1] = rdata[idx+1]; 04527 for( int r = ny/2; r >= 0; --r ) { 04528 idx = s*nxy+r*nx+c; 04529 float* p1 = &rdata[idx]; 04530 tmp[0] = p1[0]; 04531 tmp[1] = p1[1]; 04532 04533 p1[0] = prev[0]; 04534 p1[1] = prev[1]; 04535 04536 prev[0] = tmp[0]; 04537 prev[1] = tmp[1]; 04538 } 04539 } 04540 } 04541 } 04542 04543 // 3D - Shift slices correctly in the y direction, 2D - shift rows 04544 size_t idx1, idx2; 04545 for( int s = 0; s < nz; ++s ) { 04546 for( int r = 0; r < ny/2; ++r ) { 04547 for( int c =0; c < nx; c += 2 ) { 04548 idx1 = s*nxy+r*nx+c; 04549 idx2 = s*nxy+(r+ny/2+yodd)*nx+c; 04550 p1 = &rdata[idx1]; 04551 p2 = &rdata[idx2]; 04552 04553 tmp[0] = p1[0]; 04554 tmp[1] = p1[1]; 04555 04556 p1[0] = p2[0]; 04557 p1[1] = p2[1]; 04558 04559 p2[0] = tmp[0]; 04560 p2[1] = tmp[1]; 04561 } 04562 } 04563 } 04564 04565 if ( nz != 1 ) { 04566 if (zodd){ 04567 // Swap the front slice (with respect to the z direction) and the middle slice 04568 // shifting all slices behind the middles slice towards the front slice 1 voxel. 04569 float prev[2]; 04570 size_t idx; 04571 for( int r = 0; r < ny; ++r ) { 04572 for( int c =0; c < nx; c += 2 ) { 04573 prev[0] = rdata[r*nx+c]; 04574 prev[1] = rdata[r*nx+c+1]; 04575 for( int s = nz/2; s >= 0; --s ) { 04576 idx = s*nxy+r*nx+c; 04577 float* p1 = &rdata[idx]; 04578 tmp[0] = p1[0]; 04579 tmp[1] = p1[1]; 04580 04581 p1[0] = prev[0]; 04582 p1[1] = prev[1]; 04583 04584 prev[0] = tmp[0]; 04585 prev[1] = tmp[1]; 04586 } 04587 } 04588 } 04589 } 04590 04591 // Shift slices correctly in the y direction 04592 size_t idx1, idx2; 04593 for( int s = 0; s < nz/2; ++s ) { 04594 for( int r = 0; r < ny; ++r ) { 04595 for( int c =0; c < nx; c += 2 ) { 04596 idx1 = s*nxy+r*nx+c; 04597 idx2 = (s+nz/2+zodd)*nxy+r*nx+c; 04598 p1 = &rdata[idx1]; 04599 p2 = &rdata[idx2]; 04600 04601 tmp[0] = p1[0]; 04602 tmp[1] = p1[1]; 04603 04604 p1[0] = p2[0]; 04605 p1[1] = p2[1]; 04606 04607 p2[0] = tmp[0]; 04608 p2[1] = tmp[1]; 04609 } 04610 } 04611 } 04612 } 04613 image->set_shuffled(true); 04614 }
|
|
Definition at line 162 of file processor.cpp. |