#include <processor.h>
Inheritance diagram for EMAN::PhaseToCenterProcessor:
Public Member Functions | |
virtual void | process_inplace (EMData *image) |
To process an image in-place. | |
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.phaseorigin.tocenter" |
works for 1D, 2D and 3D images, for all combinations of even and oddness
Definition at line 4799 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 4814 of file processor.h. 04815 { 04816 return "Undoes the effect of the xform.phaseorigin.tocorner processor"; 04817 }
|
|
Get the processor's name. Each processor is identified by a unique name.
Implements EMAN::Processor. Definition at line 4804 of file processor.h. 04805 {
04806 return NAME;
04807 }
|
|
Definition at line 4809 of file processor.h. 04810 { 04811 return new PhaseToCenterProcessor(); 04812 }
|
|
To process an image in-place. For those processors which can only be processed out-of-place, override this function to just print out some error message to remind user call the out-of-place version.
Implements EMAN::Processor. Definition at line 5006 of file processor.cpp. References emdata_phaseorigin_to_center(), EMAN::Phase180Processor::fourier_phaseshift180(), EMAN::EMData::get_data(), EMAN::EMData::get_ndim(), EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::EMData::get_zsize(), EMAN::EMData::is_complex(), NullPointerException, nx, ny, rdata, EMAN::Phase180Processor::swap_central_slices_180(), EMAN::Phase180Processor::swap_corners_180(), and UnexpectedBehaviorException. 05007 { 05008 if (!image) throw NullPointerException("Error: attempt to phase shift a null image"); 05009 bool proceed = true; 05010 05011 #ifdef EMAN2_USING_CUDA 05012 bool cpu = image->cpu_rw_is_current(); 05013 bool gpu = image->gpu_rw_is_current(); 05014 if ( !cpu && !gpu ) 05015 throw UnexpectedBehaviorException("Both the CPU and GPU data are not current"); 05016 if (gpu && image->get_ndim() == 2) { // Because CUDA phase origin to center only works for 2D atm 05017 EMDataForCuda tmp = image->get_data_struct_for_cuda(); 05018 emdata_phaseorigin_to_center(&tmp); 05019 proceed = false; 05020 image->gpu_update(); 05021 } 05022 #endif // EMAN2_USING_CUDA 05023 if (!proceed) return; // GPU processing occurred 05024 05025 if (image->is_complex()) { 05026 fourier_phaseshift180(image); 05027 return; 05028 } 05029 05030 int nx = image->get_xsize(); 05031 int ny = image->get_ysize(); 05032 int nz = image->get_zsize(); 05033 05034 if ( ny == 1 && nz == 1 && nx == 1) return; 05035 05036 int nxy = nx * ny; 05037 05038 float *rdata = image->get_data(); 05039 05040 bool xodd = (nx % 2) == 1; 05041 bool yodd = (ny % 2) == 1; 05042 bool zodd = (nz % 2) == 1; 05043 05044 if ( ny == 1 && nz == 1 ){ 05045 if (xodd) { 05046 // Put the center pixel at the end, shifting the contents 05047 // to right of the center one step to the left 05048 float in_x = rdata[nx/2]; 05049 float tmp; 05050 for ( int i = nx-1; i >= nx/2; --i ) { 05051 tmp = rdata[i]; 05052 rdata[i] = in_x; 05053 in_x = tmp; 05054 } 05055 } 05056 // now the operation is straight forward 05057 for ( int i = 0; i < nx/2; ++i ) { 05058 int idx = i + nx/2; 05059 float tmp = rdata[i]; 05060 rdata[i] = rdata[idx]; 05061 rdata[idx] = tmp; 05062 } 05063 } 05064 else if ( nz == 1 ){ 05065 // The order in which these operations occur literally undoes what the 05066 // PhaseToCornerProcessor did to the image. 05067 // First, the corners sections of the image are swapped appropriately 05068 swap_corners_180(image); 05069 // Second, central pixel lines are swapped 05070 swap_central_slices_180(image); 05071 05072 float tmp; 05073 // Third, appropriate sections of the image are cyclically shifted by one pixel 05074 if (xodd) { 05075 // Transfer the middle column to the far right 05076 // Shift all from the far right to (but not including the) middle one to the left 05077 for ( int r = 0; r < ny; ++r ) { 05078 float last_val = rdata[r*nx+nx/2]; 05079 for ( int c = nx-1; c >= nx/2; --c ){ 05080 int idx = r*nx+c; 05081 tmp = rdata[idx]; 05082 rdata[idx] = last_val; 05083 last_val = tmp; 05084 } 05085 } 05086 } 05087 if (yodd) { 05088 // Tranfer the middle row to the top, 05089 // shifting all pixels from the top row down one, until but not including the) middle 05090 for ( int c = 0; c < nx; ++c ) { 05091 // Get the value in the top row 05092 float last_val = rdata[ny/2*nx + c]; 05093 for ( int r = ny-1; r >= ny/2; --r ){ 05094 int idx = r*nx+c; 05095 tmp = rdata[idx]; 05096 rdata[idx] = last_val; 05097 last_val = tmp; 05098 } 05099 } 05100 } 05101 } 05102 else 05103 { 05104 // The order in which these operations occur literally undoes the 05105 // PhaseToCornerProcessor operation - in 3D. 05106 // First, the corner quadrants of the voxel volume are swapped 05107 swap_corners_180(image); 05108 // Second, appropriate parts of the central slices are swapped 05109 swap_central_slices_180(image); 05110 05111 float tmp; 05112 // Third, appropriate sections of the image are cyclically shifted by one voxel 05113 if (xodd) { 05114 // Transfer the central slice in the x direction to the far right 05115 // moving all slices on the far right toward the center one pixel, until 05116 // the center x slice is ecountered 05117 size_t idx = 0; 05118 for (int s = 0; s < nz; ++s) { 05119 for (int r = 0; r < ny; ++r) { 05120 float last_val = rdata[s*nxy+r*nx+nx/2]; 05121 for (int c = nx-1; c >= nx/2; --c){ 05122 idx = s*nxy+r*nx+c; 05123 tmp = rdata[idx]; 05124 rdata[idx] = last_val; 05125 last_val = tmp; 05126 } 05127 } 05128 } 05129 } 05130 if (yodd) { 05131 // Tranfer the central slice in the y direction to the top 05132 // shifting all pixels below it down on, until the center y slice is encountered. 05133 size_t idx = 0; 05134 for (int s = 0; s < nz; ++s) { 05135 for (int c = 0; c < nx; ++c) { 05136 float last_val = rdata[s*nxy+ny/2*nx+c]; 05137 for (int r = ny-1; r >= ny/2; --r){ 05138 idx = s*nxy+r*nx+c; 05139 tmp = rdata[idx]; 05140 rdata[idx] = last_val; 05141 last_val = tmp; 05142 } 05143 } 05144 } 05145 } 05146 if (zodd) { 05147 // Tranfer the central slice in the z direction to the back 05148 // shifting all pixels beyond and including the middle slice back one. 05149 size_t idx = 0; 05150 for (int r = 0; r < ny; ++r){ 05151 for (int c = 0; c < nx; ++c) { 05152 float last_val = rdata[nz/2*nxy+r*nx+c]; 05153 for (int s = nz-1; s >= nz/2; --s) { 05154 idx = s*nxy+r*nx+c; 05155 tmp = rdata[idx]; 05156 rdata[idx] = last_val; 05157 last_val = tmp; 05158 } 05159 } 05160 } 05161 } 05162 05163 05164 } 05165 }
|
|
Definition at line 163 of file processor.cpp. |