#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 4879 of file processor.h.
virtual string EMAN::PhaseToCenterProcessor::get_desc | ( | ) | const [inline, virtual] |
Get the descrition of this specific processor.
This function must be overwritten by a subclass.
Implements EMAN::Processor.
Definition at line 4894 of file processor.h.
virtual string EMAN::PhaseToCenterProcessor::get_name | ( | ) | const [inline, virtual] |
Get the processor's name.
Each processor is identified by a unique name.
Implements EMAN::Processor.
Definition at line 4884 of file processor.h.
References NAME.
04885 { 04886 return NAME; 04887 }
static Processor* EMAN::PhaseToCenterProcessor::NEW | ( | ) | [inline, static] |
Definition at line 4889 of file processor.h.
04890 { 04891 return new PhaseToCenterProcessor(); 04892 }
void PhaseToCenterProcessor::process_inplace | ( | EMData * | image | ) | [virtual] |
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.
image | The image to be processed. |
Implements EMAN::Processor.
Definition at line 5189 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(), and EMAN::Phase180Processor::swap_corners_180().
05190 { 05191 if (!image) throw NullPointerException("Error: attempt to phase shift a null image"); 05192 05193 #ifdef EMAN2_USING_CUDA 05194 if (EMData::usecuda == 1 && image->getcudarwdata() && image->get_ndim() == 2) { // Because CUDA phase origin to center only works for 2D atm 05195 //cout << "CUDA tocenter" << endl; 05196 emdata_phaseorigin_to_center(image->getcudarwdata(), image->get_xsize(), image->get_ysize(), image->get_zsize()); 05197 return; 05198 } 05199 #endif // EMAN2_USING_CUDA 05200 05201 if (image->is_complex()) { 05202 fourier_phaseshift180(image); 05203 return; 05204 } 05205 05206 int nx = image->get_xsize(); 05207 int ny = image->get_ysize(); 05208 int nz = image->get_zsize(); 05209 05210 if ( ny == 1 && nz == 1 && nx == 1) return; 05211 05212 int nxy = nx * ny; 05213 05214 float *rdata = image->get_data(); 05215 05216 bool xodd = (nx % 2) == 1; 05217 bool yodd = (ny % 2) == 1; 05218 bool zodd = (nz % 2) == 1; 05219 05220 if ( ny == 1 && nz == 1 ){ 05221 if (xodd) { 05222 // Put the center pixel at the end, shifting the contents 05223 // to right of the center one step to the left 05224 float in_x = rdata[nx/2]; 05225 float tmp; 05226 for ( int i = nx-1; i >= nx/2; --i ) { 05227 tmp = rdata[i]; 05228 rdata[i] = in_x; 05229 in_x = tmp; 05230 } 05231 } 05232 // now the operation is straight forward 05233 for ( int i = 0; i < nx/2; ++i ) { 05234 int idx = i + nx/2; 05235 float tmp = rdata[i]; 05236 rdata[i] = rdata[idx]; 05237 rdata[idx] = tmp; 05238 } 05239 } 05240 else if ( nz == 1 ){ 05241 // The order in which these operations occur literally undoes what the 05242 // PhaseToCornerProcessor did to the image. 05243 // First, the corners sections of the image are swapped appropriately 05244 swap_corners_180(image); 05245 // Second, central pixel lines are swapped 05246 swap_central_slices_180(image); 05247 05248 float tmp; 05249 // Third, appropriate sections of the image are cyclically shifted by one pixel 05250 if (xodd) { 05251 // Transfer the middle column to the far right 05252 // Shift all from the far right to (but not including the) middle one to the left 05253 for ( int r = 0; r < ny; ++r ) { 05254 float last_val = rdata[r*nx+nx/2]; 05255 for ( int c = nx-1; c >= nx/2; --c ){ 05256 int idx = r*nx+c; 05257 tmp = rdata[idx]; 05258 rdata[idx] = last_val; 05259 last_val = tmp; 05260 } 05261 } 05262 } 05263 if (yodd) { 05264 // Tranfer the middle row to the top, 05265 // shifting all pixels from the top row down one, until but not including the) middle 05266 for ( int c = 0; c < nx; ++c ) { 05267 // Get the value in the top row 05268 float last_val = rdata[ny/2*nx + c]; 05269 for ( int r = ny-1; r >= ny/2; --r ){ 05270 int idx = r*nx+c; 05271 tmp = rdata[idx]; 05272 rdata[idx] = last_val; 05273 last_val = tmp; 05274 } 05275 } 05276 } 05277 } 05278 else 05279 { 05280 // The order in which these operations occur literally undoes the 05281 // PhaseToCornerProcessor operation - in 3D. 05282 // First, the corner quadrants of the voxel volume are swapped 05283 swap_corners_180(image); 05284 // Second, appropriate parts of the central slices are swapped 05285 swap_central_slices_180(image); 05286 05287 float tmp; 05288 // Third, appropriate sections of the image are cyclically shifted by one voxel 05289 if (xodd) { 05290 // Transfer the central slice in the x direction to the far right 05291 // moving all slices on the far right toward the center one pixel, until 05292 // the center x slice is ecountered 05293 size_t idx = 0; 05294 for (int s = 0; s < nz; ++s) { 05295 for (int r = 0; r < ny; ++r) { 05296 float last_val = rdata[s*nxy+r*nx+nx/2]; 05297 for (int c = nx-1; c >= nx/2; --c){ 05298 idx = (size_t)s*nxy+r*nx+c; 05299 tmp = rdata[idx]; 05300 rdata[idx] = last_val; 05301 last_val = tmp; 05302 } 05303 } 05304 } 05305 } 05306 if (yodd) { 05307 // Tranfer the central slice in the y direction to the top 05308 // shifting all pixels below it down on, until the center y slice is encountered. 05309 size_t idx = 0; 05310 for (int s = 0; s < nz; ++s) { 05311 for (int c = 0; c < nx; ++c) { 05312 float last_val = rdata[s*nxy+ny/2*nx+c]; 05313 for (int r = ny-1; r >= ny/2; --r){ 05314 idx = (size_t)s*nxy+r*nx+c; 05315 tmp = rdata[idx]; 05316 rdata[idx] = last_val; 05317 last_val = tmp; 05318 } 05319 } 05320 } 05321 } 05322 if (zodd) { 05323 // Tranfer the central slice in the z direction to the back 05324 // shifting all pixels beyond and including the middle slice back one. 05325 size_t idx = 0; 05326 for (int r = 0; r < ny; ++r){ 05327 for (int c = 0; c < nx; ++c) { 05328 float last_val = rdata[nz/2*nxy+r*nx+c]; 05329 for (int s = nz-1; s >= nz/2; --s) { 05330 idx = (size_t)s*nxy+r*nx+c; 05331 tmp = rdata[idx]; 05332 rdata[idx] = last_val; 05333 last_val = tmp; 05334 } 05335 } 05336 } 05337 } 05338 05339 05340 } 05341 }
const string PhaseToCenterProcessor::NAME = "xform.phaseorigin.tocenter" [static] |