#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 | |
static Processor * | NEW () |
Static Public Attributes | |
static const string | NAME = "xform.phaseorigin.tocenter" |
works for 1D, 2D and 3D images, for all combinations of even and oddness
Definition at line 4840 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 4855 of file processor.h.
|
|
Get the processor's name. Each processor is identified by a unique name.
Implements EMAN::Processor. Definition at line 4845 of file processor.h. References NAME. 04846 { 04847 return NAME; 04848 }
|
|
Definition at line 4850 of file processor.h. 04851 { 04852 return new PhaseToCenterProcessor(); 04853 }
|
|
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 5144 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, rdata, EMAN::Phase180Processor::swap_central_slices_180(), EMAN::Phase180Processor::swap_corners_180(), and UnexpectedBehaviorException. 05145 { 05146 if (!image) throw NullPointerException("Error: attempt to phase shift a null image"); 05147 bool proceed = true; 05148 05149 #ifdef EMAN2_USING_CUDA 05150 bool cpu = image->cpu_rw_is_current(); 05151 bool gpu = image->gpu_rw_is_current(); 05152 if ( !cpu && !gpu ) 05153 throw UnexpectedBehaviorException("Both the CPU and GPU data are not current"); 05154 if (gpu && image->get_ndim() == 2) { // Because CUDA phase origin to center only works for 2D atm 05155 EMDataForCuda tmp = image->get_data_struct_for_cuda(); 05156 emdata_phaseorigin_to_center(&tmp); 05157 proceed = false; 05158 image->gpu_update(); 05159 } 05160 #endif // EMAN2_USING_CUDA 05161 if (!proceed) return; // GPU processing occurred 05162 05163 if (image->is_complex()) { 05164 fourier_phaseshift180(image); 05165 return; 05166 } 05167 05168 int nx = image->get_xsize(); 05169 int ny = image->get_ysize(); 05170 int nz = image->get_zsize(); 05171 05172 if ( ny == 1 && nz == 1 && nx == 1) return; 05173 05174 int nxy = nx * ny; 05175 05176 float *rdata = image->get_data(); 05177 05178 bool xodd = (nx % 2) == 1; 05179 bool yodd = (ny % 2) == 1; 05180 bool zodd = (nz % 2) == 1; 05181 05182 if ( ny == 1 && nz == 1 ){ 05183 if (xodd) { 05184 // Put the center pixel at the end, shifting the contents 05185 // to right of the center one step to the left 05186 float in_x = rdata[nx/2]; 05187 float tmp; 05188 for ( int i = nx-1; i >= nx/2; --i ) { 05189 tmp = rdata[i]; 05190 rdata[i] = in_x; 05191 in_x = tmp; 05192 } 05193 } 05194 // now the operation is straight forward 05195 for ( int i = 0; i < nx/2; ++i ) { 05196 int idx = i + nx/2; 05197 float tmp = rdata[i]; 05198 rdata[i] = rdata[idx]; 05199 rdata[idx] = tmp; 05200 } 05201 } 05202 else if ( nz == 1 ){ 05203 // The order in which these operations occur literally undoes what the 05204 // PhaseToCornerProcessor did to the image. 05205 // First, the corners sections of the image are swapped appropriately 05206 swap_corners_180(image); 05207 // Second, central pixel lines are swapped 05208 swap_central_slices_180(image); 05209 05210 float tmp; 05211 // Third, appropriate sections of the image are cyclically shifted by one pixel 05212 if (xodd) { 05213 // Transfer the middle column to the far right 05214 // Shift all from the far right to (but not including the) middle one to the left 05215 for ( int r = 0; r < ny; ++r ) { 05216 float last_val = rdata[r*nx+nx/2]; 05217 for ( int c = nx-1; c >= nx/2; --c ){ 05218 int idx = r*nx+c; 05219 tmp = rdata[idx]; 05220 rdata[idx] = last_val; 05221 last_val = tmp; 05222 } 05223 } 05224 } 05225 if (yodd) { 05226 // Tranfer the middle row to the top, 05227 // shifting all pixels from the top row down one, until but not including the) middle 05228 for ( int c = 0; c < nx; ++c ) { 05229 // Get the value in the top row 05230 float last_val = rdata[ny/2*nx + c]; 05231 for ( int r = ny-1; r >= ny/2; --r ){ 05232 int idx = r*nx+c; 05233 tmp = rdata[idx]; 05234 rdata[idx] = last_val; 05235 last_val = tmp; 05236 } 05237 } 05238 } 05239 } 05240 else 05241 { 05242 // The order in which these operations occur literally undoes the 05243 // PhaseToCornerProcessor operation - in 3D. 05244 // First, the corner quadrants of the voxel volume are swapped 05245 swap_corners_180(image); 05246 // Second, appropriate parts of the central slices are swapped 05247 swap_central_slices_180(image); 05248 05249 float tmp; 05250 // Third, appropriate sections of the image are cyclically shifted by one voxel 05251 if (xodd) { 05252 // Transfer the central slice in the x direction to the far right 05253 // moving all slices on the far right toward the center one pixel, until 05254 // the center x slice is ecountered 05255 size_t idx = 0; 05256 for (int s = 0; s < nz; ++s) { 05257 for (int r = 0; r < ny; ++r) { 05258 float last_val = rdata[s*nxy+r*nx+nx/2]; 05259 for (int c = nx-1; c >= nx/2; --c){ 05260 idx = s*nxy+r*nx+c; 05261 tmp = rdata[idx]; 05262 rdata[idx] = last_val; 05263 last_val = tmp; 05264 } 05265 } 05266 } 05267 } 05268 if (yodd) { 05269 // Tranfer the central slice in the y direction to the top 05270 // shifting all pixels below it down on, until the center y slice is encountered. 05271 size_t idx = 0; 05272 for (int s = 0; s < nz; ++s) { 05273 for (int c = 0; c < nx; ++c) { 05274 float last_val = rdata[s*nxy+ny/2*nx+c]; 05275 for (int r = ny-1; r >= ny/2; --r){ 05276 idx = s*nxy+r*nx+c; 05277 tmp = rdata[idx]; 05278 rdata[idx] = last_val; 05279 last_val = tmp; 05280 } 05281 } 05282 } 05283 } 05284 if (zodd) { 05285 // Tranfer the central slice in the z direction to the back 05286 // shifting all pixels beyond and including the middle slice back one. 05287 size_t idx = 0; 05288 for (int r = 0; r < ny; ++r){ 05289 for (int c = 0; c < nx; ++c) { 05290 float last_val = rdata[nz/2*nxy+r*nx+c]; 05291 for (int s = nz-1; s >= nz/2; --s) { 05292 idx = s*nxy+r*nx+c; 05293 tmp = rdata[idx]; 05294 rdata[idx] = last_val; 05295 last_val = tmp; 05296 } 05297 } 05298 } 05299 } 05300 05301 05302 } 05303 }
|
|
Definition at line 4860 of file processor.h. Referenced by get_name(). |