00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include <stack>
00037 #include "ctf.h"
00038 #include "emdata.h"
00039 #include <iostream>
00040 #include <cmath>
00041 #include <cstring>
00042
00043 #include <gsl/gsl_sf_bessel.h>
00044 #include <gsl/gsl_errno.h>
00045 #include <vector>
00046 #include <boost/shared_ptr.hpp>
00047
00048 using boost::shared_ptr;
00049 using std::vector;
00050 using std::cout;
00051 using namespace EMAN;
00052 using namespace std;
00053
00054 EMData *EMData::real2FH(float OverSamplekB)
00055 {
00056 int nx = get_xsize();
00057 int ny = get_ysize();
00058 int nz = get_zsize();
00059 int Center = (int) floor( (nx+1.0)/2.0 +.01);
00060 #ifdef DEBUG
00061 printf("nx=%d, ny=%d, nz=%d Center=%d\n", nx,ny,nz, Center);
00062 #endif //DEBUG
00063 float ScalFactor=4.1f;
00064 gsl_set_error_handler_off();
00065
00066 if ( (nz==1) && (nx==ny) && (!is_complex()) && (Center*2)==(nx+1)){
00067 #ifdef DEBUG
00068 printf("entered if \n");fflush(stdout);
00069 #endif //DEBUG
00070
00071 EMData* ImBW = this ;
00072 int Size=nx;
00073 int iMax = (int) floor( (Size-1.0)/2 +.01);
00074 int CountMax = (iMax+2)*(iMax+1)/2;
00075 int *PermMatTr = new int[CountMax];
00076 float *RValsSorted = new float[CountMax];
00077 float *weightofkValsSorted = new float[CountMax];
00078 int *SizeReturned = new int[1];
00079 Util::Radialize(PermMatTr, RValsSorted,weightofkValsSorted,Size, SizeReturned);
00080 int RIntMax= SizeReturned[0];
00081
00082 int mMax = (int) floor( ScalFactor*RValsSorted[RIntMax-1]+10.0);
00083
00084 int kIntMax=2+ (int) floor( RValsSorted[RIntMax-1]*OverSamplekB);
00085 float *kVec2Use= new float[kIntMax];
00086 for (int kk=0; kk<kIntMax; kk++){
00087 kVec2Use[kk]= ((float) kk)/OverSamplekB;}
00088
00089 float *krVec= new float[kIntMax*RIntMax];
00090 int Count=0;
00091 for (int jk=0; jk<kIntMax; jk++ ){
00092 for (int jR=0; jR<RIntMax; jR++ ){
00093 krVec[Count]=2.0f*M_PI*RValsSorted[jR]
00094 *kVec2Use[jk]/( (float) Size);
00095 Count++;
00096
00097 }}
00098 float krVecMin= kVec2Use[1]*RValsSorted[1];
00099 float krVecMax = krVec[kIntMax*RIntMax-1]+krVecMin;
00100 int Number2Use = (int) floor(OverSamplekB*krVecMax+1.0);
00101 float *krVec2Use = new float[Number2Use+1];
00102 float *sampledBesselJ = new float[Number2Use+1];
00103 #ifdef DEBUG
00104 printf("Size=%d, iMax=%d, SizeReturned=%d, RIntMax=%d, \n"
00105 "mMax=%d, kIntMax=%d, krVecMin=%f, krVecMax=%f, Number2Use=%d \n\n",
00106 Size, iMax, SizeReturned[0], RIntMax, mMax, kIntMax,
00107 krVecMin,krVecMax,Number2Use);fflush(stdout);
00108 #endif //DEBUG
00109 for (int jkr=0; jkr<= Number2Use; jkr++) {
00110 krVec2Use[jkr] =((float)jkr)*krVecMax/
00111 ((float)Number2Use);
00112
00113 }
00114
00115
00116 EMData* rhoOfkmB = copy();
00117
00118 rhoOfkmB->set_size(2*(mMax+1),kIntMax);
00119 rhoOfkmB->to_zero();
00120
00121
00122 int CenterM= Center-1;
00123 std::complex <float> *rhoOfRandmTemp = new std::complex <float>[RIntMax];
00124 std::complex <float> rhoTemp;
00125
00126 int PCount=0;
00127
00128 for (int m=0; m <=mMax; m++){
00129
00130 std::complex <float> tempF(0.0f,-1.0f);
00131 std::complex <float> overallFactor = pow(tempF,m);
00132 std::complex <float> mI(0.0f,static_cast<float>(m));
00133 for (int ii=0; ii< RIntMax; ii++){ rhoOfRandmTemp[ii]=0;}
00134 for (int jx=0; jx <Center ; jx++) {
00135 for (int jy=0; jy <=jx; jy++){
00136 float fjx=float(jx);
00137 float fjy= float(jy);
00138 Count = (jx*jx+jx)/2 +1 +jy;
00139 PCount = PermMatTr[Count-1];
00140
00141 rhoTemp = std::complex <float> ((*ImBW)(CenterM+jx,CenterM+jy)) *exp(mI* std::complex <float> (atan2(+fjy,+fjx)))
00142 + std::complex <float> ((*ImBW)(CenterM+jx,CenterM-jy)) * exp(mI*std::complex <float>(atan2(-fjy,+fjx)))
00143 + std::complex <float> ((*ImBW)(CenterM-jx,CenterM+jy)) * exp(mI*std::complex <float>(atan2(+fjy,-fjx)))
00144 + std::complex <float> ((*ImBW)(CenterM-jx,CenterM-jy)) * exp(mI*std::complex <float>(atan2(-fjy,-fjx)))
00145 + std::complex <float> ((*ImBW)(CenterM+jy,CenterM+jx)) * exp(mI*std::complex <float>(atan2(+fjx,+fjy)))
00146 + std::complex <float> ((*ImBW)(CenterM+jy,CenterM-jx)) * exp(mI*std::complex <float>(atan2(-fjx,+fjy)))
00147 + std::complex <float> ((*ImBW)(CenterM-jy,CenterM+jx)) * exp(mI*std::complex <float>(atan2(+fjx,-fjy)))
00148 + std::complex <float> ((*ImBW)(CenterM-jy,CenterM-jx)) * exp(mI*std::complex <float>(atan2(-fjx,-fjy)));
00149 if (((jx+jy)==0)&&(m>0) ){
00150 rhoTemp=0;}
00151
00152
00153
00154
00155 rhoOfRandmTemp[PCount-1] +=
00156 rhoTemp/((float)pow(2.,(int)( (jx==0) +(jy==0)+ (jy==jx))));
00157
00158 }}
00159
00160
00161
00162
00163
00164
00165 float tempp;
00166
00167 for (int st=0; st<= Number2Use; st++){
00168 tempp=krVec2Use[st];
00169 sampledBesselJ[st] = static_cast<float>(gsl_sf_bessel_Jn(m,tempp));
00170
00171 }
00172
00173
00174 float *tempMB = new float [kIntMax*RIntMax];
00175 Util::spline_mat(krVec2Use, sampledBesselJ, Number2Use+1,krVec,tempMB,kIntMax*RIntMax );
00176
00177 std::complex <float> *rowV = new std::complex <float> [kIntMax];
00178
00179
00180
00181
00182
00183 for (int st=0; st < kIntMax; st++) {
00184 rowV[st]=0;
00185 for (int sv=0; sv < RIntMax; sv++) {
00186 rowV[st]+= rhoOfRandmTemp[sv] *tempMB[sv+st*RIntMax];
00187 }
00188 rowV[st] *= overallFactor;
00189
00190 }
00191 for (int st=0; st < kIntMax; st++) {
00192 (*rhoOfkmB)(2*m ,st) = rowV[st].real();
00193 (*rhoOfkmB)(2*m+1,st) = rowV[st].imag();
00194 }
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204 }
00205
00206 update();
00207 rhoOfkmB-> update();
00208 rhoOfkmB->set_complex(true);
00209 if(rhoOfkmB->get_ysize()==1 && rhoOfkmB->get_zsize()==1) {
00210 rhoOfkmB->set_complex_x(true);
00211 }
00212 rhoOfkmB->set_ri(true);
00213 rhoOfkmB->set_FH(true);
00214 rhoOfkmB->set_fftodd(true);
00215 return rhoOfkmB;
00216 } else {
00217 LOGERR("2D real square odd image expected.");
00218 throw ImageFormatException("2D real square odd image expected.");
00219 }
00220 }
00221
00222
00223 EMData *EMData::FH2F(int Size, float OverSamplekB, int IntensityFlag)
00224 {
00225 int nx=get_xsize();
00226 int ny=get_ysize();
00227 int nz=get_zsize();
00228 float ScalFactor=4.1f;
00229 int Center = (int) floor((Size+1.0)/2.0 +.1);
00230 int CenterM= Center-1;
00231 int CountMax = (Center+1)*Center/2;
00232
00233 int *PermMatTr = new int[CountMax];
00234 float *RValsSorted = new float[CountMax];
00235 float *weightofkValsSorted = new float[CountMax];
00236 int *SizeReturned = new int[1];
00237 Util::Radialize(PermMatTr, RValsSorted,weightofkValsSorted,Size, SizeReturned);
00238 int RIntMax= SizeReturned[0];
00239
00240
00241 int mMax = (int) floor( ScalFactor*RValsSorted[RIntMax-1]+10.0);
00242
00243 int kIntMax = 2+ (int) floor( RValsSorted[RIntMax-1]*OverSamplekB);
00244 float *kVec2Use = new float[kIntMax];
00245 for (int kk=0; kk<kIntMax; kk++){
00246 kVec2Use[kk]= ((float) kk)/OverSamplekB;}
00247
00248
00249
00250 #ifdef DEBUG
00251 printf("nx=%d, ny=%d, nz=%d Center=%d mMax=%d CountMax=%d kIntMax=%d Centerm1=%d Size=%d\n\n",
00252 nx,ny,nz, Center, mMax, CountMax, kIntMax, CenterM, Size);
00253 #endif
00254
00255 EMData * rhoOfkmB = this;
00256
00257
00258
00259
00260 if ( (nx==2*(mMax+1)) && (ny==kIntMax) &&(nz==1) ) {
00261
00262 EMData *rhoOfkandm = copy();
00263 rhoOfkandm ->set_size(2*(mMax+1),RIntMax);
00264 rhoOfkandm ->to_zero();
00265
00266
00267 for (int mr=0; mr <2*(mMax+1); mr++){
00268 float *Row= new float[kIntMax];
00269 float *RowOut= new float[RIntMax];
00270 for (int ii=0; ii<kIntMax; ii++){ Row[ii]=(*rhoOfkmB)(mr,ii);}
00271 Util::spline_mat(kVec2Use, Row, kIntMax, RValsSorted, RowOut, RIntMax );
00272 for (int ii=0; ii<RIntMax; ii++){
00273 (*rhoOfkandm)(mr,ii) = RowOut[ii];
00274
00275 }
00276
00277
00278 }
00279 rhoOfkandm ->update();
00280
00281
00282
00283 EMData* outCopy = rhoOfkandm ->copy();
00284 outCopy->set_size(2*Size,Size,1);
00285 outCopy->to_zero();
00286
00287
00288 int Count =0, kInt, kIntm1;
00289 std::complex <float> ImfTemp;
00290 float kValue, thetak;
00291
00292 for (int jkx=0; jkx <Center; jkx++) {
00293 for (int jky=0; jky<=jkx; jky++){
00294 kInt = PermMatTr[Count];
00295 kIntm1= kInt-1;
00296 Count++;
00297 float fjkx = float(jkx);
00298 float fjky = float(jky);
00299
00300 kValue = std::sqrt(fjkx*fjkx + fjky*fjky ) ;
00301
00302
00303
00304
00305 thetak = atan2(fjky,fjkx);
00306 ImfTemp = (*rhoOfkandm)(0, kIntm1) ;
00307 for (int mm= 1; mm <mMax;mm++) {
00308 std::complex <float> fact(0,-mm*thetak);
00309 std::complex <float> expfact= exp(fact);
00310 std::complex <float> tempRho((*rhoOfkandm)(2*mm,kIntm1),(*rhoOfkandm)(2*mm+1,kIntm1));
00311 float mmFac = float(1-2*(mm%2));
00312 if (IntensityFlag==1){ mmFac=1;}
00313 ImfTemp += expfact * tempRho + mmFac *conj(expfact*tempRho);
00314 }
00315 (*outCopy)(2*(CenterM+jkx),CenterM+jky) = ImfTemp.real();
00316 (*outCopy)(2*(CenterM+jkx)+1,CenterM+jky) = ImfTemp.imag();
00317
00318
00319 if (jky>0) {
00320 thetak = atan2(-fjky,fjkx);
00321 ImfTemp = (*rhoOfkandm)(0,kIntm1);
00322 for (int mm= 1; mm<mMax; mm++) {
00323 std::complex <float> fact(0,-mm*thetak);
00324 std::complex <float> expfact= exp(fact);
00325 std::complex <float> tempRho((*rhoOfkandm)(2*mm,kIntm1), (*rhoOfkandm)(2*mm+1,kIntm1));
00326 float mmFac = float(1-2*(mm%2));
00327 if (IntensityFlag==1){ mmFac=1;}
00328 ImfTemp += expfact * tempRho + mmFac *conj(expfact*tempRho);
00329 }
00330 (*outCopy)(2*(CenterM+jkx),CenterM-jky) = ImfTemp.real();
00331
00332 (*outCopy)(2*(CenterM+jkx)+1,CenterM-jky) = ImfTemp.imag();
00333 }
00334
00335 if (jkx>0) {
00336 thetak = atan2(fjky,-fjkx);
00337 ImfTemp = (*rhoOfkandm)(0,kIntm1);
00338 for (int mm= 1; mm<mMax; mm++) {
00339 std::complex <float> fact(0,-mm*thetak);
00340 std::complex <float> expfact= exp(fact);
00341 std::complex <float> tempRho((*rhoOfkandm)(2*mm,kIntm1), (*rhoOfkandm)(2*mm+1,kIntm1));
00342 float mmFac = float(1-2*(mm%2));
00343 if (IntensityFlag==1){ mmFac=1;}
00344 ImfTemp += expfact * tempRho + mmFac *conj(expfact*tempRho);
00345 }
00346 (*outCopy)(2*(CenterM-jkx) ,CenterM+jky) = ImfTemp.real();
00347 (*outCopy)(2*(CenterM-jkx)+1,CenterM+jky) = ImfTemp.imag();
00348 }
00349
00350 if (jkx>0 && jky>0) {
00351 thetak = atan2(-fjky,-fjkx);
00352 ImfTemp = (*rhoOfkandm)(0 , kIntm1);
00353 for (int mm= 1; mm<mMax; mm++) {
00354 std::complex <float> fact(0,-mm*thetak);
00355 std::complex <float> expfact= exp(fact);
00356 std::complex <float> tempRho( (*rhoOfkandm)(2*mm,kIntm1),(*rhoOfkandm)(2*mm+1,kIntm1) );
00357 float mmFac = float(1-2*(mm%2));
00358 if (IntensityFlag==1){ mmFac=1;}
00359 ImfTemp += expfact * tempRho + mmFac *conj(expfact*tempRho);
00360 }
00361 (*outCopy)(2*(CenterM-jkx) ,CenterM-jky) = ImfTemp.real();
00362 (*outCopy)(2*(CenterM-jkx)+1,CenterM-jky) = ImfTemp.imag();
00363 }
00364
00365 if (jky< jkx) {
00366 thetak = atan2(fjkx,fjky);
00367 ImfTemp = (*rhoOfkandm)(0,kIntm1);
00368 for (int mm= 1; mm<mMax; mm++){
00369 std::complex <float> fact(0,-mm*thetak);
00370 std::complex <float> expfact= exp(fact);
00371 std::complex <float> tempRho((*rhoOfkandm)(2*mm,kIntm1),(*rhoOfkandm)(2*mm+1,kIntm1));
00372 float mmFac = float(1-2*(mm%2));
00373 if (IntensityFlag==1){ mmFac=1;}
00374 ImfTemp += expfact * tempRho + mmFac *conj(expfact*tempRho);
00375 }
00376 (*outCopy)(2*(CenterM+jky) ,CenterM+jkx) = ImfTemp.real();
00377 (*outCopy)(2*(CenterM+jky)+1,CenterM+jkx) = ImfTemp.imag();
00378
00379 if (jky>0){
00380 thetak = atan2(fjkx,-fjky);
00381 ImfTemp = (*rhoOfkandm)(0, kIntm1);
00382 for (int mm= 1; mm <mMax; mm++) {
00383 std::complex <float> fact(0,-mm*thetak);
00384 std::complex <float> expfact= exp(fact);
00385 std::complex <float> tempRho((*rhoOfkandm)(2*mm,kIntm1),(*rhoOfkandm)(2*mm+1,kIntm1));
00386 float mmFac = float(1-2*(mm%2));
00387 if (IntensityFlag==1){ mmFac=1;}
00388 ImfTemp += expfact * tempRho + mmFac *conj(expfact*tempRho);
00389 }
00390 (*outCopy)(2*(CenterM-jky) ,CenterM+jkx) = ImfTemp.real();
00391 (*outCopy)(2*(CenterM-jky)+1,CenterM+jkx) = ImfTemp.imag();
00392 }
00393
00394 if (jkx>0) {
00395 thetak = atan2(-fjkx,fjky);
00396 ImfTemp = (*rhoOfkandm)(0,kIntm1);
00397 for (int mm= 1; mm <mMax; mm++) {
00398 std::complex <float> fact(0,-mm*thetak);
00399 std::complex <float> expfact= exp(fact);
00400 std::complex <float> tempRho((*rhoOfkandm)(2*mm,kIntm1),(*rhoOfkandm)(2*mm+1,kIntm1));
00401 float mmFac = float(1-2*(mm%2));
00402 if (IntensityFlag==1){ mmFac=1;}
00403 ImfTemp += expfact * tempRho + mmFac *conj(expfact*tempRho);
00404 }
00405 (*outCopy)(2*(CenterM+jky) ,CenterM-jkx) = ImfTemp.real();
00406 (*outCopy)(2*(CenterM+jky)+1,CenterM-jkx) = ImfTemp.imag();
00407 }
00408
00409 if (jkx>0 && jky>0) {
00410 thetak = atan2(-fjkx,-fjky);
00411 ImfTemp = (*rhoOfkandm)(0,kIntm1) ;
00412 for (int mm= 1; mm <mMax; mm++) {
00413 std::complex <float> fact(0,-mm*thetak);
00414 std::complex <float> expfact= exp(fact);
00415 std::complex <float> tempRho((*rhoOfkandm)(2*mm,kIntm1) ,(*rhoOfkandm)(2*mm+1,kIntm1) );
00416 float mmFac = float(1-2*(mm%2));
00417 if (IntensityFlag==1){ mmFac=1;}
00418 ImfTemp += expfact * tempRho + mmFac *conj(expfact*tempRho);
00419 }
00420 (*outCopy)(2*(CenterM-jky) ,CenterM-jkx) = ImfTemp.real();
00421 (*outCopy)(2*(CenterM-jky)+1,CenterM-jkx) = ImfTemp.imag();
00422 }
00423 }
00424
00425
00426 }
00427 }
00428 outCopy->update();
00429 outCopy->set_complex(true);
00430 if(outCopy->get_ysize()==1 && outCopy->get_zsize()==1) outCopy->set_complex_x(true);
00431 outCopy->set_ri(true);
00432 outCopy->set_FH(false);
00433 outCopy->set_fftodd(true);
00434 outCopy->set_shuffled(true);
00435 return outCopy;
00436 } else {
00437 LOGERR("can't be an FH image not this size");
00438 throw ImageFormatException("something strange about this image: not a FH");
00439
00440 }
00441 }
00442
00443
00444 EMData *EMData::FH2Real(int Size, float OverSamplekB, int)
00445 {
00446 EMData* FFT= FH2F(Size,OverSamplekB,0);
00447 FFT->process_inplace("xform.fourierorigin.tocorner");
00448 EMData* eguess= FFT ->do_ift();
00449 return eguess;
00450 }
00451
00452 float dist(int lnlen, const float* line_1, const float* line_2)
00453 {
00454 float dis2=0.0;
00455 for( int i=0; i < lnlen; ++i) {
00456 float tmp = line_1[i] - line_2[i];
00457 dis2 += tmp*tmp;
00458 }
00459
00460 return dis2;
00461 }
00462
00463 float dist_r(int lnlen, const float* line_1, const float* line_2)
00464 {
00465 double dis2 = 0.0;
00466 for( int i=0; i < lnlen; ++i ) {
00467 float tmp = line_1[lnlen-1-i] - line_2[i];
00468 dis2 += tmp*tmp;
00469 }
00470 return static_cast<float>(std::sqrt(dis2));
00471 }
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503 float EMData::cm_euc(EMData* sinoj, int n1, int n2)
00504 {
00505 int lnlen = get_xsize();
00506 float* line_1 = get_data() + n1 * lnlen;
00507 float* line_2 = sinoj->get_data() + n2 * lnlen;
00508 return dist(lnlen, line_1, line_2);
00509 }
00510
00511 EMData* EMData::rotavg() {
00512
00513 int rmax;
00514
00515 ENTERFUNC;
00516
00517
00518 if (ny<2 && nz <2) {
00519 LOGERR("No 1D images.");
00520 throw ImageDimensionException("No 1D images!");
00521 }
00522
00523 float apix[3];
00524 apix[0] = get_attr_default("apix_x",1.0);
00525 apix[1] = get_attr_default("apix_y",1.0);
00526 apix[2] = get_attr_default("apix_z",1.0);
00527 float min_apix = *std::min_element(&apix[0],&apix[3]);
00528
00529 float apix_x = apix[0]/min_apix;
00530 float apix_y = apix[1]/min_apix;
00531 float apix_z = 1.0;
00532 if( nz > 1)
00533 apix_z=apix[2]/min_apix;
00534 float apix_x2 = apix_x*apix_x;
00535 float apix_y2 = apix_y*apix_y;
00536 float apix_z2 = apix_z*apix_z;
00537
00538 vector<int> saved_offsets = get_array_offsets();
00539 set_array_offsets(-nx/2,-ny/2,-nz/2);
00540
00541
00542 #ifdef _WIN32
00543
00544 if ( nz == 1 ) {
00545 rmax = _cpp_min( nx/2 + nx%2, ny/2 + ny%2);
00546 } else {
00547 rmax = _cpp_min(nx/2 + nx%2, _cpp_min(ny/2 + ny%2, nz/2 + nz%2));
00548 }
00549 #else
00550
00551 if ( nz == 1 ) {
00552 rmax = std::min(nx/2 + nx%2, ny/2 + ny%2);
00553 } else {
00554 rmax = std::min(nx/2 + nx%2, std::min(ny/2 + ny%2, nz/2 + nz%2));
00555 }
00556 #endif //_WIN32
00557
00558 float rmax_ratio = 0.0;
00559 if (rmax == nx/2 + nx%2 )
00560 rmax_ratio = apix_x;
00561 else if (rmax == ny/2 + ny%2)
00562 rmax_ratio = apix_y;
00563 else
00564 rmax_ratio = apix_z;
00565
00566 EMData* ret = new EMData();
00567 ret->set_size(rmax+1, 1, 1);
00568 ret->to_zero();
00569 vector<float> count(rmax+1);
00570 for (int k = -nz/2; k < nz/2 + nz%2; k++) {
00571 if (abs( k*apix_z) > rmax*rmax_ratio ) continue;
00572 for (int j = -ny/2; j < ny/2 + ny%2; j++) {
00573 if (abs( j*apix_y ) > rmax*rmax_ratio) continue;
00574 for (int i = -nx/2; i < nx/2 + nx%2; i++) {
00575 float r = std::sqrt(float(k*k*apix_z2) + float(j*j*apix_y2) + float(i*i*apix_x2))/rmax_ratio;
00576 int ir = int(r);
00577 if (ir >= rmax) continue;
00578 float frac = r - float(ir);
00579 (*ret)(ir) += (*this)(i,j,k)*(1.0f - frac);
00580 (*ret)(ir+1) += (*this)(i,j,k)*frac;
00581 count[ir] += 1.0f - frac;
00582 count[ir+1] += frac;
00583 }
00584 }
00585 }
00586 for (int ir = 0; ir <= rmax; ir++) {
00587 #ifdef _WIN32
00588 (*ret)(ir) /= _cpp_max(count[ir],1.0f);
00589 #else
00590 (*ret)(ir) /= std::max(count[ir],1.0f);
00591 #endif //_WIN32
00592 }
00593
00594 set_array_offsets(saved_offsets);
00595 ret->update();
00596 EXITFUNC;
00597 return ret;
00598 }
00599
00600 EMData* EMData::rotavg_i() {
00601
00602 int rmax;
00603 ENTERFUNC;
00604 if ( ny == 1 && nz == 1 ) {
00605 LOGERR("Input image must be 2-D or 3-D!");
00606 throw ImageDimensionException("Input image must be 2-D or 3-D!");
00607 }
00608
00609 EMData* avg1D = new EMData();
00610 EMData* result = new EMData();
00611
00612 result->set_size(nx,ny,nz);
00613 result->to_zero();
00614 result->set_array_offsets(-nx/2, -ny/2, -nz/2);
00615
00616 if ( nz == 1 ) {
00617 #ifdef _WIN32
00618 rmax = _cpp_min(nx/2 + nx%2, ny/2 + ny%2);
00619 } else {
00620 rmax = _cpp_min(nx/2 + nx%2, _cpp_min(ny/2 + ny%2, nz/2 + nz%2));
00621 #else
00622 rmax = std::min(nx/2 + nx%2, ny/2 + ny%2);
00623 } else {
00624 rmax = std::min(nx/2 + nx%2, std::min(ny/2 + ny%2, nz/2 + nz%2));
00625 #endif //_WIN32
00626 }
00627
00628 avg1D = rotavg();
00629 float padded_value = 0.0, r;
00630 int i, j, k, ir;
00631 long int number_of_pixels = 0;
00632 for ( k = -nz/2; k < nz/2 + nz%2; k++) {
00633 if (abs(k) > rmax) continue;
00634 for ( j = -ny/2; j < ny/2 + ny%2; j++) {
00635 if (abs(j) > rmax) continue;
00636 for (i = -nx/2; i < nx/2 + nx%2; i++) {
00637 r = std::sqrt(float(k*k) + float(j*j) + float(i*i));
00638 ir = int(r);
00639 if (ir > rmax || ir < rmax-2 ) continue ;
00640 else {
00641 padded_value += (*avg1D)(ir) ;
00642 number_of_pixels++ ;
00643 }
00644 }
00645 }
00646 }
00647 padded_value /= number_of_pixels;
00648 for ( k = -nz/2; k < nz/2 + nz%2; k++) {
00649 for ( j = -ny/2; j < ny/2 + ny%2; j++) {
00650 for ( i = -nx/2; i < nx/2 + nx%2; i++) {
00651 r = std::sqrt(float(k*k) + float(j*j) + float(i*i));
00652 ir = int(r);
00653 if (ir >= rmax) (*result)(i,j,k) = padded_value ;
00654 else (*result)(i,j,k) = (*avg1D)(ir)+((*avg1D)(ir+1)-(*avg1D)(ir))*(r - float(ir));
00655
00656 }
00657 }
00658 }
00659 result->update();
00660 result->set_array_offsets(0,0,0);
00661 EXITFUNC;
00662 return result;
00663 }
00664
00665
00666 EMData* EMData::mult_radial(EMData* radial) {
00667
00668 ENTERFUNC;
00669 if ( ny == 1 && nz == 1 ) {
00670 LOGERR("Input image must be 2-D or 3-D!");
00671 throw ImageDimensionException("Input image must be 2-D or 3-D!");
00672 }
00673
00674 EMData* result = this->copy_head();
00675
00676 result->to_zero();
00677 result->set_array_offsets(-nx/2, -ny/2, -nz/2);
00678 this->set_array_offsets(-nx/2, -ny/2, -nz/2);
00679 int rmax = radial->get_xsize();
00680 int i, j, k, ir;
00681 float r;
00682 for ( k = -nz/2; k < nz/2+nz%2; k++) {
00683 for ( j = -ny/2; j < ny/2+ny%2; j++) {
00684 for ( i = -nx/2; i < nx/2+nx%2; i++) {
00685 r = std::sqrt(float(k*k) + float(j*j) + float(i*i));
00686 ir = int(r);
00687 if(ir < rmax-1) (*result)(i,j,k) = (*this)(i,j,k) * ((*radial)(ir)+((*radial)(ir+1)-(*radial)(ir))*(r - float(ir)));
00688 }
00689 }
00690 }
00691 result->update();
00692 result->set_array_offsets(0,0,0);
00693 this->set_array_offsets(0,0,0);
00694 EXITFUNC;
00695 return result;
00696 }
00697
00698 #define rdata(i,j,k) rdata[(i-1)+((j-1)+(k-1)*ny)*nx]
00699 #define square(x) ((x)*(x))
00700 vector<float> EMData::cog() {
00701
00702 vector<float> cntog;
00703 int ndim = get_ndim();
00704 int i=1,j=1,k=1;
00705 float val,sum1=0.f,MX=0.f,RG=0.f,MY=0.f,MZ=0.f,r=0.f;
00706
00707 if (ndim == 1) {
00708 for ( i = 1;i <= nx; i++) {
00709 val = rdata(i,j,k);
00710 sum1 += val;
00711 MX += ((i-1)*val);
00712 }
00713 MX=(MX/sum1);
00714 for ( i = 1;i <= nx; i++) {
00715 val = rdata(i,j,k);
00716 sum1 += val;
00717 RG += val*(square(MX - (i-1)));
00718 }
00719 RG=std::sqrt(RG/sum1);
00720 MX=MX-(nx/2);
00721 cntog.push_back(MX);
00722 cntog.push_back(RG);
00723 #ifdef _WIN32
00724 cntog.push_back((float)Util::round(MX));
00725 #else
00726 cntog.push_back(round(MX));
00727 #endif //_WIN32
00728 } else if (ndim == 2) {
00729 for (j=1;j<=ny;j++) {
00730 for (i=1;i<=nx;i++) {
00731 val = rdata(i,j,k);
00732 sum1 += val;
00733 MX += ((i-1)*val);
00734 MY += ((j-1)*val);
00735 }
00736 }
00737 MX=(MX/sum1);
00738 MY=(MY/sum1);
00739 sum1=0.f;
00740 RG=0.f;
00741 for (j=1;j<=ny;j++) {
00742 r = (square(MY-(j-1)));
00743 for (i=1;i<=nx;i++) {
00744 val = rdata(i,j,k);
00745 sum1 += val;
00746 RG += val*(square(MX - (i-1)) + r);
00747 }
00748 }
00749 RG = std::sqrt(RG/sum1);
00750 MX = MX - nx/2;
00751 MY = MY - ny/2;
00752 cntog.push_back(MX);
00753 cntog.push_back(MY);
00754 cntog.push_back(RG);
00755 #ifdef _WIN32
00756 cntog.push_back((float)Util::round(MX));cntog.push_back((float)Util::round(MY));
00757 #else
00758 cntog.push_back(round(MX));cntog.push_back(round(MY));
00759 #endif //_WIN32
00760 } else {
00761 for (k = 1;k <= nz;k++) {
00762 for (j=1;j<=ny;j++) {
00763 for (i=1;i<=nx;i++) {
00764 val = rdata(i,j,k);
00765 sum1 += val;
00766 MX += ((i-1)*val);
00767 MY += ((j-1)*val);
00768 MZ += ((k-1)*val);
00769 }
00770 }
00771 }
00772 MX = MX/sum1;
00773 MY = MY/sum1;
00774 MZ = MZ/sum1;
00775 sum1=0.f;
00776 RG=0.f;
00777 for (k = 1;k <= nz;k++) {
00778 for (j=1;j<=ny;j++) {
00779 float r = (square(MY-(j-1)) + square(MZ - (k-1)));
00780 for (i=1;i<=nx;i++) {
00781 val = rdata(i,j,k);
00782 sum1 += val;
00783 RG += val*(square(MX - (i-1)) + r);
00784 }
00785 }
00786 }
00787 RG = std::sqrt(RG/sum1);
00788 MX = MX - nx/2;
00789 MY = MY - ny/2;
00790 MZ = MZ - nz/2;
00791 cntog.push_back(MX);
00792 cntog.push_back(MY);
00793 cntog.push_back(MZ);
00794 cntog.push_back(RG);
00795 #ifdef _WIN32
00796 cntog.push_back((float)Util::round(MX));cntog.push_back((float)Util::round(MY));cntog.push_back((float)Util::round(MZ));
00797 #else
00798 cntog.push_back(round(MX));cntog.push_back(round(MY));cntog.push_back(round(MZ));
00799 #endif //_WIN32
00800 }
00801 return cntog;
00802 }
00803 #undef square
00804 #undef rdata
00805
00806
00807
00808
00809
00810 vector < float >EMData::calc_fourier_shell_correlation(EMData * with, float w)
00811 {
00812 ENTERFUNC;
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837 int needfree=0, kz, ky, ii;
00838 float argx, argy, argz;
00839
00840 if (!with) {
00841 throw NullPointerException("NULL input image");
00842 }
00843
00844
00845 EMData *f = this;
00846 EMData *g = with;
00847
00848 int nx = f->get_xsize();
00849 int ny = f->get_ysize();
00850 int nz = f->get_zsize();
00851
00852 if (ny==0 && nz==0) {
00853 throw ImageFormatException( "Cannot calculate FSC for 1D images");
00854 }
00855
00856 if (f->is_complex()) nx = (nx - 2 + f->is_fftodd());
00857 int lsd2 = (nx + 2 - nx%2) ;
00858
00859
00860 EMData* fpimage = NULL;
00861 if (f->is_complex()) fpimage = f;
00862 else {
00863 fpimage= f->norm_pad(false, 1);
00864 fpimage->do_fft_inplace();
00865 needfree|=1;
00866 }
00867
00868
00869 EMData* gpimage = NULL;
00870 if (g->is_complex()) gpimage = g;
00871 else {
00872 gpimage= g->norm_pad(false, 1);
00873 gpimage->do_fft_inplace();
00874 needfree|=2;
00875 }
00876
00877 float *d1 = fpimage->get_data();
00878 float *d2 = gpimage->get_data();
00879
00880 int nx2 = nx/2;
00881 int ny2 = ny/2;
00882 int nz2 = nz/2;
00883
00884 float dx2 = 1.0f/float(nx2)/float(nx2);
00885 float dy2 = 1.0f/float(ny2)/float(ny2);
00886
00887 #ifdef _WIN32
00888 float dz2 = 1.0f / _cpp_max(float(nz2),1.0f)/_cpp_max(float(nz2),1.0f);
00889 int inc = Util::round(float( _cpp_max( _cpp_max(nx2,ny2),nz2) )/w );
00890 #else
00891 float dz2 = 1.0f/std::max(float(nz2),1.0f)/std::max(float(nz2),1.0f);
00892 int inc = Util::round(float(std::max(std::max(nx2,ny2),nz2))/w);
00893 #endif //_WIN32
00894
00895 double* ret = new double[inc+1];
00896 double* n1 = new double[inc+1];
00897 double* n2 = new double[inc+1];
00898 float* lr = new float[inc+1];
00899 for (int i = 0; i <= inc; i++) {
00900 ret[i] = 0; n1[i] = 0; n2[i] = 0; lr[i]=0;
00901 }
00902
00903 for (int iz = 0; iz <= nz-1; iz++) {
00904 if(iz>nz2) kz=iz-nz; else kz=iz; argz = float(kz*kz)*dz2;
00905 for (int iy = 0; iy <= ny-1; iy++) {
00906 if(iy>ny2) ky=iy-ny; else ky=iy; argy = argz + float(ky*ky)*dy2;
00907 for (int ix = 0; ix <= lsd2-1; ix+=2) {
00908
00909 if (ix>0 || (kz>=0 && (ky>=0 || kz!=0))) {
00910 argx = 0.5f*std::sqrt(argy + float(ix*ix)*0.25f*dx2);
00911 int r = Util::round(inc*2*argx);
00912 if(r <= inc) {
00913 ii = ix + (iy + iz * ny)* lsd2;
00914 ret[r] += d1[ii] * double(d2[ii]) + d1[ii + 1] * double(d2[ii + 1]);
00915 n1[r] += d1[ii] * double(d1[ii]) + d1[ii + 1] * double(d1[ii + 1]);
00916 n2[r] += d2[ii] * double(d2[ii]) + d2[ii + 1] * double(d2[ii + 1]);
00917 lr[r] += 2;
00918 }
00919 }
00920 }
00921 }
00922 }
00923
00924 int linc = 0;
00925 for (int i = 0; i <= inc; i++) if(lr[i]>0) linc++;
00926
00927 vector<float> result(linc*3);
00928
00929 ii = -1;
00930 for (int i = 0; i <= inc; i++) {
00931 if(lr[i]>0) {
00932 ii++;
00933 result[ii] = float(i)/float(2*inc);
00934 result[ii+linc] = float(ret[i] / (std::sqrt(n1[i] * n2[i])));
00935 result[ii+2*linc] = lr[i] ;
00936 }
00937
00938
00939
00940
00941 }
00942
00943 if (needfree&1) {
00944 if (fpimage) {
00945 delete fpimage;
00946 fpimage = 0;
00947 }
00948 }
00949 if (needfree&2) {
00950 if (gpimage) {
00951 delete gpimage;
00952 gpimage = 0;
00953 }
00954 }
00955 delete[] ret; delete[] n1; delete[] n2; delete[] lr;
00956
00957 EXITFUNC;
00958 return result;
00959 }
00960
00961
00962 EMData* EMData::symvol(string symString) {
00963 ENTERFUNC;
00964 int nsym = Transform::get_nsym(symString);
00965 Transform sym;
00966
00967 EMData *svol = new EMData;
00968 svol->set_size(nx, ny, nz);
00969 svol->to_zero();
00970
00971
00972
00973
00974
00975 for (int isym = 0; isym < nsym; isym++) {
00976 Transform rm = sym.get_sym(symString, isym);
00977 EMData* symcopy = this -> rot_scale_trans(rm);
00978 *svol += (*symcopy);
00979 delete symcopy;
00980
00981 }
00982
00983 *svol /= ((float) nsym);
00984 svol->update();
00985 EXITFUNC;
00986 return svol;
00987 }
00988
00989 #define proj(ix,iy,iz) proj[ix-1+(iy-1+(iz-1)*ny)*nx]
00990 #define pnewimg(ix,iy,iz) pnewimg[ix-1+(iy-1+(iz-1)*ny)*nx]
00991 EMData* EMData::average_circ_sub() const
00992 {
00993
00994
00995 ENTERFUNC;
00996 const EMData* const image = this;
00997 EMData* newimg = copy_head();
00998 float *proj = image->get_data();
00999 float *pnewimg = newimg->get_data();
01000
01001 float r2 = static_cast<float>( (nx/2)*(nx/2) );
01002 float qs=0.0f;
01003 int m=0;
01004 int ncz = nz/2 + 1;
01005 int ncy = ny/2 + 1;
01006 int ncx = nx/2 + 1;
01007 for (int iz = 1; iz <= nz; iz++) {
01008 float yy = static_cast<float>( (iz-ncz)*(iz-ncz) );
01009 for (int iy = 1; iy <=ny; iy++) { float xx = yy + (iy-ncy)*(iy-ncy);
01010 for (int ix = 1; ix <= nx; ix++) {
01011 if ( xx+float((ix-ncx)*(ix-ncx)) > r2 ) {
01012 qs += proj(ix,iy,iz);
01013 m++;
01014 }
01015 }
01016 }
01017 }
01018
01019
01020 if( m > 0 ) qs /= m;
01021
01022 for (int iz = 1; iz <= nz; iz++)
01023 for (int iy = 1; iy <= ny; iy++)
01024 for (int ix = 1; ix <= nx; ix++)
01025 pnewimg(ix,iy,iz) = proj(ix,iy,iz) - qs;
01026 newimg->update();
01027 return newimg;
01028 EXITFUNC;
01029 }
01030
01031
01032
01033
01034
01035 void EMData::onelinenn(int j, int n, int n2, EMData* wptr, EMData* bi, const Transform& tf)
01036 {
01037
01038 int jp = (j >= 0) ? j+1 : n+j+1;
01039
01040
01041 for (int i = 0; i <= n2; i++) {
01042 if (((i*i+j*j) < n*n/4) && !((0 == i) && (j < 0))) {
01043
01044 float xnew = i*tf[0][0] + j*tf[1][0];
01045 float ynew = i*tf[0][1] + j*tf[1][1];
01046 float znew = i*tf[0][2] + j*tf[1][2];
01047 std::complex<float> btq;
01048 if (xnew < 0.) {
01049 xnew = -xnew;
01050 ynew = -ynew;
01051 znew = -znew;
01052 btq = conj(bi->cmplx(i,jp));
01053 } else {
01054 btq = bi->cmplx(i,jp);
01055 }
01056 int ixn = int(xnew + 0.5 + n) - n;
01057 int iyn = int(ynew + 0.5 + n) - n;
01058 int izn = int(znew + 0.5 + n) - n;
01059
01060 int iza, iya;
01061 if (izn >= 0) iza = izn + 1;
01062 else iza = n + izn + 1;
01063
01064 if (iyn >= 0) iya = iyn + 1;
01065 else iya = n + iyn + 1;
01066
01067 cmplx(ixn,iya,iza) += btq;
01068
01069 (*wptr)(ixn,iya,iza)++;
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096 }
01097 }
01098 }
01099
01100
01101 void EMData::onelinenn_mult(int j, int n, int n2, EMData* wptr, EMData* bi, const Transform& tf, int mult)
01102 {
01103
01104 int jp = (j >= 0) ? j+1 : n+j+1;
01105
01106
01107 for (int i = 0; i <= n2; i++) {
01108 if (((i*i+j*j) < n*n/4) && !((0 == i) && (j < 0))) {
01109
01110 float xnew = i*tf[0][0] + j*tf[1][0];
01111 float ynew = i*tf[0][1] + j*tf[1][1];
01112 float znew = i*tf[0][2] + j*tf[1][2];
01113 std::complex<float> btq;
01114 if (xnew < 0.) {
01115 xnew = -xnew;
01116 ynew = -ynew;
01117 znew = -znew;
01118 btq = conj(bi->cmplx(i,jp));
01119 } else {
01120 btq = bi->cmplx(i,jp);
01121 }
01122 int ixn = int(xnew + 0.5 + n) - n;
01123 int iyn = int(ynew + 0.5 + n) - n;
01124 int izn = int(znew + 0.5 + n) - n;
01125
01126
01127 int iza, iya;
01128 if (izn >= 0) iza = izn + 1;
01129 else iza = n + izn + 1;
01130
01131 if (iyn >= 0) iya = iyn + 1;
01132 else iya = n + iyn + 1;
01133
01134 cmplx(ixn,iya,iza) += btq*float(mult);
01135 (*wptr)(ixn,iya,iza)+=float(mult);
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160 }
01161 }
01162 }
01163
01164 void EMData::nn(EMData* wptr, EMData* myfft, const Transform& tf, int mult)
01165 {
01166 ENTERFUNC;
01167 int nxc = attr_dict["nxc"];
01168
01169 vector<int> saved_offsets = get_array_offsets();
01170 vector<int> myfft_saved_offsets = myfft->get_array_offsets();
01171 set_array_offsets(0,1,1);
01172 myfft->set_array_offsets(0,1);
01173
01174 if( mult == 1 ) {
01175 for (int iy = -ny/2 + 1; iy <= ny/2; iy++) onelinenn(iy, ny, nxc, wptr, myfft, tf);
01176 } else {
01177 for (int iy = -ny/2 + 1; iy <= ny/2; iy++) onelinenn_mult(iy, ny, nxc, wptr, myfft, tf, mult);
01178 }
01179
01180 set_array_offsets(saved_offsets);
01181 myfft->set_array_offsets(myfft_saved_offsets);
01182 EXITFUNC;
01183 }
01184
01185
01186 void EMData::insert_rect_slice(EMData* w, EMData* myfft, const Transform& trans, int sizeofprojection, float xratio, float yratio, int npad, int mult)
01187 {
01188 ENTERFUNC;
01189 vector<int> saved_offsets = get_array_offsets();
01190 vector<int> myfft_saved_offsets = myfft->get_array_offsets();
01191 set_array_offsets(0,1,1);
01192 myfft->set_array_offsets(0,1);
01193
01194
01195
01196 Vec2f coordinate_2d_sqaure;
01197 Vec3f coordinate_3dnew;
01198 Vec3f axis_newx;
01199 Vec3f axis_newy;
01200 Vec3f tempv;
01201
01202
01203
01204 axis_newx[0] = xratio*0.5*(sizeofprojection*npad)*trans[0][0];
01205 axis_newx[1] = yratio*0.5*(sizeofprojection*npad)*trans[0][1];
01206 axis_newx[2] = 0.5*(sizeofprojection*npad)*trans[0][2];
01207
01208 float ellipse_length_x = std::sqrt(axis_newx[0]*axis_newx[0]+axis_newx[1]*axis_newx[1]+axis_newx[2]*axis_newx[2]);
01209
01210 int ellipse_length_x_int = int(ellipse_length_x);
01211 float ellipse_step_x = 0.5*(sizeofprojection*npad)/float(ellipse_length_x_int);
01212 float xscale = ellipse_step_x;
01213
01214 axis_newy[0] = xratio*0.5*(sizeofprojection*npad)*trans[1][0];
01215 axis_newy[1] = yratio*0.5*(sizeofprojection*npad)*trans[1][1];
01216 axis_newy[2] = 0.5*(sizeofprojection*npad)*trans[1][2];
01217
01218
01219
01220 float ellipse_length_y = std::sqrt(axis_newy[0]*axis_newy[0]+axis_newy[1]*axis_newy[1]+axis_newy[2]*axis_newy[2]);
01221 int ellipse_length_y_int = int(ellipse_length_y);
01222 float ellipse_step_y = 0.5*(sizeofprojection*npad)/float(ellipse_length_y_int);
01223 float yscale = ellipse_step_y;
01224
01225 std::complex<float> c1;
01226 nz = get_zsize();
01227
01228 float r2=0.25*sizeofprojection*npad*sizeofprojection*npad;
01229 float r2_at_point;
01230
01231 for(int i=0;i<ellipse_length_x_int;i++) {
01232 for(int j=-1*ellipse_length_y_int+1; j<=ellipse_length_y_int; j++) {
01233
01234 r2_at_point=i*xscale*i*xscale+j*yscale*j*yscale;
01235 if(r2_at_point<=r2 ) {
01236
01237
01238 coordinate_2d_sqaure[0] = xscale*float(i);
01239 coordinate_2d_sqaure[1] = yscale*float(j);
01240 float xnew = coordinate_2d_sqaure[0]*trans[0][0] + coordinate_2d_sqaure[1]*trans[1][0];
01241 float ynew = coordinate_2d_sqaure[0]*trans[0][1] + coordinate_2d_sqaure[1]*trans[1][1];
01242 float znew = coordinate_2d_sqaure[0]*trans[0][2] + coordinate_2d_sqaure[1]*trans[1][2];
01243 coordinate_3dnew[0] =xnew*xratio;
01244 coordinate_3dnew[1] = ynew*yratio;
01245 coordinate_3dnew[2] = znew;
01246
01247
01248 float xp = coordinate_2d_sqaure[0];
01249 float yp = ( coordinate_2d_sqaure[1] >= 0) ? coordinate_2d_sqaure[1]+1 : nz+coordinate_2d_sqaure[1]+1;
01250 std::complex<float> lin_interpolated(0,0);
01251 int xlow=int(xp),xhigh=int(xp)+1;
01252 int ylow=int(yp),yhigh=int(yp)+1;
01253 float tx=xp-xlow,ty=yp-ylow;
01254
01255
01256 if(j == -1) {
01257
01258 if(ylow<yp)
01259 lin_interpolated=myfft->cmplx(xlow,ylow)*(1-tx)*(1-ty) + myfft->cmplx(xlow,yhigh)*(1-tx)*ty
01260 + myfft->cmplx(xhigh,ylow)*tx*(1-ty) + myfft->cmplx(xhigh,yhigh)*tx*ty;
01261 else
01262 lin_interpolated=myfft->cmplx(xlow,ylow)*(1-tx)
01263 + myfft->cmplx(xhigh,ylow)*tx;
01264
01265 }
01266 else {
01267 lin_interpolated=myfft->cmplx(xlow,ylow)*(1-tx)*(1-ty) + myfft->cmplx(xlow,yhigh)*(1-tx)*ty
01268 + myfft->cmplx(xhigh,ylow)*tx*(1-ty)+ myfft->cmplx(xhigh,yhigh)*tx*ty;
01269
01270 }
01271
01272 c1 = lin_interpolated;
01273
01274
01275
01276 std::complex<float> btq;
01277 if ( coordinate_3dnew[0] < 0.) {
01278 coordinate_3dnew[0] = -coordinate_3dnew[0];
01279 coordinate_3dnew[1] = -coordinate_3dnew[1];
01280 coordinate_3dnew[2] = -coordinate_3dnew[2];
01281 btq = conj(c1);
01282 } else {
01283 btq = c1;
01284 }
01285 int ixn = int(coordinate_3dnew[0] + 0.5 + nx) - nx;
01286 int iyn = int(coordinate_3dnew[1] + 0.5 + ny) - ny;
01287 int izn = int(coordinate_3dnew[2] + 0.5 + nz) - nz;
01288
01289 int iza, iya;
01290 if (izn >= 0) iza = izn + 1;
01291 else iza = nz + izn + 1;
01292
01293 if (iyn >= 0) iya = iyn + 1;
01294 else iya = ny + iyn + 1;
01295
01296 cmplx(ixn,iya,iza) += btq*float(mult);
01297 (*w)(ixn,iya,iza) += mult;
01298
01299 }
01300 }
01301
01302 }
01303
01304
01305
01306
01307 set_array_offsets(saved_offsets);
01308 myfft->set_array_offsets(myfft_saved_offsets);
01309 EXITFUNC;
01310
01311 }
01312
01313
01314
01315 void EMData::nn_SSNR(EMData* wptr, EMData* wptr2, EMData* myfft, const Transform& tf, int)
01316 {
01317 ENTERFUNC;
01318 int nxc = attr_dict["nxc"];
01319
01320 vector<int> saved_offsets = get_array_offsets();
01321 vector<int> myfft_saved_offsets = myfft->get_array_offsets();
01322
01323 set_array_offsets(0,1,1);
01324 myfft->set_array_offsets(0,1);
01325
01326 int iymin = is_fftodd() ? -ny/2 : -ny/2 + 1 ;
01327 int iymax = ny/2;
01328 int izmin = is_fftodd() ? -nz/2 : -nz/2 + 1 ;
01329 int izmax = nz/2;
01330
01331 for (int iy = iymin; iy <= iymax; iy++) {
01332 int jp = iy >= 0 ? iy+1 : ny+iy+1;
01333 for (int ix = 0; ix <= nxc; ix++) {
01334 if (( 4*(ix*ix+iy*iy) < ny*ny ) && !( ix == 0 && iy < 0 ) ) {
01335 float xnew = ix*tf[0][0] + iy*tf[1][0];
01336 float ynew = ix*tf[0][1] + iy*tf[1][1];
01337 float znew = ix*tf[0][2] + iy*tf[1][2];
01338 std::complex<float> btq;
01339 if (xnew < 0.0) {
01340 xnew = -xnew;
01341 ynew = -ynew;
01342 znew = -znew;
01343 btq = conj(myfft->cmplx(ix,jp));
01344 } else {
01345 btq = myfft->cmplx(ix,jp);
01346 }
01347 int ixn = int(xnew + 0.5 + nx) - nx;
01348 int iyn = int(ynew + 0.5 + ny) - ny;
01349 int izn = int(znew + 0.5 + nz) - nz;
01350 if ((ixn <= nxc) && (iyn >= iymin) && (iyn <= iymax) && (izn >= izmin) && (izn <= izmax)) {
01351 if (ixn >= 0) {
01352 int iza, iya;
01353 if (izn >= 0) iza = izn + 1;
01354 else iza = nz + izn + 1;
01355
01356 if (iyn >= 0) iya = iyn + 1;
01357 else iya = ny + iyn + 1;
01358
01359 cmplx(ixn,iya,iza) += btq;
01360 (*wptr)(ixn,iya,iza)++;
01361 (*wptr2)(ixn,iya,iza) += norm(btq);
01362 } else {
01363 int izt, iyt;
01364 if (izn > 0) izt = nz - izn + 1;
01365 else izt = -izn + 1;
01366
01367 if (iyn > 0) iyt = ny - iyn + 1;
01368 else iyt = -iyn + 1;
01369
01370 cmplx(-ixn,iyt,izt) += conj(btq);
01371 (*wptr)(-ixn,iyt,izt)++;
01372 (*wptr2)(-ixn,iyt,izt) += norm(btq);
01373 }
01374 }
01375 }
01376 }
01377 }
01378 set_array_offsets(saved_offsets);
01379 myfft->set_array_offsets(myfft_saved_offsets);
01380 EXITFUNC;
01381 }
01382
01383
01384
01385 void EMData::symplane0(EMData* wptr) {
01386 ENTERFUNC;
01387 int nxc = attr_dict["nxc"];
01388 int n = nxc*2;
01389
01390 vector<int> saved_offsets = get_array_offsets();
01391 set_array_offsets(0,1,1);
01392 for (int iza = 2; iza <= nxc; iza++) {
01393 for (int iya = 2; iya <= nxc; iya++) {
01394 cmplx(0,iya,iza) += conj(cmplx(0,n-iya+2,n-iza+2));
01395 (*wptr)(0,iya,iza) += (*wptr)(0,n-iya+2,n-iza+2);
01396 cmplx(0,n-iya+2,n-iza+2) = conj(cmplx(0,iya,iza));
01397 (*wptr)(0,n-iya+2,n-iza+2) = (*wptr)(0,iya,iza);
01398 cmplx(0,n-iya+2,iza) += conj(cmplx(0,iya,n-iza+2));
01399 (*wptr)(0,n-iya+2,iza) += (*wptr)(0,iya,n-iza+2);
01400 cmplx(0,iya,n-iza+2) = conj(cmplx(0,n-iya+2,iza));
01401 (*wptr)(0,iya,n-iza+2) = (*wptr)(0,n-iya+2,iza);
01402 }
01403 }
01404 for (int iya = 2; iya <= nxc; iya++) {
01405 cmplx(0,iya,1) += conj(cmplx(0,n-iya+2,1));
01406 (*wptr)(0,iya,1) += (*wptr)(0,n-iya+2,1);
01407 cmplx(0,n-iya+2,1) = conj(cmplx(0,iya,1));
01408 (*wptr)(0,n-iya+2,1) = (*wptr)(0,iya,1);
01409 }
01410 for (int iza = 2; iza <= nxc; iza++) {
01411 cmplx(0,1,iza) += conj(cmplx(0,1,n-iza+2));
01412 (*wptr)(0,1,iza) += (*wptr)(0,1,n-iza+2);
01413 cmplx(0,1,n-iza+2) = conj(cmplx(0,1,iza));
01414 (*wptr)(0,1,n-iza+2) = (*wptr)(0,1,iza);
01415 }
01416 EXITFUNC;
01417 }
01418
01419 void EMData::symplane1(EMData* wptr, EMData* wptr2) {
01420 ENTERFUNC;
01421 int nxc = attr_dict["nxc"];
01422 int n = nxc*2;
01423 vector<int> saved_offsets = get_array_offsets();
01424 set_array_offsets(0,1,1);
01425 for (int iza = 2; iza <= nxc; iza++) {
01426 for (int iya = 2; iya <= nxc; iya++) {
01427 cmplx(0,iya,iza) += conj(cmplx(0,n-iya+2,n-iza+2));
01428 (*wptr)(0,iya,iza) += (*wptr)(0,n-iya+2,n-iza+2);
01429 (*wptr2)(0,iya,iza) += (*wptr2)(0,n-iya+2,n-iza+2);
01430 cmplx(0,n-iya+2,n-iza+2) = conj(cmplx(0,iya,iza));
01431 (*wptr)(0,n-iya+2,n-iza+2) = (*wptr)(0,iya,iza);
01432 (*wptr2)(0,n-iya+2,n-iza+2) = (*wptr2)(0,iya,iza);
01433 cmplx(0,n-iya+2,iza) += conj(cmplx(0,iya,n-iza+2));
01434 (*wptr)(0,n-iya+2,iza) += (*wptr)(0,iya,n-iza+2);
01435 (*wptr2)(0,n-iya+2,iza) += (*wptr2)(0,iya,n-iza+2);
01436 cmplx(0,iya,n-iza+2) = conj(cmplx(0,n-iya+2,iza));
01437 (*wptr)(0,iya,n-iza+2) = (*wptr)(0,n-iya+2,iza);
01438 (*wptr2)(0,iya,n-iza+2) = (*wptr2)(0,n-iya+2,iza);
01439 }
01440 }
01441 for (int iya = 2; iya <= nxc; iya++) {
01442 cmplx(0,iya,1) += conj(cmplx(0,n-iya+2,1));
01443 (*wptr)(0,iya,1) += (*wptr)(0,n-iya+2,1);
01444 (*wptr2)(0,iya,1) += (*wptr2)(0,n-iya+2,1);
01445 cmplx(0,n-iya+2,1) = conj(cmplx(0,iya,1));
01446 (*wptr)(0,n-iya+2,1) = (*wptr)(0,iya,1);
01447 (*wptr2)(0,n-iya+2,1) = (*wptr2)(0,iya,1);
01448 }
01449 for (int iza = 2; iza <= nxc; iza++) {
01450 cmplx(0,1,iza) += conj(cmplx(0,1,n-iza+2));
01451 (*wptr)(0,1,iza) += (*wptr)(0,1,n-iza+2);
01452 (*wptr2)(0,1,iza) += (*wptr2)(0,1,n-iza+2);
01453 cmplx(0,1,n-iza+2) = conj(cmplx(0,1,iza));
01454 (*wptr)(0,1,n-iza+2) = (*wptr)(0,1,iza);
01455 (*wptr2)(0,1,n-iza+2) = (*wptr2)(0,1,iza);
01456 }
01457 EXITFUNC;
01458 }
01459
01460 void EMData::symplane2(EMData* wptr, EMData* wptr2, EMData* wptr3) {
01461 ENTERFUNC;
01462 int nxc = attr_dict["nxc"];
01463 int n = nxc*2;
01464 vector<int> saved_offsets = get_array_offsets();
01465 set_array_offsets(0,1,1);
01466 for (int iza = 2; iza <= nxc; iza++) {
01467 for (int iya = 2; iya <= nxc; iya++) {
01468 cmplx(0,iya,iza) += conj(cmplx(0,n-iya+2,n-iza+2));
01469 (*wptr)(0,iya,iza) += (*wptr)(0,n-iya+2,n-iza+2);
01470 (*wptr2)(0,iya,iza) += (*wptr2)(0,n-iya+2,n-iza+2);
01471 (*wptr3)(0,iya,iza) += (*wptr3)(0,n-iya+2,n-iza+2);
01472
01473 cmplx(0,n-iya+2,n-iza+2) = conj(cmplx(0,iya,iza));
01474 (*wptr)(0,n-iya+2,n-iza+2) = (*wptr)(0,iya,iza);
01475 (*wptr2)(0,n-iya+2,n-iza+2) = (*wptr2)(0,iya,iza);
01476 (*wptr3)(0,n-iya+2,n-iza+2) = (*wptr3)(0,iya,iza);
01477
01478 cmplx(0,n-iya+2,iza) += conj(cmplx(0,iya,n-iza+2));
01479 (*wptr)(0,n-iya+2,iza) += (*wptr)(0,iya,n-iza+2);
01480 (*wptr2)(0,n-iya+2,iza) += (*wptr2)(0,iya,n-iza+2);
01481 (*wptr3)(0,n-iya+2,iza) += (*wptr3)(0,iya,n-iza+2);
01482
01483 cmplx(0,iya,n-iza+2) = conj(cmplx(0,n-iya+2,iza));
01484 (*wptr)(0,iya,n-iza+2) = (*wptr)(0,n-iya+2,iza);
01485 (*wptr2)(0,iya,n-iza+2) = (*wptr2)(0,n-iya+2,iza);
01486 (*wptr3)(0,iya,n-iza+2) = (*wptr3)(0,n-iya+2,iza);
01487 }
01488 }
01489 for (int iya = 2; iya <= nxc; iya++) {
01490 cmplx(0,iya,1) += conj(cmplx(0,n-iya+2,1));
01491 (*wptr)(0,iya,1) += (*wptr)(0,n-iya+2,1);
01492 (*wptr2)(0,iya,1) += (*wptr2)(0,n-iya+2,1);
01493 (*wptr3)(0,iya,1) += (*wptr3)(0,n-iya+2,1);
01494
01495 cmplx(0,n-iya+2,1) = conj(cmplx(0,iya,1));
01496 (*wptr)(0,n-iya+2,1) = (*wptr)(0,iya,1);
01497 (*wptr2)(0,n-iya+2,1) = (*wptr2)(0,iya,1);
01498 (*wptr3)(0,n-iya+2,1) = (*wptr3)(0,iya,1);
01499 }
01500 for (int iza = 2; iza <= nxc; iza++) {
01501 cmplx(0,1,iza) += conj(cmplx(0,1,n-iza+2));
01502 (*wptr)(0,1,iza) += (*wptr)(0,1,n-iza+2);
01503 (*wptr2)(0,1,iza) += (*wptr2)(0,1,n-iza+2);
01504 (*wptr3)(0,1,iza) += (*wptr3)(0,1,n-iza+2);
01505
01506 cmplx(0,1,n-iza+2) = conj(cmplx(0,1,iza));
01507 (*wptr)(0,1,n-iza+2) = (*wptr)(0,1,iza);
01508 (*wptr2)(0,1,n-iza+2) = (*wptr2)(0,1,iza);
01509 (*wptr3)(0,1,n-iza+2) = (*wptr3)(0,1,iza);
01510 }
01511 EXITFUNC;
01512 }
01513
01514
01515 class ctf_store
01516 {
01517 public:
01518
01519 static void init( int winsize, const Ctf* ctf )
01520 {
01521 Dict params = ctf->to_dict();
01522
01523 m_winsize = winsize;
01524
01525 m_voltage = params["voltage"];
01526 m_pixel = params["apix"];
01527 m_cs = params["cs"];
01528 m_ampcont = params["ampcont"];
01529 m_bfactor = params["bfactor"];
01530 m_defocus = params["defocus"];
01531 m_winsize2= m_winsize*m_winsize;
01532 m_vecsize = m_winsize2/4;
01533 }
01534
01535 static float get_ctf( int r2 )
01536 {
01537 float ak = std::sqrt( r2/float(m_winsize2) )/m_pixel;
01538 return Util::tf( m_defocus, ak, m_voltage, m_cs, m_ampcont, m_bfactor, 1 );
01539 }
01540
01541 private:
01542
01543 static int m_winsize, m_winsize2, m_vecsize;
01544 static float m_cs;
01545 static float m_voltage;
01546 static float m_pixel;
01547 static float m_ampcont;
01548 static float m_bfactor;
01549 static float m_defocus;
01550 };
01551
01552
01553 int ctf_store::m_winsize, ctf_store::m_winsize2, ctf_store::m_vecsize;
01554
01555 float ctf_store::m_cs, ctf_store::m_voltage, ctf_store::m_pixel;
01556 float ctf_store::m_ampcont, ctf_store::m_bfactor;
01557 float ctf_store::m_defocus;
01558
01559
01560 class ctf_store_new
01561 {
01562 public:
01563
01564 static void init( int winsize, const Ctf* ctf )
01565 {
01566 Dict params = ctf->to_dict();
01567
01568 m_winsize = winsize;
01569
01570 m_voltage = params["voltage"];
01571 m_pixel = params["apix"];
01572 m_cs = params["cs"];
01573 m_ampcont = params["ampcont"];
01574 m_bfactor = params["bfactor"];
01575 m_defocus = params["defocus"];
01576 m_winsize2= m_winsize*m_winsize;
01577 m_vecsize = m_winsize2/4;
01578 }
01579
01580 static float get_ctf( float r2 )
01581 {
01582 float ak = std::sqrt( r2/float(m_winsize2) )/m_pixel;
01583 return Util::tf( m_defocus, ak, m_voltage, m_cs, m_ampcont, m_bfactor, 1 );
01584 }
01585
01586 private:
01587
01588 static int m_winsize, m_winsize2, m_vecsize;
01589 static float m_cs;
01590 static float m_voltage;
01591 static float m_pixel;
01592 static float m_ampcont;
01593 static float m_bfactor;
01594 static float m_defocus;
01595 };
01596
01597
01598 int ctf_store_new::m_winsize, ctf_store_new::m_winsize2, ctf_store_new::m_vecsize;
01599
01600 float ctf_store_new::m_cs, ctf_store_new::m_voltage, ctf_store_new::m_pixel;
01601 float ctf_store_new::m_ampcont, ctf_store_new::m_bfactor;
01602 float ctf_store_new::m_defocus;
01603
01604
01605
01606
01607 void EMData::onelinenn_ctf(int j, int n, int n2,
01608 EMData* w, EMData* bi, const Transform& tf, int mult) {
01609
01610 int remove = bi->get_attr_default( "remove", 0 );
01611
01612 int jp = (j >= 0) ? j+1 : n+j+1;
01613
01614 for (int i = 0; i <= n2; i++) {
01615 int r2 = i*i+j*j;
01616 if ( (r2<n*n/4) && !((0==i) && (j<0)) ) {
01617 float ctf = ctf_store::get_ctf( r2 );
01618 float xnew = i*tf[0][0] + j*tf[1][0];
01619 float ynew = i*tf[0][1] + j*tf[1][1];
01620 float znew = i*tf[0][2] + j*tf[1][2];
01621 std::complex<float> btq;
01622 if (xnew < 0.) {
01623 xnew = -xnew;
01624 ynew = -ynew;
01625 znew = -znew;
01626 btq = conj(bi->cmplx(i,jp));
01627 } else btq = bi->cmplx(i,jp);
01628 int ixn = int(xnew + 0.5 + n) - n;
01629 int iyn = int(ynew + 0.5 + n) - n;
01630 int izn = int(znew + 0.5 + n) - n;
01631
01632 int iza, iya;
01633 if (izn >= 0) iza = izn + 1;
01634 else iza = n + izn + 1;
01635
01636 if (iyn >= 0) iya = iyn + 1;
01637 else iya = n + iyn + 1;
01638
01639 if(remove > 0 ) {
01640 cmplx(ixn,iya,iza) -= btq*ctf*float(mult);
01641 (*w)(ixn,iya,iza) -= ctf*ctf*mult;
01642 } else {
01643 cmplx(ixn,iya,iza) += btq*ctf*float(mult);
01644 (*w)(ixn,iya,iza) += ctf*ctf*mult;
01645 }
01646
01647
01648
01649
01650
01651
01652
01653
01654
01655
01656
01657
01658
01659
01660
01661
01662
01663
01664
01665
01666
01667
01668
01669
01670
01671
01672
01673
01674
01675
01676
01677
01678
01679
01680
01681
01682
01683
01684
01685
01686 }
01687 }
01688 }
01689
01690 void EMData::onelinenn_ctf_applied(int j, int n, int n2,
01691 EMData* w, EMData* bi, const Transform& tf, int mult) {
01692
01693 int remove = bi->get_attr_default( "remove", 0 );
01694
01695 int jp = (j >= 0) ? j+1 : n+j+1;
01696
01697 for (int i = 0; i <= n2; i++) {
01698 int r2 = i*i + j*j;
01699 if ( (r2< n*n/4) && !((0==i) && (j< 0)) ) {
01700 float ctf = ctf_store::get_ctf(r2);
01701
01702
01703 float xnew = i*tf[0][0] + j*tf[1][0];
01704 float ynew = i*tf[0][1] + j*tf[1][1];
01705 float znew = i*tf[0][2] + j*tf[1][2];
01706 std::complex<float> btq;
01707 if (xnew < 0.) {
01708 xnew = -xnew;
01709 ynew = -ynew;
01710 znew = -znew;
01711 btq = conj(bi->cmplx(i,jp));
01712 } else btq = bi->cmplx(i,jp);
01713 int ixn = int(xnew + 0.5 + n) - n;
01714 int iyn = int(ynew + 0.5 + n) - n;
01715 int izn = int(znew + 0.5 + n) - n;
01716
01717 int iza, iya;
01718 if (izn >= 0) iza = izn + 1;
01719 else iza = n + izn + 1;
01720
01721 if (iyn >= 0) iya = iyn + 1;
01722 else iya = n + iyn + 1;
01723
01724 if( remove > 0 ) {
01725 cmplx(ixn,iya,iza) -= btq*float(mult);
01726 (*w)(ixn,iya,iza) -= mult*ctf*ctf;
01727 } else {
01728 cmplx(ixn,iya,iza) += btq*float(mult);
01729 (*w)(ixn,iya,iza) += mult*ctf*ctf;
01730 }
01731
01732
01733
01734
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746
01747
01748
01749
01750
01751
01752
01753
01754
01755
01756
01757
01758
01759
01760
01761
01762
01763
01764
01765
01766
01767
01768
01769 }
01770 }
01771 }
01772
01773 void
01774 EMData::nn_ctf(EMData* w, EMData* myfft, const Transform& tf, int mult) {
01775 ENTERFUNC;
01776 int nxc = attr_dict["nxc"];
01777
01778 vector<int> saved_offsets = get_array_offsets();
01779 vector<int> myfft_saved_offsets = myfft->get_array_offsets();
01780 set_array_offsets(0,1,1);
01781 myfft->set_array_offsets(0,1);
01782
01783 Ctf* ctf = myfft->get_attr("ctf");
01784 ctf_store::init( ny, ctf );
01785 if(ctf) {delete ctf; ctf=0;}
01786
01787
01788 for (int iy = -ny/2 + 1; iy <= ny/2; iy++) onelinenn_ctf(iy, ny, nxc, w, myfft, tf, mult);
01789 set_array_offsets(saved_offsets);
01790 myfft->set_array_offsets(myfft_saved_offsets);
01791 EXITFUNC;
01792 }
01793
01794 void
01795 EMData::nn_ctf_applied(EMData* w, EMData* myfft, const Transform& tf, int mult) {
01796 ENTERFUNC;
01797 int nxc = attr_dict["nxc"];
01798
01799 vector<int> saved_offsets = get_array_offsets();
01800 vector<int> myfft_saved_offsets = myfft->get_array_offsets();
01801 set_array_offsets(0,1,1);
01802 myfft->set_array_offsets(0,1);
01803
01804 Ctf* ctf = myfft->get_attr( "ctf" );
01805 ctf_store::init( ny, ctf );
01806 if(ctf) {delete ctf; ctf=0;}
01807
01808
01809
01810 for (int iy = -ny/2 + 1; iy <= ny/2; iy++) onelinenn_ctf_applied(iy, ny, nxc, w, myfft, tf, mult);
01811 set_array_offsets(saved_offsets);
01812 myfft->set_array_offsets(myfft_saved_offsets);
01813 EXITFUNC;
01814 }
01815
01816
01817 void EMData::insert_rect_slice_ctf(EMData* w, EMData* myfft, const Transform& trans, int sizeofprojection, float xratio, float yratio, int npad, int mult)
01818 {
01819 ENTERFUNC;
01820 vector<int> saved_offsets = get_array_offsets();
01821 vector<int> myfft_saved_offsets = myfft->get_array_offsets();
01822 set_array_offsets(0,1,1);
01823 myfft->set_array_offsets(0,1);
01824
01825
01826
01827 Vec2f coordinate_2d_sqaure;
01828 Vec3f coordinate_3dnew;
01829 Vec3f axis_newx;
01830 Vec3f axis_newy;
01831 Vec3f tempv;
01832
01833
01834
01835 axis_newx[0] = xratio*0.5*(sizeofprojection*npad)*trans[0][0];
01836 axis_newx[1] = yratio*0.5*(sizeofprojection*npad)*trans[0][1];
01837 axis_newx[2] = 0.5*(sizeofprojection*npad)*trans[0][2];
01838
01839 float ellipse_length_x = std::sqrt(axis_newx[0]*axis_newx[0]+axis_newx[1]*axis_newx[1]+axis_newx[2]*axis_newx[2]);
01840
01841 int ellipse_length_x_int = int(ellipse_length_x);
01842 float ellipse_step_x = 0.5*(sizeofprojection*npad)/float(ellipse_length_x_int);
01843 float xscale = ellipse_step_x;
01844
01845 axis_newy[0] = xratio*0.5*(sizeofprojection*npad)*trans[1][0];
01846 axis_newy[1] = yratio*0.5*(sizeofprojection*npad)*trans[1][1];
01847 axis_newy[2] = 0.5*(sizeofprojection*npad)*trans[1][2];
01848
01849
01850
01851 float ellipse_length_y = std::sqrt(axis_newy[0]*axis_newy[0]+axis_newy[1]*axis_newy[1]+axis_newy[2]*axis_newy[2]);
01852 int ellipse_length_y_int = int(ellipse_length_y);
01853 float ellipse_step_y = 0.5*(sizeofprojection*npad)/float(ellipse_length_y_int);
01854 float yscale = ellipse_step_y;
01855
01856 std::complex<float> c1;
01857 nz = get_zsize();
01858 Ctf* ctf = myfft->get_attr( "ctf" );
01859 ctf_store_new::init( nz, ctf );
01860 if(ctf) {delete ctf; ctf=0;}
01861 int remove = myfft->get_attr_default( "remove", 0 );
01862
01863 float r2=0.25*sizeofprojection*npad*sizeofprojection*npad;
01864 float r2_at_point;
01865
01866 for(int i=0;i<ellipse_length_x_int;i++) {
01867 for(int j=-1*ellipse_length_y_int+1; j<=ellipse_length_y_int; j++) {
01868
01869 r2_at_point=i*xscale*i*xscale+j*yscale*j*yscale;
01870 if(r2_at_point<=r2 && ! ((0==i) && (j<0))) {
01871
01872 float ctf_value = ctf_store_new::get_ctf( r2_at_point );
01873 coordinate_2d_sqaure[0] = xscale*float(i);
01874 coordinate_2d_sqaure[1] = yscale*float(j);
01875 float xnew = coordinate_2d_sqaure[0]*trans[0][0] + coordinate_2d_sqaure[1]*trans[1][0];
01876 float ynew = coordinate_2d_sqaure[0]*trans[0][1] + coordinate_2d_sqaure[1]*trans[1][1];
01877 float znew = coordinate_2d_sqaure[0]*trans[0][2] + coordinate_2d_sqaure[1]*trans[1][2];
01878 coordinate_3dnew[0] =xnew*xratio;
01879 coordinate_3dnew[1] = ynew*yratio;
01880 coordinate_3dnew[2] = znew;
01881
01882
01883 float xp = coordinate_2d_sqaure[0];
01884 float yp = ( coordinate_2d_sqaure[1] >= 0) ? coordinate_2d_sqaure[1]+1 : nz+coordinate_2d_sqaure[1]+1;
01885 std::complex<float> lin_interpolated(0,0);
01886 int xlow=int(xp),xhigh=int(xp)+1;
01887 int ylow=int(yp),yhigh=int(yp)+1;
01888 float tx=xp-xlow,ty=yp-ylow;
01889
01890
01891 if(j == -1) {
01892
01893 if(ylow<yp)
01894 lin_interpolated=myfft->cmplx(xlow,ylow)*(1-tx)*(1-ty) + myfft->cmplx(xlow,yhigh)*(1-tx)*ty
01895 + myfft->cmplx(xhigh,ylow)*tx*(1-ty) + myfft->cmplx(xhigh,yhigh)*tx*ty;
01896 else
01897 lin_interpolated=myfft->cmplx(xlow,ylow)*(1-tx)
01898 + myfft->cmplx(xhigh,ylow)*tx;
01899
01900 }
01901 else {
01902 lin_interpolated=myfft->cmplx(xlow,ylow)*(1-tx)*(1-ty) + myfft->cmplx(xlow,yhigh)*(1-tx)*ty
01903 + myfft->cmplx(xhigh,ylow)*tx*(1-ty)+ myfft->cmplx(xhigh,yhigh)*tx*ty;
01904
01905 }
01906
01907 c1 = lin_interpolated;
01908
01909
01910
01911 std::complex<float> btq;
01912 if ( coordinate_3dnew[0] < 0.) {
01913 coordinate_3dnew[0] = -coordinate_3dnew[0];
01914 coordinate_3dnew[1] = -coordinate_3dnew[1];
01915 coordinate_3dnew[2] = -coordinate_3dnew[2];
01916 btq = conj(c1);
01917 } else {
01918 btq = c1;
01919 }
01920 int ixn = int(coordinate_3dnew[0] + 0.5 + nx) - nx;
01921 int iyn = int(coordinate_3dnew[1] + 0.5 + ny) - ny;
01922 int izn = int(coordinate_3dnew[2] + 0.5 + nz) - nz;
01923
01924 int iza, iya;
01925 if (izn >= 0) iza = izn + 1;
01926 else iza = nz + izn + 1;
01927
01928 if (iyn >= 0) iya = iyn + 1;
01929 else iya = ny + iyn + 1;
01930
01931 if(remove > 0 ) {
01932 cmplx(ixn,iya,iza) -= btq*ctf_value*float(mult);
01933 (*w)(ixn,iya,iza) -= ctf_value*ctf_value*mult;
01934 } else {
01935 cmplx(ixn,iya,iza) += btq*ctf_value*float(mult);
01936 (*w)(ixn,iya,iza) += ctf_value*ctf_value*mult;
01937 }
01938
01939 }
01940 }
01941
01942 }
01943
01944
01945
01946
01947 set_array_offsets(saved_offsets);
01948 myfft->set_array_offsets(myfft_saved_offsets);
01949 EXITFUNC;
01950
01951 }
01952
01953
01954 void EMData::insert_rect_slice_ctf_applied(EMData* w, EMData* myfft,const Transform& trans,int sizeofprojection,float xratio,float yratio,int npad,int mult)
01955 {
01956 ENTERFUNC;
01957 vector<int> saved_offsets = get_array_offsets();
01958 vector<int> myfft_saved_offsets = myfft->get_array_offsets();
01959 set_array_offsets(0,1,1);
01960 myfft->set_array_offsets(0,1);
01961
01962
01963
01964 Vec2f coordinate_2d_sqaure;
01965 Vec3f coordinate_3dnew;
01966 Vec3f axis_newx;
01967 Vec3f axis_newy;
01968 Vec3f tempv;
01969
01970
01971
01972 axis_newx[0] = xratio*0.5*(sizeofprojection*npad)*trans[0][0];
01973 axis_newx[1] = yratio*0.5*(sizeofprojection*npad)*trans[0][1];
01974 axis_newx[2] = 0.5*(sizeofprojection*npad)*trans[0][2];
01975
01976 float ellipse_length_x = std::sqrt(axis_newx[0]*axis_newx[0]+axis_newx[1]*axis_newx[1]+axis_newx[2]*axis_newx[2]);
01977
01978 int ellipse_length_x_int = int(ellipse_length_x);
01979 float ellipse_step_x = 0.5*(sizeofprojection*npad)/float(ellipse_length_x_int);
01980 float xscale = ellipse_step_x;
01981
01982 axis_newy[0] = xratio*0.5*(sizeofprojection*npad)*trans[1][0];
01983 axis_newy[1] = yratio*0.5*(sizeofprojection*npad)*trans[1][1];
01984 axis_newy[2] = 0.5*(sizeofprojection*npad)*trans[1][2];
01985
01986
01987
01988 float ellipse_length_y = std::sqrt(axis_newy[0]*axis_newy[0]+axis_newy[1]*axis_newy[1]+axis_newy[2]*axis_newy[2]);
01989 int ellipse_length_y_int = int(ellipse_length_y);
01990 float ellipse_step_y = 0.5*(sizeofprojection*npad)/float(ellipse_length_y_int);
01991 float yscale = ellipse_step_y;
01992
01993 std::complex<float> c1;
01994 nz = get_zsize();
01995 Ctf* ctf = myfft->get_attr( "ctf" );
01996 ctf_store_new::init( nz, ctf );
01997 if(ctf) {delete ctf; ctf=0;}
01998 int remove = myfft->get_attr_default( "remove", 0 );
01999
02000 float r2=0.25*sizeofprojection*npad*sizeofprojection*npad;
02001 float r2_at_point;
02002
02003 for(int i=0;i<ellipse_length_x_int;i++) {
02004 for(int j=-1*ellipse_length_y_int+1; j<=ellipse_length_y_int; j++) {
02005
02006 r2_at_point=i*xscale*i*xscale+j*yscale*j*yscale;
02007 if(r2_at_point<=r2 && ! ((0==i) && (j<0))) {
02008
02009 float ctf_value = ctf_store_new::get_ctf( r2_at_point );
02010 coordinate_2d_sqaure[0] = xscale*float(i);
02011 coordinate_2d_sqaure[1] = yscale*float(j);
02012 float xnew = coordinate_2d_sqaure[0]*trans[0][0] + coordinate_2d_sqaure[1]*trans[1][0];
02013 float ynew = coordinate_2d_sqaure[0]*trans[0][1] + coordinate_2d_sqaure[1]*trans[1][1];
02014 float znew = coordinate_2d_sqaure[0]*trans[0][2] + coordinate_2d_sqaure[1]*trans[1][2];
02015 coordinate_3dnew[0] =xnew*xratio;
02016 coordinate_3dnew[1] = ynew*yratio;
02017 coordinate_3dnew[2] = znew;
02018
02019
02020 float xp = coordinate_2d_sqaure[0];
02021 float yp = ( coordinate_2d_sqaure[1] >= 0) ? coordinate_2d_sqaure[1]+1 : nz+coordinate_2d_sqaure[1]+1;
02022 std::complex<float> lin_interpolated(0,0);
02023 int xlow=int(xp),xhigh=int(xp)+1;
02024 int ylow=int(yp),yhigh=int(yp)+1;
02025 float tx=xp-xlow,ty=yp-ylow;
02026
02027
02028 if(j == -1) {
02029
02030 if(ylow<yp)
02031 lin_interpolated=myfft->cmplx(xlow,ylow)*(1-tx)*(1-ty) + myfft->cmplx(xlow,yhigh)*(1-tx)*ty
02032 + myfft->cmplx(xhigh,ylow)*tx*(1-ty) + myfft->cmplx(xhigh,yhigh)*tx*ty;
02033 else
02034 lin_interpolated=myfft->cmplx(xlow,ylow)*(1-tx)
02035 + myfft->cmplx(xhigh,ylow)*tx;
02036
02037 }
02038 else {
02039 lin_interpolated=myfft->cmplx(xlow,ylow)*(1-tx)*(1-ty) + myfft->cmplx(xlow,yhigh)*(1-tx)*ty
02040 + myfft->cmplx(xhigh,ylow)*tx*(1-ty)+ myfft->cmplx(xhigh,yhigh)*tx*ty;
02041
02042 }
02043
02044 c1 = lin_interpolated;
02045
02046
02047
02048 std::complex<float> btq;
02049 if ( coordinate_3dnew[0] < 0.) {
02050 coordinate_3dnew[0] = -coordinate_3dnew[0];
02051 coordinate_3dnew[1] = -coordinate_3dnew[1];
02052 coordinate_3dnew[2] = -coordinate_3dnew[2];
02053 btq = conj(c1);
02054 } else {
02055 btq = c1;
02056 }
02057 int ixn = int(coordinate_3dnew[0] + 0.5 + nx) - nx;
02058 int iyn = int(coordinate_3dnew[1] + 0.5 + ny) - ny;
02059 int izn = int(coordinate_3dnew[2] + 0.5 + nz) - nz;
02060
02061 int iza, iya;
02062 if (izn >= 0) iza = izn + 1;
02063 else iza = nz + izn + 1;
02064
02065 if (iyn >= 0) iya = iyn + 1;
02066 else iya = ny + iyn + 1;
02067
02068 if(remove > 0 ) {
02069 cmplx(ixn,iya,iza) -= btq*float(mult);
02070 (*w)(ixn,iya,iza) -= ctf_value*ctf_value*mult;
02071 } else {
02072 cmplx(ixn,iya,iza) += btq*float(mult);
02073 (*w)(ixn,iya,iza) += ctf_value*ctf_value*mult;
02074 }
02075
02076 }
02077 }
02078
02079 }
02080
02081
02082
02083
02084 set_array_offsets(saved_offsets);
02085 myfft->set_array_offsets(myfft_saved_offsets);
02086 EXITFUNC;
02087
02088 }
02089
02090
02091
02092
02093
02094
02095
02096
02097
02098
02099
02100
02101
02102
02103
02104
02105
02106
02107
02108
02109
02110
02111
02112
02113
02114
02115
02116
02117
02118
02119
02120
02121
02122
02123
02124
02125
02126
02127
02128
02129
02130
02131
02132
02133
02134
02135
02136
02137
02138
02139
02140
02141
02142
02143
02144
02145
02146
02147
02148
02149
02150
02151
02152
02153
02154
02155
02156
02157
02158
02159 void EMData::nn_SSNR_ctf(EMData* wptr, EMData* wptr2, EMData* wptr3, EMData* myfft, const Transform& tf, int)
02160 {
02161
02162
02163
02164
02165
02166
02167
02168
02169
02170 ENTERFUNC;
02171 int nxc = attr_dict["nxc"];
02172 vector<int> saved_offsets = get_array_offsets();
02173 vector<int> myfft_saved_offsets = myfft->get_array_offsets();
02174 set_array_offsets(0,1,1);
02175 myfft->set_array_offsets(0,1);
02176
02177 Ctf* ctf = myfft->get_attr("ctf");
02178 ctf_store::init( ny, ctf );
02179 int iymin = is_fftodd() ? -ny/2 : -ny/2 + 1;
02180 int iymax = ny/2;
02181 int izmin = is_fftodd() ? -nz/2 : -nz/2 + 1;
02182 int izmax = nz/2;
02183
02184 for (int iy = iymin; iy <= iymax; iy++) {
02185 int jp = iy >= 0 ? iy+1 : ny+iy+1;
02186 for (int ix = 0; ix <= nxc; ix++) {
02187 int r2 = ix*ix+iy*iy;
02188 if (( 4*r2 < ny*ny ) && !( ix == 0 && iy < 0 ) ) {
02189 float ctf = ctf_store::get_ctf( r2 )*10.f;
02190 float xnew = ix*tf[0][0] + iy*tf[1][0];
02191 float ynew = ix*tf[0][1] + iy*tf[1][1];
02192 float znew = ix*tf[0][2] + iy*tf[1][2];
02193 std::complex<float> btq;
02194 if (xnew < 0.0) {
02195 xnew = -xnew;
02196 ynew = -ynew;
02197 znew = -znew;
02198 btq = conj(myfft->cmplx(ix,jp));
02199 } else {
02200 btq = myfft->cmplx(ix,jp);
02201 }
02202 int ixn = int(xnew + 0.5 + nx) - nx;
02203 int iyn = int(ynew + 0.5 + ny) - ny;
02204 int izn = int(znew + 0.5 + nz) - nz;
02205 if ((ixn <= nxc) && (iyn >= iymin) && (iyn <= iymax) && (izn >= izmin) && (izn <= izmax)) {
02206 if (ixn >= 0) {
02207 int iza, iya;
02208 if (izn >= 0) iza = izn + 1;
02209 else iza = nz + izn + 1;
02210
02211 if (iyn >= 0) iya = iyn + 1;
02212 else iya = ny + iyn + 1;
02213
02214 cmplx(ixn,iya,iza) += btq*ctf;
02215 (*wptr)(ixn,iya,iza) += ctf*ctf;
02216 (*wptr2)(ixn,iya,iza) += std::norm(btq);
02217 (*wptr3)(ixn,iya,iza) += 1;
02218 } else {
02219 int izt, iyt;
02220 if (izn > 0) izt = nz - izn + 1;
02221 else izt = -izn + 1;
02222
02223 if (iyn > 0) iyt = ny - iyn + 1;
02224 else iyt = -iyn + 1;
02225
02226 cmplx(-ixn,iyt,izt) += std::conj(btq)*ctf;
02227 (*wptr) (-ixn,iyt,izt) += ctf*ctf;
02228 (*wptr2)(-ixn,iyt,izt) += std::norm(btq);
02229 (*wptr3)(-ixn,iyt,izt) += 1;
02230 }
02231 }
02232 }
02233 }
02234 }
02235 set_array_offsets(saved_offsets);
02236 myfft->set_array_offsets(myfft_saved_offsets);
02237 if(ctf) {delete ctf; ctf=0;}
02238 EXITFUNC;
02239 }
02240
02241
02242
02243
02244
02245
02246
02247
02248
02249
02250
02251
02252
02253
02254
02255
02256
02257
02258
02259
02260
02261
02262
02263
02264
02265
02266
02267
02268
02269
02270
02271
02272
02273
02274
02275
02276
02277
02278
02279
02280
02281
02282
02283
02284
02285
02286
02287
02288
02289
02290
02291
02292
02293
02294
02295
02296
02297
02298
02299
02300
02301
02302
02303
02304
02305
02306
02307
02308
02309
02310
02311
02312
02313
02314
02315
02316
02317
02318
02319
02320
02321
02322
02323
02324
02325
02326
02327
02328
02329
02330
02331
02332
02333
02334
02335
02336
02337
02338
02339 void EMData::symplane0_ctf(EMData* w) {
02340 ENTERFUNC;
02341 int nxc = attr_dict["nxc"];
02342 int n = nxc*2;
02343
02344 vector<int> saved_offsets = get_array_offsets();
02345 set_array_offsets(0,1,1);
02346 for (int iza = 2; iza <= nxc; iza++) {
02347 for (int iya = 2; iya <= nxc; iya++) {
02348 cmplx(0,iya,iza) += conj(cmplx(0,n-iya+2,n-iza+2));
02349 (*w)(0,iya,iza) += (*w)(0,n-iya+2,n-iza+2);
02350 cmplx(0,n-iya+2,n-iza+2) = conj(cmplx(0,iya,iza));
02351 (*w)(0,n-iya+2,n-iza+2) = (*w)(0,iya,iza);
02352 cmplx(0,n-iya+2,iza) += conj(cmplx(0,iya,n-iza+2));
02353 (*w)(0,n-iya+2,iza) += (*w)(0,iya,n-iza+2);
02354 cmplx(0,iya,n-iza+2) = conj(cmplx(0,n-iya+2,iza));
02355 (*w)(0,iya,n-iza+2) = (*w)(0,n-iya+2,iza);
02356 }
02357 }
02358 for (int iya = 2; iya <= nxc; iya++) {
02359 cmplx(0,iya,1) += conj(cmplx(0,n-iya+2,1));
02360 (*w)(0,iya,1) += (*w)(0,n-iya+2,1);
02361 cmplx(0,n-iya+2,1) = conj(cmplx(0,iya,1));
02362 (*w)(0,n-iya+2,1) = (*w)(0,iya,1);
02363 }
02364 for (int iza = 2; iza <= nxc; iza++) {
02365 cmplx(0,1,iza) += conj(cmplx(0,1,n-iza+2));
02366 (*w)(0,1,iza) += (*w)(0,1,n-iza+2);
02367 cmplx(0,1,n-iza+2) = conj(cmplx(0,1,iza));
02368 (*w)(0,1,n-iza+2) = (*w)(0,1,iza);
02369 }
02370 EXITFUNC;
02371 }
02372
02373 void EMData::symplane0_rect(EMData* w) {
02374 ENTERFUNC;
02375 nx=get_xsize();
02376 ny=get_ysize();
02377 nz=get_zsize();
02378 int nzc=nz/2;
02379 int nyc=ny/2;
02380
02381
02382
02383 vector<int> saved_offsets = get_array_offsets();
02384 set_array_offsets(0,1,1);
02385 for (int iza = 2; iza <= nzc; iza++) {
02386 for (int iya = 2; iya <= nyc; iya++) {
02387 cmplx(0,iya,iza) += conj(cmplx(0,ny-iya+2,nz-iza+2));
02388 (*w)(0,iya,iza) += (*w)(0,ny-iya+2,nz-iza+2);
02389 cmplx(0,ny-iya+2,nz-iza+2) = conj(cmplx(0,iya,iza));
02390 (*w)(0,ny-iya+2,nz-iza+2) = (*w)(0,iya,iza);
02391 cmplx(0,ny-iya+2,iza) += conj(cmplx(0,iya,nz-iza+2));
02392 (*w)(0,ny-iya+2,iza) += (*w)(0,iya,nz-iza+2);
02393 cmplx(0,iya,nz-iza+2) = conj(cmplx(0,ny-iya+2,iza));
02394 (*w)(0,iya,nz-iza+2) = (*w)(0,ny-iya+2,iza);
02395 }
02396 }
02397 for (int iya = 2; iya <= nyc; iya++) {
02398 cmplx(0,iya,1) += conj(cmplx(0,ny-iya+2,1));
02399 (*w)(0,iya,1) += (*w)(0,ny-iya+2,1);
02400 cmplx(0,ny-iya+2,1) = conj(cmplx(0,iya,1));
02401 (*w)(0,ny-iya+2,1) = (*w)(0,iya,1);
02402 }
02403 for (int iza = 2; iza <= nzc; iza++) {
02404 cmplx(0,1,iza) += conj(cmplx(0,1,nz-iza+2));
02405 (*w)(0,1,iza) += (*w)(0,1,nz-iza+2);
02406 cmplx(0,1,nz-iza+2) = conj(cmplx(0,1,iza));
02407 (*w)(0,1,nz-iza+2) = (*w)(0,1,iza);
02408 }
02409 EXITFUNC;
02410 }
02411
02412 EMData* EMData::rot_scale_trans2D(float angDeg, float delx, float dely, float scale) {
02413 float ang=angDeg*M_PI/180.0f;
02414 if (1 >= ny)
02415 throw ImageDimensionException("Can't rotate 1D image");
02416 if (nz<2) {
02417 vector<int> saved_offsets = get_array_offsets();
02418 set_array_offsets(0,0,0);
02419 if (0.0f == scale) scale = 1.0f;
02420 EMData* ret = copy_head();
02421 delx = restrict2(delx, nx);
02422 dely = restrict2(dely, ny);
02423
02424 int xc = nx/2;
02425 int yc = ny/2;
02426
02427 float shiftxc = xc + delx;
02428 float shiftyc = yc + dely;
02429
02430 float cang = cos(ang);
02431 float sang = sin(ang);
02432 for (int iy = 0; iy < ny; iy++) {
02433 float y = float(iy) - shiftyc;
02434 float ycang = y*cang/scale + yc;
02435 float ysang = -y*sang/scale + xc;
02436 for (int ix = 0; ix < nx; ix++) {
02437 float x = float(ix) - shiftxc;
02438 float xold = x*cang/scale + ysang ;
02439 float yold = x*sang/scale + ycang ;
02440
02441 (*ret)(ix,iy) = Util::quadri(xold+1.0f, yold+1.0f, nx, ny, get_data());
02442
02443 }
02444 }
02445 set_array_offsets(saved_offsets);
02446 return ret;
02447 } else {
02448 throw ImageDimensionException("Volume not currently supported");
02449 }
02450 }
02451
02452 EMData* EMData::rot_scale_trans2D_background(float angDeg, float delx, float dely, float scale) {
02453 float ang=angDeg*M_PI/180.0f;
02454 if (1 >= ny)
02455 throw ImageDimensionException("Can't rotate 1D image");
02456 if (nz<2) {
02457 vector<int> saved_offsets = get_array_offsets();
02458 set_array_offsets(0,0,0);
02459 if (0.0f == scale) scale = 1.0f;
02460 EMData* ret = copy_head();
02461 delx = restrict2(delx, nx);
02462 dely = restrict2(dely, ny);
02463
02464 int xc = nx/2;
02465 int yc = ny/2;
02466
02467 float shiftxc = xc + delx;
02468 float shiftyc = yc + dely;
02469
02470 float cang = cos(ang);
02471 float sang = sin(ang);
02472 for (int iy = 0; iy < ny; iy++) {
02473 float y = float(iy) - shiftyc;
02474 float ycang = y*cang/scale + yc;
02475 float ysang = -y*sang/scale + xc;
02476 for (int ix = 0; ix < nx; ix++) {
02477 float x = float(ix) - shiftxc;
02478 float xold = x*cang/scale + ysang ;
02479 float yold = x*sang/scale + ycang ;
02480
02481 (*ret)(ix,iy) = Util::quadri_background(xold+1.0f, yold+1.0f, nx, ny, get_data(),ix+1,iy+1);
02482
02483 }
02484 }
02485 set_array_offsets(saved_offsets);
02486 return ret;
02487 } else {
02488 throw ImageDimensionException("Volume not currently supported");
02489 }
02490 }
02491
02492 #define in(i,j,k) in[i+(j+(k*ny))*nx]
02493 EMData*
02494 EMData::rot_scale_trans(const Transform &RA) {
02495
02496 EMData* ret = copy_head();
02497 float *in = this->get_data();
02498 vector<int> saved_offsets = get_array_offsets();
02499 set_array_offsets(0,0,0);
02500 Vec3f translations = RA.get_trans();
02501 Transform RAinv = RA.inverse();
02502
02503 if (1 >= ny) throw ImageDimensionException("Can't rotate 1D image");
02504 if (nz < 2) {
02505 float p1, p2, p3, p4;
02506 float delx = translations.at(0);
02507 float dely = translations.at(1);
02508 delx = restrict2(delx, nx);
02509 dely = restrict2(dely, ny);
02510 int xc = nx/2;
02511 int yc = ny/2;
02512
02513 float shiftxc = xc + delx;
02514 float shiftyc = yc + dely;
02515 for (int iy = 0; iy < ny; iy++) {
02516 float y = float(iy) - shiftyc;
02517 float ysang = y*RAinv[0][1]+xc;
02518 float ycang = y*RAinv[1][1]+yc;
02519 for (int ix = 0; ix < nx; ix++) {
02520 float x = float(ix) - shiftxc;
02521 float xold = x*RAinv[0][0] + ysang;
02522 float yold = x*RAinv[1][0] + ycang;
02523
02524 xold = restrict1(xold, nx);
02525 yold = restrict1(yold, ny);
02526
02527 int xfloor = int(xold);
02528 int yfloor = int(yold);
02529 float t = xold-xfloor;
02530 float u = yold-yfloor;
02531 if(xfloor == nx -1 && yfloor == ny -1) {
02532
02533 p1 =in[xfloor + yfloor*ny];
02534 p2 =in[ yfloor*ny];
02535 p3 =in[0];
02536 p4 =in[xfloor];
02537 } else if(xfloor == nx - 1) {
02538
02539 p1 =in[xfloor + yfloor*ny];
02540 p2 =in[ yfloor*ny];
02541 p3 =in[ (yfloor+1)*ny];
02542 p4 =in[xfloor + (yfloor+1)*ny];
02543 } else if(yfloor == ny - 1) {
02544
02545 p1 =in[xfloor + yfloor*ny];
02546 p2 =in[xfloor+1 + yfloor*ny];
02547 p3 =in[xfloor+1 ];
02548 p4 =in[xfloor ];
02549 } else {
02550 p1 =in[xfloor + yfloor*ny];
02551 p2 =in[xfloor+1 + yfloor*ny];
02552 p3 =in[xfloor+1 + (yfloor+1)*ny];
02553 p4 =in[xfloor + (yfloor+1)*ny];
02554 }
02555 (*ret)(ix,iy) = p1 + u * ( p4 - p1) + t * ( p2 - p1 + u *(p3-p2-p4+p1));
02556 }
02557 }
02558 set_array_offsets(saved_offsets);
02559 return ret;
02560 } else {
02561
02562
02563 float delx = translations.at(0);
02564 float dely = translations.at(1);
02565 float delz = translations.at(2);
02566 delx = restrict2(delx, nx);
02567 dely = restrict2(dely, ny);
02568 delz = restrict2(delz, nz);
02569 int xc = nx/2;
02570 int yc = ny/2;
02571 int zc = nz/2;
02572
02573 float shiftxc = xc + delx;
02574 float shiftyc = yc + dely;
02575 float shiftzc = zc + delz;
02576
02577 for (int iz = 0; iz < nz; iz++) {
02578 float z = float(iz) - shiftzc;
02579 float xoldz = z*RAinv[0][2]+xc;
02580 float yoldz = z*RAinv[1][2]+yc;
02581 float zoldz = z*RAinv[2][2]+zc;
02582 for (int iy = 0; iy < ny; iy++) {
02583 float y = float(iy) - shiftyc;
02584 float xoldzy = xoldz + y*RAinv[0][1] ;
02585 float yoldzy = yoldz + y*RAinv[1][1] ;
02586 float zoldzy = zoldz + y*RAinv[2][1] ;
02587 for (int ix = 0; ix < nx; ix++) {
02588 float x = float(ix) - shiftxc;
02589 float xold = xoldzy + x*RAinv[0][0] ;
02590 float yold = yoldzy + x*RAinv[1][0] ;
02591 float zold = zoldzy + x*RAinv[2][0] ;
02592
02593 xold = restrict1(xold, nx);
02594 yold = restrict1(yold, ny);
02595 zold = restrict1(zold, nz);
02596
02597
02598 int IOX = int(xold);
02599 int IOY = int(yold);
02600 int IOZ = int(zold);
02601
02602 #ifdef _WIN32
02603 int IOXp1 = _cpp_min( nx-1 ,IOX+1);
02604 #else
02605 int IOXp1 = std::min( nx-1 ,IOX+1);
02606 #endif //_WIN32
02607
02608 #ifdef _WIN32
02609 int IOYp1 = _cpp_min( ny-1 ,IOY+1);
02610 #else
02611 int IOYp1 = std::min( ny-1 ,IOY+1);
02612 #endif //_WIN32
02613
02614 #ifdef _WIN32
02615 int IOZp1 = _cpp_min( nz-1 ,IOZ+1);
02616 #else
02617 int IOZp1 = std::min( nz-1 ,IOZ+1);
02618 #endif //_WIN32
02619
02620 float dx = xold-IOX;
02621 float dy = yold-IOY;
02622 float dz = zold-IOZ;
02623
02624 float a1 = in(IOX,IOY,IOZ);
02625 float a2 = in(IOXp1,IOY,IOZ) - in(IOX,IOY,IOZ);
02626 float a3 = in(IOX,IOYp1,IOZ) - in(IOX,IOY,IOZ);
02627 float a4 = in(IOX,IOY,IOZp1) - in(IOX,IOY,IOZ);
02628 float a5 = in(IOX,IOY,IOZ) - in(IOXp1,IOY,IOZ) - in(IOX,IOYp1,IOZ) + in(IOXp1,IOYp1,IOZ);
02629 float a6 = in(IOX,IOY,IOZ) - in(IOXp1,IOY,IOZ) - in(IOX,IOY,IOZp1) + in(IOXp1,IOY,IOZp1);
02630 float a7 = in(IOX,IOY,IOZ) - in(IOX,IOYp1,IOZ) - in(IOX,IOY,IOZp1) + in(IOX,IOYp1,IOZp1);
02631 float a8 = in(IOXp1,IOY,IOZ) + in(IOX,IOYp1,IOZ)+ in(IOX,IOY,IOZp1)
02632 - in(IOX,IOY,IOZ)- in(IOXp1,IOYp1,IOZ) - in(IOXp1,IOY,IOZp1)
02633 - in(IOX,IOYp1,IOZp1) + in(IOXp1,IOYp1,IOZp1);
02634 (*ret)(ix,iy,iz) = a1 + dz*(a4 + a6*dx + (a7 + a8*dx)*dy) + a3*dy + dx*(a2 + a5*dy);
02635 }
02636 }
02637 }
02638
02639 set_array_offsets(saved_offsets);
02640 return ret;
02641
02642
02643
02644
02645
02646
02647
02648
02649
02650
02651
02652
02653
02654
02655
02656
02657
02658
02659
02660
02661
02662
02663
02664
02665
02666
02667
02668
02669
02670
02671
02672
02673
02674
02675
02676
02677
02678
02679
02680
02681
02682
02683
02684
02685
02686
02687
02688
02689
02690
02691
02692
02693
02694
02695
02696
02697
02698
02699
02700
02701
02702
02703
02704
02705
02706
02707
02708
02709
02710
02711
02712
02713
02714
02715
02716
02717
02718
02719
02720
02721
02722
02723
02724
02725
02726
02727
02728
02729
02730
02731
02732
02733
02734
02735
02736
02737
02738
02739
02740
02741
02742
02743
02744
02745
02746
02747
02748
02749
02750
02751
02752
02753
02754
02755
02756 }
02757 }
02758 #undef in
02759
02760
02761 #define in(i,j,k) in[i+(j+(k*ny))*nx]
02762 EMData*
02763 EMData::rot_scale_trans_background(const Transform &RA) {
02764 EMData* ret = copy_head();
02765 float *in = this->get_data();
02766 vector<int> saved_offsets = get_array_offsets();
02767 set_array_offsets(0,0,0);
02768 Vec3f translations = RA.get_trans();
02769 Transform RAinv = RA.inverse();
02770
02771 if (1 >= ny) throw ImageDimensionException("Can't rotate 1D image");
02772 if (nz < 2) {
02773 float p1, p2, p3, p4;
02774 float delx = translations.at(0);
02775 float dely = translations.at(1);
02776 delx = restrict2(delx, nx);
02777 dely = restrict2(dely, ny);
02778 int xc = nx/2;
02779 int yc = ny/2;
02780
02781 float shiftxc = xc + delx;
02782 float shiftyc = yc + dely;
02783 for (int iy = 0; iy < ny; iy++) {
02784 float y = float(iy) - shiftyc;
02785 float ysang = y*RAinv[0][1]+xc;
02786 float ycang = y*RAinv[1][1]+yc;
02787 for (int ix = 0; ix < nx; ix++) {
02788 float x = float(ix) - shiftxc;
02789 float xold = x*RAinv[0][0] + ysang;
02790 float yold = x*RAinv[1][0] + ycang;
02791
02792
02793
02794 if ( (xold < 0.0f) || (xold >= (float)(nx)) || (yold < 0.0f) || (yold >= (float)(ny)) ){
02795 xold = (float)ix;
02796 yold = (float)iy;
02797 }
02798
02799 int xfloor = int(xold);
02800 int yfloor = int(yold);
02801 float t = xold-xfloor;
02802 float u = yold-yfloor;
02803 if(xfloor == nx -1 && yfloor == ny -1) {
02804
02805 p1 =in[xfloor + yfloor*ny];
02806 p2 =in[ yfloor*ny];
02807 p3 =in[0];
02808 p4 =in[xfloor];
02809 } else if(xfloor == nx - 1) {
02810
02811 p1 =in[xfloor + yfloor*ny];
02812 p2 =in[ yfloor*ny];
02813 p3 =in[ (yfloor+1)*ny];
02814 p4 =in[xfloor + (yfloor+1)*ny];
02815 } else if(yfloor == ny - 1) {
02816
02817 p1 =in[xfloor + yfloor*ny];
02818 p2 =in[xfloor+1 + yfloor*ny];
02819 p3 =in[xfloor+1 ];
02820 p4 =in[xfloor ];
02821 } else {
02822
02823 p1 =in[xfloor + yfloor*ny];
02824 p2 =in[xfloor+1 + yfloor*ny];
02825 p3 =in[xfloor+1 + (yfloor+1)*ny];
02826 p4 =in[xfloor + (yfloor+1)*ny];
02827 }
02828 (*ret)(ix,iy) = p1 + u * ( p4 - p1) + t * ( p2 - p1 + u *(p3-p2-p4+p1));
02829 }
02830 }
02831 set_array_offsets(saved_offsets);
02832 return ret;
02833 } else {
02834
02835
02836 float delx = translations.at(0);
02837 float dely = translations.at(1);
02838 float delz = translations.at(2);
02839 delx = restrict2(delx, nx);
02840 dely = restrict2(dely, ny);
02841 delz = restrict2(delz, nz);
02842 int xc = nx/2;
02843 int yc = ny/2;
02844 int zc = nz/2;
02845
02846 float shiftxc = xc + delx;
02847 float shiftyc = yc + dely;
02848 float shiftzc = zc + delz;
02849
02850 for (int iz = 0; iz < nz; iz++) {
02851 float z = float(iz) - shiftzc;
02852 float xoldz = z*RAinv[0][2]+xc;
02853 float yoldz = z*RAinv[1][2]+yc;
02854 float zoldz = z*RAinv[2][2]+zc;
02855 for (int iy = 0; iy < ny; iy++) {
02856 float y = float(iy) - shiftyc;
02857 float xoldzy = xoldz + y*RAinv[0][1] ;
02858 float yoldzy = yoldz + y*RAinv[1][1] ;
02859 float zoldzy = zoldz + y*RAinv[2][1] ;
02860 for (int ix = 0; ix < nx; ix++) {
02861 float x = float(ix) - shiftxc;
02862 float xold = xoldzy + x*RAinv[0][0] ;
02863 float yold = yoldzy + x*RAinv[1][0] ;
02864 float zold = zoldzy + x*RAinv[2][0] ;
02865
02866
02867
02868 if ( (xold < 0.0f) || (xold >= (float)(nx)) || (yold < 0.0f) || (yold >= (float)(ny)) || (zold < 0.0f) || (zold >= (float)(nz)) ){
02869 xold = (float)ix;
02870 yold = (float)iy;
02871 zold = (float)iz;
02872 }
02873
02874 int IOX = int(xold);
02875 int IOY = int(yold);
02876 int IOZ = int(zold);
02877
02878 #ifdef _WIN32
02879 int IOXp1 = _cpp_min( nx-1 ,IOX+1);
02880 #else
02881 int IOXp1 = std::min( nx-1 ,IOX+1);
02882 #endif //_WIN32
02883
02884 #ifdef _WIN32
02885 int IOYp1 = _cpp_min( ny-1 ,IOY+1);
02886 #else
02887 int IOYp1 = std::min( ny-1 ,IOY+1);
02888 #endif //_WIN32
02889
02890 #ifdef _WIN32
02891 int IOZp1 = _cpp_min( nz-1 ,IOZ+1);
02892 #else
02893 int IOZp1 = std::min( nz-1 ,IOZ+1);
02894 #endif //_WIN32
02895
02896 float dx = xold-IOX;
02897 float dy = yold-IOY;
02898 float dz = zold-IOZ;
02899
02900 float a1 = in(IOX,IOY,IOZ);
02901 float a2 = in(IOXp1,IOY,IOZ) - in(IOX,IOY,IOZ);
02902 float a3 = in(IOX,IOYp1,IOZ) - in(IOX,IOY,IOZ);
02903 float a4 = in(IOX,IOY,IOZp1) - in(IOX,IOY,IOZ);
02904 float a5 = in(IOX,IOY,IOZ) - in(IOXp1,IOY,IOZ) - in(IOX,IOYp1,IOZ) + in(IOXp1,IOYp1,IOZ);
02905 float a6 = in(IOX,IOY,IOZ) - in(IOXp1,IOY,IOZ) - in(IOX,IOY,IOZp1) + in(IOXp1,IOY,IOZp1);
02906 float a7 = in(IOX,IOY,IOZ) - in(IOX,IOYp1,IOZ) - in(IOX,IOY,IOZp1) + in(IOX,IOYp1,IOZp1);
02907 float a8 = in(IOXp1,IOY,IOZ) + in(IOX,IOYp1,IOZ)+ in(IOX,IOY,IOZp1)
02908 - in(IOX,IOY,IOZ)- in(IOXp1,IOYp1,IOZ) - in(IOXp1,IOY,IOZp1)
02909 - in(IOX,IOYp1,IOZp1) + in(IOXp1,IOYp1,IOZp1);
02910 (*ret)(ix,iy,iz) = a1 + dz*(a4 + a6*dx + (a7 + a8*dx)*dy) + a3*dy + dx*(a2 + a5*dy);
02911 }
02912 }
02913 }
02914
02915 set_array_offsets(saved_offsets);
02916 return ret;
02917
02918 }
02919 }
02920 #undef in
02921
02922
02923
02924
02925
02926
02927
02928
02929
02930
02931
02932
02933
02934
02935
02936
02937
02938
02939
02940
02941
02942
02943
02944
02945
02946
02947
02948
02949
02950
02951
02952
02953
02954
02955
02956
02957
02958
02959
02960
02961
02962
02963
02964
02965
02966
02967
02968
02969
02970
02971
02972
02973
02974
02975
02976
02977
02978
02979
02980
02981
02982
02983
02984
02985
02986
02987
02988
02989
02990
02991
02992
02993
02994
02995
02996
02997
02998 EMData* EMData::rot_scale_conv(float ang, float delx, float dely, Util::KaiserBessel& kb, float scale_input) {
02999 int nxn, nyn, nzn;
03000 if(scale_input == 0.0f) scale_input = 1.0f;
03001
03002 float scale = 0.5f*scale_input;
03003 float sum, w;
03004 if (1 >= ny)
03005 throw ImageDimensionException("Can't rotate 1D image");
03006 if (1 < nz)
03007 throw ImageDimensionException("Volume not currently supported");
03008 nxn=nx/2;nyn=ny/2;nzn=nz/2;
03009
03010 int K = kb.get_window_size();
03011 int kbmin = -K/2;
03012 int kbmax = -kbmin;
03013 int kbc = kbmax+1;
03014 vector<int> saved_offsets = get_array_offsets();
03015 set_array_offsets(0,0,0);
03016 EMData* ret = this->copy_head();
03017 #ifdef _WIN32
03018 ret->set_size(nxn, _cpp_max(nyn,1), _cpp_max(nzn,1));
03019 #else
03020 ret->set_size(nxn, std::max(nyn,1), std::max(nzn,1));
03021 #endif //_WIN32
03022
03023 delx = restrict2(delx, nx);
03024 dely = restrict2(dely, ny);
03025
03026 int xc = nxn;
03027 int ixs = nxn%2;
03028 int yc = nyn;
03029 int iys = nyn%2;
03030
03031 int xcn = nxn/2;
03032 int ycn = nyn/2;
03033
03034 float shiftxc = xcn + delx;
03035 float shiftyc = ycn + dely;
03036
03037 float ymin = -ny/2.0f;
03038 float xmin = -nx/2.0f;
03039 float ymax = -ymin;
03040 float xmax = -xmin;
03041 if (0 == nx%2) xmax--;
03042 if (0 == ny%2) ymax--;
03043
03044 float *t = (float*)calloc(kbmax-kbmin+1, sizeof(float));
03045
03046
03047 float cang = cos(ang);
03048 float sang = sin(ang);
03049 for (int iy = 0; iy < nyn; iy++) {
03050 float y = float(iy) - shiftyc;
03051 float ycang = y*cang/scale + yc;
03052 float ysang = -y*sang/scale + xc;
03053 for (int ix = 0; ix < nxn; ix++) {
03054 float x = float(ix) - shiftxc;
03055 float xold = x*cang/scale + ysang-ixs;
03056 float yold = x*sang/scale + ycang-iys;
03057
03058 xold = restrict1(xold, nx);
03059 yold = restrict1(yold, ny);
03060
03061 int inxold = int(Util::round(xold)); int inyold = int(Util::round(yold));
03062 sum=0.0f; w=0.0f;
03063 for (int m1 =kbmin; m1 <=kbmax; m1++) t[m1-kbmin] = kb.i0win_tab(xold - inxold-m1);
03064 if(inxold <= kbc || inxold >=nx-kbc-2 || inyold <= kbc || inyold >=ny-kbc-2 ) {
03065 for (int m2 =kbmin; m2 <=kbmax; m2++) {
03066 float qt = kb.i0win_tab(yold - inyold-m2);
03067 for (int m1 =kbmin; m1 <=kbmax; m1++) {
03068 float q = t[m1-kbmin]*qt;
03069 sum += (*this)((inxold+m1+nx)%nx,(inyold+m2+ny)%ny)*q; w+=q;
03070 }
03071 }
03072 } else {
03073 for (int m2 =kbmin; m2 <=kbmax; m2++) {
03074 float qt = kb.i0win_tab(yold - inyold-m2);
03075 for (int m1 =kbmin; m1 <=kbmax; m1++) {
03076 float q = t[m1-kbmin]*qt;
03077 sum += (*this)(inxold+m1,inyold+m2)*q; w+=q;}
03078 }
03079 }
03080 (*ret)(ix,iy)=sum/w;
03081 }
03082 }
03083 if (t) free(t);
03084 set_array_offsets(saved_offsets);
03085 return ret;
03086 }
03087
03088
03089
03090 EMData* EMData::rot_scale_conv7(float ang, float delx, float dely, Util::KaiserBessel& kb, float scale_input) {
03091 int nxn, nyn, nzn;
03092 float scale = 0.5f*scale_input;
03093 float sum, w;
03094 if (1 >= ny)
03095 throw ImageDimensionException("Can't rotate 1D image");
03096 if (1 < nz)
03097 throw ImageDimensionException("Volume not currently supported");
03098 nxn = nx/2; nyn=ny/2; nzn=nz/2;
03099
03100 int K = kb.get_window_size();
03101 int kbmin = -K/2;
03102 int kbmax = -kbmin;
03103 int kbc = kbmax+1;
03104 vector<int> saved_offsets = get_array_offsets();
03105 set_array_offsets(0,0,0);
03106 EMData* ret = this->copy_head();
03107 #ifdef _WIN32
03108 ret->set_size(nxn, _cpp_max(nyn,1), _cpp_max(nzn,1));
03109 #else
03110 ret->set_size(nxn, std::max(nyn,1), std::max(nzn,1));
03111 #endif //_WIN32
03112
03113 delx = restrict2(delx, nx);
03114 dely = restrict2(dely, ny);
03115
03116 int xc = nxn;
03117 int ixs = nxn%2;
03118 int yc = nyn;
03119 int iys = nyn%2;
03120
03121 int xcn = nxn/2;
03122 int ycn = nyn/2;
03123
03124 float shiftxc = xcn + delx;
03125 float shiftyc = ycn + dely;
03126
03127 float ymin = -ny/2.0f;
03128 float xmin = -nx/2.0f;
03129 float ymax = -ymin;
03130 float xmax = -xmin;
03131 if (0 == nx%2) xmax--;
03132 if (0 == ny%2) ymax--;
03133
03134 float *t = (float*)calloc(kbmax-kbmin+1, sizeof(float));
03135
03136
03137 float cang = cos(ang);
03138 float sang = sin(ang);
03139 for (int iy = 0; iy < nyn; iy++) {
03140 float y = float(iy) - shiftyc;
03141 float ycang = y*cang/scale + yc;
03142 float ysang = -y*sang/scale + xc;
03143 for (int ix = 0; ix < nxn; ix++) {
03144 float x = float(ix) - shiftxc;
03145 float xold = x*cang/scale + ysang-ixs;
03146 float yold = x*sang/scale + ycang-iys;
03147
03148 xold = restrict1(xold, nx);
03149 yold = restrict1(yold, ny);
03150
03151 int inxold = int(Util::round(xold)); int inyold = int(Util::round(yold));
03152 sum=0.0f; w=0.0f;
03153
03154 float tablex1 = kb.i0win_tab(xold-inxold+3);
03155 float tablex2 = kb.i0win_tab(xold-inxold+2);
03156 float tablex3 = kb.i0win_tab(xold-inxold+1);
03157 float tablex4 = kb.i0win_tab(xold-inxold);
03158 float tablex5 = kb.i0win_tab(xold-inxold-1);
03159 float tablex6 = kb.i0win_tab(xold-inxold-2);
03160 float tablex7 = kb.i0win_tab(xold-inxold-3);
03161
03162 float tabley1 = kb.i0win_tab(yold-inyold+3);
03163 float tabley2 = kb.i0win_tab(yold-inyold+2);
03164 float tabley3 = kb.i0win_tab(yold-inyold+1);
03165 float tabley4 = kb.i0win_tab(yold-inyold);
03166 float tabley5 = kb.i0win_tab(yold-inyold-1);
03167 float tabley6 = kb.i0win_tab(yold-inyold-2);
03168 float tabley7 = kb.i0win_tab(yold-inyold-3);
03169
03170 int x1, x2, x3, x4, x5, x6, x7, y1, y2, y3, y4, y5, y6, y7;
03171
03172 if(inxold <= kbc || inxold >=nx-kbc-2 || inyold <= kbc || inyold >=ny-kbc-2 ) {
03173 x1 = (inxold-3+nx)%nx;
03174 x2 = (inxold-2+nx)%nx;
03175 x3 = (inxold-1+nx)%nx;
03176 x4 = (inxold +nx)%nx;
03177 x5 = (inxold+1+nx)%nx;
03178 x6 = (inxold+2+nx)%nx;
03179 x7 = (inxold+3+nx)%nx;
03180
03181 y1 = (inyold-3+ny)%ny;
03182 y2 = (inyold-2+ny)%ny;
03183 y3 = (inyold-1+ny)%ny;
03184 y4 = (inyold +ny)%ny;
03185 y5 = (inyold+1+ny)%ny;
03186 y6 = (inyold+2+ny)%ny;
03187 y7 = (inyold+3+ny)%ny;
03188 } else {
03189 x1 = inxold-3;
03190 x2 = inxold-2;
03191 x3 = inxold-1;
03192 x4 = inxold;
03193 x5 = inxold+1;
03194 x6 = inxold+2;
03195 x7 = inxold+3;
03196
03197 y1 = inyold-3;
03198 y2 = inyold-2;
03199 y3 = inyold-1;
03200 y4 = inyold;
03201 y5 = inyold+1;
03202 y6 = inyold+2;
03203 y7 = inyold+3;
03204 }
03205 sum = ( (*this)(x1,y1)*tablex1 + (*this)(x2,y1)*tablex2 + (*this)(x3,y1)*tablex3 +
03206 (*this)(x4,y1)*tablex4 + (*this)(x5,y1)*tablex5 + (*this)(x6,y1)*tablex6 +
03207 (*this)(x7,y1)*tablex7 ) * tabley1 +
03208 ( (*this)(x1,y2)*tablex1 + (*this)(x2,y2)*tablex2 + (*this)(x3,y2)*tablex3 +
03209 (*this)(x4,y2)*tablex4 + (*this)(x5,y2)*tablex5 + (*this)(x6,y2)*tablex6 +
03210 (*this)(x7,y2)*tablex7 ) * tabley2 +
03211 ( (*this)(x1,y3)*tablex1 + (*this)(x2,y3)*tablex2 + (*this)(x3,y3)*tablex3 +
03212 (*this)(x4,y3)*tablex4 + (*this)(x5,y3)*tablex5 + (*this)(x6,y3)*tablex6 +
03213 (*this)(x7,y3)*tablex7 ) * tabley3 +
03214 ( (*this)(x1,y4)*tablex1 + (*this)(x2,y4)*tablex2 + (*this)(x3,y4)*tablex3 +
03215 (*this)(x4,y4)*tablex4 + (*this)(x5,y4)*tablex5 + (*this)(x6,y4)*tablex6 +
03216 (*this)(x7,y4)*tablex7 ) * tabley4 +
03217 ( (*this)(x1,y5)*tablex1 + (*this)(x2,y5)*tablex2 + (*this)(x3,y5)*tablex3 +
03218 (*this)(x4,y5)*tablex4 + (*this)(x5,y5)*tablex5 + (*this)(x6,y5)*tablex6 +
03219 (*this)(x7,y5)*tablex7 ) * tabley5 +
03220 ( (*this)(x1,y6)*tablex1 + (*this)(x2,y6)*tablex2 + (*this)(x3,y6)*tablex3 +
03221 (*this)(x4,y6)*tablex4 + (*this)(x5,y6)*tablex5 + (*this)(x6,y6)*tablex6 +
03222 (*this)(x7,y6)*tablex7 ) * tabley6 +
03223 ( (*this)(x1,y7)*tablex1 + (*this)(x2,y7)*tablex2 + (*this)(x3,y7)*tablex3 +
03224 (*this)(x4,y7)*tablex4 + (*this)(x5,y7)*tablex5 + (*this)(x6,y7)*tablex6 +
03225 (*this)(x7,y7)*tablex7 ) * tabley7;
03226
03227 w = (tablex1+tablex2+tablex3+tablex4+tablex5+tablex6+tablex7) *
03228 (tabley1+tabley2+tabley3+tabley4+tabley5+tabley6+tabley7);
03229
03230 (*ret)(ix,iy)=sum/w;
03231 }
03232 }
03233 if (t) free(t);
03234 set_array_offsets(saved_offsets);
03235 return ret;
03236 }
03237
03238 EMData* EMData::downsample(Util::sincBlackman& kb, float scale) {
03239
03240
03241
03242
03243
03244 int nxn, nyn, nzn;
03245 nxn = (int)(nx*scale); nyn = (int)(ny*scale); nzn = (int)(nz*scale);
03246
03247 vector<int> saved_offsets = get_array_offsets();
03248 set_array_offsets(0,0,0);
03249 EMData* ret = this->copy_head();
03250 #ifdef _WIN32
03251 ret->set_size(nxn, _cpp_max(nyn,1), _cpp_max(nzn,1));
03252 #else
03253 ret->set_size(nxn, std::max(nyn,1), std::max(nzn,1));
03254 #endif //_WIN32
03255 ret->to_zero();
03256
03257
03258 for (int iy =0; iy < nyn; iy++) {
03259 float y = float(iy)/scale;
03260 for (int ix = 0; ix < nxn; ix++) {
03261 float x = float(ix)/scale;
03262 (*ret)(ix,iy) = this->get_pixel_filtered(x, y, 1.0f, kb);
03263 }
03264 }
03265 set_array_offsets(saved_offsets);
03266 return ret;
03267 }
03268
03269
03270 EMData* EMData::rot_scale_conv_new(float ang, float delx, float dely, Util::KaiserBessel& kb, float scale_input) {
03271
03272 if (scale_input == 0.0f) scale_input = 1.0f;
03273 float scale = 0.5f*scale_input;
03274
03275 if (1 >= ny)
03276 throw ImageDimensionException("Can't rotate 1D image");
03277 if (1 < nz)
03278 throw ImageDimensionException("Use rot_scale_conv_new_3D for volumes");
03279 int nxn = nx/2; int nyn = ny/2; int nzn = nz/2;
03280
03281 vector<int> saved_offsets = get_array_offsets();
03282 set_array_offsets(0,0,0);
03283 EMData* ret = this->copy_head();
03284 #ifdef _WIN32
03285 ret->set_size(nxn, _cpp_max(nyn,1), _cpp_max(nzn,1));
03286 #else
03287 ret->set_size(nxn, std::max(nyn,1), std::max(nzn,1));
03288 #endif //_WIN32
03289
03290 delx = restrict2(delx, nx);
03291 dely = restrict2(dely, ny);
03292
03293 int xc = nxn;
03294 int ixs = nxn%2;
03295 int yc = nyn;
03296 int iys = nyn%2;
03297
03298 int xcn = nxn/2;
03299 int ycn = nyn/2;
03300
03301 float shiftxc = xcn + delx;
03302 float shiftyc = ycn + dely;
03303
03304 float ymin = -ny/2.0f;
03305 float xmin = -nx/2.0f;
03306 float ymax = -ymin;
03307 float xmax = -xmin;
03308 if (0 == nx%2) xmax--;
03309 if (0 == ny%2) ymax--;
03310
03311 float* data = this->get_data();
03312
03313 float cang = cos(ang);
03314 float sang = sin(ang);
03315 for (int iy = 0; iy < nyn; iy++) {
03316 float y = float(iy) - shiftyc;
03317 float ycang = y*cang/scale + yc;
03318 float ysang = -y*sang/scale + xc;
03319 for (int ix = 0; ix < nxn; ix++) {
03320 float x = float(ix) - shiftxc;
03321 float xold = x*cang/scale + ysang-ixs;
03322 float yold = x*sang/scale + ycang-iys;
03323
03324 (*ret)(ix,iy) = Util::get_pixel_conv_new(nx, ny, 1, xold, yold, 1, data, kb);
03325 }
03326 }
03327 set_array_offsets(saved_offsets);
03328 return ret;
03329 }
03330
03331 EMData* EMData::rot_scale_conv_new_3D(float phi, float theta, float psi, float delx, float dely, float delz, Util::KaiserBessel& kb, float scale_input) {
03332
03333 if (scale_input == 0.0f) scale_input = 1.0f;
03334 float scale = 0.5f*scale_input;
03335
03336 if (1 >= ny)
03337 throw ImageDimensionException("Can't rotate 1D image");
03338 int nxn = nx/2; int nyn = ny/2; int nzn = nz/2;
03339
03340 vector<int> saved_offsets = get_array_offsets();
03341 set_array_offsets(0,0,0);
03342 EMData* ret = this->copy_head();
03343 #ifdef _WIN32
03344 ret->set_size(nxn, _cpp_max(nyn,1), _cpp_max(nzn,1));
03345 #else
03346 ret->set_size(nxn, std::max(nyn,1), std::max(nzn,1));
03347 #endif //_WIN32
03348
03349 delx = restrict2(delx, nx);
03350 dely = restrict2(dely, ny);
03351 delz = restrict2(delz, nz);
03352
03353 int xc = nxn;
03354 int ixs = nxn%2;
03355 int yc = nyn;
03356 int iys = nyn%2;
03357 int zc = nzn;
03358 int izs = nzn%2;
03359
03360 int xcn = nxn/2;
03361 int ycn = nyn/2;
03362 int zcn = nzn/2;
03363
03364 float shiftxc = xcn + delx;
03365 float shiftyc = ycn + dely;
03366 float shiftzc = zcn + delz;
03367
03368 float zmin = -nz/2.0f;
03369 float ymin = -ny/2.0f;
03370 float xmin = -nx/2.0f;
03371 float zmax = -zmin;
03372 float ymax = -ymin;
03373 float xmax = -xmin;
03374 if (0 == nx%2) xmax--;
03375 if (0 == ny%2) ymax--;
03376 if (0 == nz%2) zmax--;
03377
03378 float* data = this->get_data();
03379
03380 float cf = cos(phi); float sf = sin(phi);
03381 float ct = cos(theta); float st = sin(theta);
03382 float cp = cos(psi); float sp = sin(psi);
03383
03384 float a11 = cp*ct*cf-sp*sf; float a12 = cp*ct*sf+sp*cf; float a13 = -cp*st;
03385 float a21 = -sp*ct*cf-cp*sf; float a22 = -sp*ct*sf+cp*cf; float a23 = sp*st;
03386 float a31 = st*cf; float a32 = st*sf; float a33 = ct;
03387 for (int iz = 0; iz < nzn; iz++) {
03388 float z = (float(iz) - shiftzc)/scale;
03389 float zco1 = a31*z+xc;
03390 float zco2 = a32*z+yc;
03391 float zco3 = a33*z+zc;
03392 for (int iy = 0; iy < nyn; iy++) {
03393 float y = (float(iy) - shiftyc)/scale;
03394 float yco1 = zco1+a21*y;
03395 float yco2 = zco2+a22*y;
03396 float yco3 = zco3+a23*y;
03397 for (int ix = 0; ix < nxn; ix++) {
03398 float x = (float(ix) - shiftxc)/scale;
03399 float xold = yco1+a11*x-ixs;
03400 float yold = yco2+a12*x-iys;
03401 float zold = yco3+a13*x-izs;
03402 (*ret)(ix,iy,iz) = Util::get_pixel_conv_new(nx, ny, nz, xold, yold, zold, data, kb);
03403 }
03404 }
03405 }
03406 set_array_offsets(saved_offsets);
03407 return ret;
03408 }
03409
03410 EMData* EMData::rot_scale_conv_new_background(float ang, float delx, float dely, Util::KaiserBessel& kb, float scale_input) {
03411
03412 int nxn, nyn, nzn;
03413
03414 if (scale_input == 0.0f) scale_input = 1.0f;
03415 float scale = 0.5f*scale_input;
03416
03417 if (1 >= ny)
03418 throw ImageDimensionException("Can't rotate 1D image");
03419 if (1 < nz)
03420 throw ImageDimensionException("Use rot_scale_conv_new_background_3D for volumes");
03421 nxn = nx/2; nyn = ny/2; nzn = nz/2;
03422
03423 vector<int> saved_offsets = get_array_offsets();
03424 set_array_offsets(0,0,0);
03425 EMData* ret = this->copy_head();
03426 #ifdef _WIN32
03427 ret->set_size(nxn, _cpp_max(nyn,1), _cpp_max(nzn,1));
03428 #else
03429 ret->set_size(nxn, std::max(nyn,1), std::max(nzn,1));
03430 #endif //_WIN32
03431
03432 delx = restrict2(delx, nx);
03433 dely = restrict2(dely, ny);
03434
03435 int xc = nxn;
03436 int ixs = nxn%2;
03437 int yc = nyn;
03438 int iys = nyn%2;
03439
03440 int xcn = nxn/2;
03441 int ycn = nyn/2;
03442
03443 float shiftxc = xcn + delx;
03444 float shiftyc = ycn + dely;
03445
03446 float ymin = -ny/2.0f;
03447 float xmin = -nx/2.0f;
03448 float ymax = -ymin;
03449 float xmax = -xmin;
03450 if (0 == nx%2) xmax--;
03451 if (0 == ny%2) ymax--;
03452
03453 float* data = this->get_data();
03454
03455
03456 float cang = cos(ang);
03457 float sang = sin(ang);
03458 for (int iy = 0; iy < nyn; iy++) {
03459 float y = float(iy) - shiftyc;
03460 float ycang = y*cang/scale + yc;
03461 float ysang = -y*sang/scale + xc;
03462 for (int ix = 0; ix < nxn; ix++) {
03463 float x = float(ix) - shiftxc;
03464 float xold = x*cang/scale + ysang-ixs;
03465 float yold = x*sang/scale + ycang-iys;
03466
03467 (*ret)(ix,iy) = Util::get_pixel_conv_new_background(nx, ny, 1, xold, yold, 1, data, kb, ix, iy);
03468 }
03469 }
03470 set_array_offsets(saved_offsets);
03471 return ret;
03472 }
03473
03474 EMData* EMData::rot_scale_conv_new_background_3D(float phi, float theta, float psi, float delx, float dely, float delz, Util::KaiserBessel& kb, float scale_input) {
03475
03476 if (scale_input == 0.0f) scale_input = 1.0f;
03477 float scale = 0.5f*scale_input;
03478
03479 if (1 >= ny)
03480 throw ImageDimensionException("Can't rotate 1D image");
03481 int nxn = nx/2; int nyn = ny/2; int nzn = nz/2;
03482
03483 vector<int> saved_offsets = get_array_offsets();
03484 set_array_offsets(0,0,0);
03485 EMData* ret = this->copy_head();
03486 #ifdef _WIN32
03487 ret->set_size(nxn, _cpp_max(nyn,1), _cpp_max(nzn,1));
03488 #else
03489 ret->set_size(nxn, std::max(nyn,1), std::max(nzn,1));
03490 #endif //_WIN32
03491
03492 delx = restrict2(delx, nx);
03493 dely = restrict2(dely, ny);
03494 delz = restrict2(delz, nz);
03495
03496 int xc = nxn;
03497 int ixs = nxn%2;
03498 int yc = nyn;
03499 int iys = nyn%2;
03500 int zc = nzn;
03501 int izs = nzn%2;
03502
03503 int xcn = nxn/2;
03504 int ycn = nyn/2;
03505 int zcn = nzn/2;
03506
03507 float shiftxc = xcn + delx;
03508 float shiftyc = ycn + dely;
03509 float shiftzc = zcn + delz;
03510
03511 float zmin = -nz/2.0f;
03512 float ymin = -ny/2.0f;
03513 float xmin = -nx/2.0f;
03514 float zmax = -zmin;
03515 float ymax = -ymin;
03516 float xmax = -xmin;
03517 if (0 == nx%2) xmax--;
03518 if (0 == ny%2) ymax--;
03519 if (0 == nz%2) zmax--;
03520
03521 float* data = this->get_data();
03522
03523 float cf = cos(phi); float sf = sin(phi);
03524 float ct = cos(theta); float st = sin(theta);
03525 float cp = cos(psi); float sp = sin(psi);
03526
03527 float a11 = cp*ct*cf-sp*sf; float a12 = cp*ct*sf+sp*cf; float a13 = -cp*st;
03528 float a21 = -sp*ct*cf-cp*sf; float a22 = -sp*ct*sf+cp*cf; float a23 = sp*st;
03529 float a31 = st*cf; float a32 = st*sf; float a33 = ct;
03530 for (int iz = 0; iz < nzn; iz++) {
03531 float z = (float(iz) - shiftzc)/scale;
03532 float zco1 = a31*z+xc;
03533 float zco2 = a32*z+yc;
03534 float zco3 = a33*z+zc;
03535 for (int iy = 0; iy < nyn; iy++) {
03536 float y = (float(iy) - shiftyc)/scale;
03537 float yco1 = zco1+a21*y;
03538 float yco2 = zco2+a22*y;
03539 float yco3 = zco3+a23*y;
03540 for (int ix = 0; ix < nxn; ix++) {
03541 float x = (float(ix) - shiftxc)/scale;
03542 float xold = yco1+a11*x-ixs;
03543 float yold = yco2+a12*x-iys;
03544 float zold = yco3+a13*x-izs;
03545 (*ret)(ix,iy,iz) = Util::get_pixel_conv_new_background(nx, ny, nz, xold, yold, zold, data, kb, ix, iy);
03546 }
03547 }
03548 }
03549 set_array_offsets(saved_offsets);
03550 return ret;
03551 }
03552
03553
03554 float EMData::get_pixel_conv(float delx, float dely, float delz, Util::KaiserBessel& kb) {
03555
03556
03557 int K = kb.get_window_size();
03558 int kbmin = -K/2;
03559 int kbmax = -kbmin;
03560 int kbc = kbmax+1;
03561
03562 float pixel =0.0f;
03563 float w=0.0f;
03564
03565 delx = restrict2(delx, nx);
03566 int inxold = int(Util::round(delx));
03567 if(ny<2) {
03568 if(inxold <= kbc || inxold >=nx-kbc-2 ) {
03569
03570 for (int m1 =kbmin; m1 <=kbmax; m1++) {
03571 float q = kb.i0win_tab(delx - inxold-m1);
03572 pixel += (*this)((inxold+m1+nx)%nx)*q; w+=q;
03573 }
03574 } else {
03575 for (int m1 =kbmin; m1 <=kbmax; m1++) {
03576 float q = kb.i0win_tab(delx - inxold-m1);
03577 pixel += (*this)(inxold+m1)*q; w+=q;
03578 }
03579 }
03580
03581 } else if(nz<2) {
03582 dely = restrict2(dely, ny);
03583 int inyold = int(Util::round(dely));
03584 if(inxold <= kbc || inxold >=nx-kbc-2 || inyold <= kbc || inyold >=ny-kbc-2 ) {
03585
03586 for (int m2 =kbmin; m2 <=kbmax; m2++){ for (int m1 =kbmin; m1 <=kbmax; m1++) {
03587 float q = kb.i0win_tab(delx - inxold-m1)*kb.i0win_tab(dely - inyold-m2);
03588 pixel += (*this)((inxold+m1+nx)%nx,(inyold+m2+ny)%ny)*q; w+=q;}
03589 }
03590 } else {
03591 for (int m2 =kbmin; m2 <=kbmax; m2++){ for (int m1 =kbmin; m1 <=kbmax; m1++) {
03592 float q = kb.i0win_tab(delx - inxold-m1)*kb.i0win_tab(dely - inyold-m2);
03593 pixel += (*this)(inxold+m1,inyold+m2)*q; w+=q;}
03594 }
03595 }
03596 } else {
03597 dely = restrict2(dely, ny);
03598 int inyold = int(Util::round(dely));
03599 delz = restrict2(delz, nz);
03600 int inzold = int(Util::round(delz));
03601
03602 if(inxold <= kbc || inxold >=nx-kbc-2 || inyold <= kbc || inyold >=ny-kbc-2 || inzold <= kbc || inzold >=nz-kbc-2 ) {
03603
03604 for (int m3 =kbmin; m3 <=kbmax; m3++){ for (int m2 =kbmin; m2 <=kbmax; m2++){ for (int m1 =kbmin; m1 <=kbmax; m1++) {
03605 float q = kb.i0win_tab(delx - inxold-m1)*kb.i0win_tab(dely - inyold-m2)*kb.i0win_tab(delz - inzold-m3);
03606
03607 pixel += (*this)((inxold+m1+nx)%nx,(inyold+m2+ny)%ny,(inzold+m3+nz)%nz)*q ;w+=q;}}
03608 }
03609 } else {
03610 for (int m3 =kbmin; m3 <=kbmax; m3++){ for (int m2 =kbmin; m2 <=kbmax; m2++){ for (int m1 =kbmin; m1 <=kbmax; m1++) {
03611 float q = kb.i0win_tab(delx - inxold-m1)*kb.i0win_tab(dely - inyold-m2)*kb.i0win_tab(delz - inzold-m3);
03612
03613 pixel += (*this)(inxold+m1,inyold+m2,inzold+m3)*q; w+=q;}}
03614 }
03615 }
03616 }
03617 return pixel/w;
03618 }
03619
03620
03621 float EMData::get_pixel_filtered(float delx, float dely, float delz, Util::sincBlackman& kb) {
03622
03623
03624 int K = kb.get_sB_size();
03625 int kbmin = -K/2;
03626 int kbmax = -kbmin;
03627 int kbc = kbmax+1;
03628
03629 float pixel =0.0f;
03630 float w=0.0f;
03631
03632
03633 int inxold = int(Util::round(delx));
03634
03635
03636
03637
03638
03639
03640
03641
03642
03643
03644
03645
03646
03647
03648
03649
03650 int inyold = int(Util::round(dely));
03651 if(inxold <= kbc || inxold >=nx-kbc-2 || inyold <= kbc || inyold >=ny-kbc-2 ) {
03652
03653 for (int m2 =kbmin; m2 <=kbmax; m2++){
03654 float t = kb.sBwin_tab(dely - inyold-m2);
03655 for (int m1 =kbmin; m1 <=kbmax; m1++) {
03656 float q = kb.sBwin_tab(delx - inxold-m1)*t;
03657 pixel += (*this)((inxold+m1+nx)%nx,(inyold+m2+ny)%ny)*q;
03658 w += q;
03659 }
03660 }
03661 } else {
03662 for (int m2 =kbmin; m2 <=kbmax; m2++){
03663 float t = kb.sBwin_tab(dely - inyold-m2);
03664 for (int m1 =kbmin; m1 <=kbmax; m1++) {
03665 float q = kb.sBwin_tab(delx - inxold-m1)*t;
03666 pixel += (*this)(inxold+m1,inyold+m2)*q;
03667 w += q;
03668 }
03669 }
03670 }
03671
03672
03673
03674
03675
03676
03677
03678
03679
03680
03681
03682
03683
03684
03685
03686
03687
03688
03689
03690
03691
03692 return pixel/w;
03693 }
03694
03695
03696
03697
03698 float EMData::get_pixel_conv7(float delx, float dely, float delz, Util::KaiserBessel& kb) {
03699
03700
03701 float *image=(this->get_data());
03702 int nx = this->get_xsize();
03703 int ny = this->get_ysize();
03704 int nz = this->get_zsize();
03705
03706 float result;
03707
03708 result = Util::get_pixel_conv_new(nx,ny,nz,delx,dely,delz,image,kb);
03709 return result;
03710 }
03711
03712 float EMData::getconvpt2d_kbi0(float x, float y, Util::KaiserBessel::kbi0_win win, int size) {
03713 const int nxhalf = nx/2;
03714 const int nyhalf = ny/2;
03715 const int bd = size/2;
03716 float* wxarr = new float[size];
03717 float* wyarr = new float[size];
03718 float* wx = wxarr + bd;
03719 float* wy = wyarr + bd;
03720 int ixc = int(x + 0.5f*Util::sgn(x));
03721 int iyc = int(y + 0.5f*Util::sgn(y));
03722 if (abs(ixc) > nxhalf)
03723 throw InvalidValueException(ixc, "getconv: X value out of range");
03724 if (abs(iyc) > nyhalf)
03725 throw InvalidValueException(ixc, "getconv: Y value out of range");
03726 for (int i = -bd; i <= bd; i++) {
03727 int iyp = iyc + i;
03728 wy[i] = win(y - iyp);
03729 int ixp = ixc + i;
03730 wx[i] = win(x - ixp);
03731 }
03732 vector<int> saved_offsets = get_array_offsets();
03733 set_array_offsets(-nxhalf, -nyhalf);
03734 float conv = 0.f, wsum = 0.f;
03735 for (int iy = -bd; iy <= bd; iy++) {
03736 int iyp = iyc + iy;
03737 for (int ix = -bd; ix <= bd; ix++) {
03738 int ixp = ixc + ix;
03739 float wg = wx[ix]*wy[iy];
03740 conv += (*this)(ixp,iyp)*wg;
03741 wsum += wg;
03742 }
03743 }
03744 set_array_offsets(saved_offsets);
03745 delete [] wxarr;
03746 delete [] wyarr;
03747
03748 return conv;
03749 }
03750
03751 std::complex<float> EMData::extractpoint(float nuxnew, float nuynew, Util::KaiserBessel& kb) {
03752 if (2 != get_ndim())
03753 throw ImageDimensionException("extractpoint needs a 2-D image.");
03754 if (!is_complex())
03755 throw ImageFormatException("extractpoint requires a fourier image");
03756 int nxreal = nx - 2;
03757 if (nxreal != ny)
03758 throw ImageDimensionException("extractpoint requires ny == nx");
03759 int nhalf = nxreal/2;
03760 int kbsize = kb.get_window_size();
03761 int kbmin = -kbsize/2;
03762 int kbmax = -kbmin;
03763 bool flip = (nuxnew < 0.f);
03764 if (flip) {
03765 nuxnew *= -1;
03766 nuynew *= -1;
03767 }
03768
03769
03770
03771 int ixn = int(Util::round(nuxnew));
03772 int iyn = int(Util::round(nuynew));
03773
03774 float* wy0 = new float[kbmax - kbmin + 1];
03775 float* wy = wy0 - kbmin;
03776 float* wx0 = new float[kbmax - kbmin + 1];
03777 float* wx = wx0 - kbmin;
03778 for (int i = kbmin; i <= kbmax; i++) {
03779 int iyp = iyn + i;
03780 wy[i] = kb.i0win_tab(nuynew - iyp);
03781 int ixp = ixn + i;
03782 wx[i] = kb.i0win_tab(nuxnew - ixp);
03783 }
03784
03785 int iymin = 0;
03786 for (int iy = kbmin; iy <= -1; iy++) {
03787 if (wy[iy] != 0.f) {
03788 iymin = iy;
03789 break;
03790 }
03791 }
03792 int iymax = 0;
03793 for (int iy = kbmax; iy >= 1; iy--) {
03794 if (wy[iy] != 0.f) {
03795 iymax = iy;
03796 break;
03797 }
03798 }
03799 int ixmin = 0;
03800 for (int ix = kbmin; ix <= -1; ix++) {
03801 if (wx[ix] != 0.f) {
03802 ixmin = ix;
03803 break;
03804 }
03805 }
03806 int ixmax = 0;
03807 for (int ix = kbmax; ix >= 1; ix--) {
03808 if (wx[ix] != 0.f) {
03809 ixmax = ix;
03810 break;
03811 }
03812 }
03813 float wsum = 0.0f;
03814 for (int iy = iymin; iy <= iymax; iy++)
03815 for (int ix = ixmin; ix <= ixmax; ix++)
03816 wsum += wx[ix]*wy[iy];
03817 std::complex<float> result(0.f,0.f);
03818 if ((ixn >= -kbmin) && (ixn <= nhalf-1-kbmax) && (iyn >= -nhalf-kbmin) && (iyn <= nhalf-1-kbmax)) {
03819
03820 for (int iy = iymin; iy <= iymax; iy++) {
03821 int iyp = iyn + iy;
03822 for (int ix = ixmin; ix <= ixmax; ix++) {
03823 int ixp = ixn + ix;
03824 float w = wx[ix]*wy[iy];
03825 std::complex<float> val = cmplx(ixp,iyp);
03826 result += val*w;
03827 }
03828 }
03829 } else {
03830
03831 for (int iy = iymin; iy <= iymax; iy++) {
03832 int iyp = iyn + iy;
03833 for (int ix = ixmin; ix <= ixmax; ix++) {
03834 int ixp = ixn + ix;
03835 bool mirror = false;
03836 int ixt= ixp, iyt= iyp;
03837 if (ixt < 0) {
03838 ixt = -ixt;
03839 iyt = -iyt;
03840 mirror = !mirror;
03841 }
03842 if (ixt > nhalf) {
03843 ixt = nxreal - ixt;
03844 iyt = -iyt;
03845 mirror = !mirror;
03846 }
03847 if (iyt > nhalf-1) iyt -= nxreal;
03848 if (iyt < -nhalf) iyt += nxreal;
03849 float w = wx[ix]*wy[iy];
03850 std::complex<float> val = this->cmplx(ixt,iyt);
03851 if (mirror) result += conj(val)*w;
03852 else result += val*w;
03853 }
03854 }
03855 }
03856 if (flip) result = conj(result)/wsum;
03857 else result /= wsum;
03858 delete [] wx0;
03859 delete [] wy0;
03860 return result;
03861 }
03862
03863 EMData* EMData::extractline(Util::KaiserBessel& kb, float nuxnew, float nuynew)
03864 {
03865 if (!is_complex())
03866 throw ImageFormatException("extractline requires a fourier image");
03867 if (nx%2 != 0)
03868 throw ImageDimensionException("extractline requires nx to be even");
03869 int nxreal = nx - 2;
03870 if (nxreal != ny)
03871 throw ImageDimensionException("extractline requires ny == nx");
03872
03873 EMData* res = new EMData();
03874 res->set_size(nx,1,1);
03875 res->to_zero();
03876 res->set_complex(true);
03877 res->set_fftodd(false);
03878 res->set_fftpad(true);
03879 res->set_ri(true);
03880
03881 int n = nxreal;
03882 int nhalf = n/2;
03883 vector<int> saved_offsets = get_array_offsets();
03884 set_array_offsets(0,-nhalf,-nhalf);
03885
03886
03887 int kbsize = kb.get_window_size();
03888 int kbmin = -kbsize/2;
03889 int kbmax = -kbmin;
03890 float* wy0 = new float[kbmax - kbmin + 1];
03891 float* wy = wy0 - kbmin;
03892 float* wx0 = new float[kbmax - kbmin + 1];
03893 float* wx = wx0 - kbmin;
03894
03895 int count = 0;
03896 float wsum = 0.f;
03897 bool flip = (nuxnew < 0.f);
03898
03899 for (int jx = 0; jx <= nhalf; jx++) {
03900 float xnew = jx*nuxnew, ynew = jx*nuynew;
03901 count++;
03902 std::complex<float> btq(0.f,0.f);
03903 if (flip) {
03904 xnew = -xnew;
03905 ynew = -ynew;
03906 }
03907 int ixn = int(Util::round(xnew));
03908 int iyn = int(Util::round(ynew));
03909
03910 for (int i=kbmin; i <= kbmax; i++) {
03911 int iyp = iyn + i;
03912 wy[i] = kb.i0win_tab(ynew - iyp);
03913 int ixp = ixn + i;
03914 wx[i] = kb.i0win_tab(xnew - ixp);
03915 }
03916
03917
03918 int lnby = 0;
03919 for (int iy = kbmin; iy <= -1; iy++) {
03920 if (wy[iy] != 0.f) {
03921 lnby = iy;
03922 break;
03923 }
03924 }
03925 int lney = 0;
03926 for (int iy = kbmax; iy >= 1; iy--) {
03927 if (wy[iy] != 0.f) {
03928 lney = iy;
03929 break;
03930 }
03931 }
03932 int lnbx = 0;
03933 for (int ix = kbmin; ix <= -1; ix++) {
03934 if (wx[ix] != 0.f) {
03935 lnbx = ix;
03936 break;
03937 }
03938 }
03939 int lnex = 0;
03940 for (int ix = kbmax; ix >= 1; ix--) {
03941 if (wx[ix] != 0.f) {
03942 lnex = ix;
03943 break;
03944 }
03945 }
03946 if (ixn >= -kbmin && ixn <= nhalf-1-kbmax
03947 && iyn >= -nhalf-kbmin && iyn <= nhalf-1-kbmax) {
03948
03949 for (int ly=lnby; ly<=lney; ly++) {
03950 int iyp = iyn + ly;
03951 for (int lx=lnbx; lx<=lnex; lx++) {
03952 int ixp = ixn + lx;
03953 float wg = wx[lx]*wy[ly];
03954 btq += cmplx(ixp,iyp)*wg;
03955 wsum += wg;
03956 }
03957 }
03958 } else {
03959
03960 for (int ly=lnby; ly<=lney; ly++) {
03961 int iyp = iyn + ly;
03962 for (int lx=lnbx; lx<=lnex; lx++) {
03963 int ixp = ixn + lx;
03964 float wg = wx[lx]*wy[ly];
03965 bool mirror = false;
03966 int ixt(ixp), iyt(iyp);
03967 if (ixt > nhalf || ixt < -nhalf) {
03968 ixt = Util::sgn(ixt)*(n - abs(ixt));
03969 iyt = -iyt;
03970 mirror = !mirror;
03971 }
03972 if (iyt >= nhalf || iyt < -nhalf) {
03973 if (ixt != 0) {
03974 ixt = -ixt;
03975 iyt = Util::sgn(iyt)*(n - abs(iyt));
03976 mirror = !mirror;
03977 } else {
03978 iyt -= n*Util::sgn(iyt);
03979 }
03980 }
03981 if (ixt < 0) {
03982 ixt = -ixt;
03983 iyt = -iyt;
03984 mirror = !mirror;
03985 }
03986 if (iyt == nhalf) iyt = -nhalf;
03987 if (mirror) btq += conj(cmplx(ixt,iyt))*wg;
03988 else btq += cmplx(ixt,iyt)*wg;
03989 wsum += wg;
03990 }
03991 }
03992 }
03993 if (flip) res->cmplx(jx) = conj(btq);
03994 else res->cmplx(jx) = btq;
03995 }
03996 for (int jx = 0; jx <= nhalf; jx++) res->cmplx(jx) *= count/wsum;
03997
03998 delete[] wx0; delete[] wy0;
03999 set_array_offsets(saved_offsets);
04000 res->set_array_offsets(0,0,0);
04001 return res;
04002 }
04003
04004
04006 inline void swapx(float* a, float* b, float* temp, size_t nbytes) {
04007 memcpy(temp, a, nbytes);
04008 memcpy(a, b, nbytes);
04009 memcpy(b, temp, nbytes);
04010 }
04011
04012 void EMData::fft_shuffle() {
04013 if (!is_complex())
04014 throw ImageFormatException("fft_shuffle requires a fourier image");
04015 vector<int> offsets = get_array_offsets();
04016 set_array_offsets();
04017 EMData& self = *this;
04018 int nyhalf = ny/2;
04019 int nzhalf = nz/2;
04020 int nbytes = nx*sizeof(float);
04021 float* temp = new float[nx];
04022 for (int iz=0; iz < nz; iz++)
04023 for (int iy=0; iy < nyhalf; iy++)
04024 swapx(&self(0,iy,iz),&self(0,iy+nyhalf,iz),temp,nbytes);
04025 if (nz > 1) {
04026 for (int iy=0; iy < ny; iy++)
04027 for (int iz=0; iz < nzhalf; iz++)
04028 swapx(&self(0,iy,iz),&self(0,iy,iz+nzhalf),temp,nbytes);
04029 }
04030 set_shuffled(!is_shuffled());
04031 set_array_offsets(offsets);
04032 update();
04033 delete[] temp;
04034 }
04035
04036 void EMData::pad_corner(float *pad_image) {
04037 int nbytes = nx*sizeof(float);
04038 for (int iy=0; iy<ny; iy++)
04039 memcpy(&(*this)(0,iy), pad_image+3+(iy+3)*nx, nbytes);
04040 }
04041
04042 void EMData::shuffle_pad_corner(float *pad_image) {
04043 int nyhalf = ny/2;
04044 int nbytes = nx*sizeof(float);
04045 for (int iy = 0; iy < nyhalf; iy++)
04046 memcpy(&(*this)(0,iy), pad_image+6+(iy+nyhalf+3)*nx, nbytes);
04047 for (int iy = nyhalf; iy < ny; iy++)
04048 memcpy(&(*this)(0,iy), pad_image+6+(iy-nyhalf+3)*nx, nbytes);
04049 }
04050
04051 #define QUADPI 3.141592653589793238462643383279502884197
04052 #define DGR_TO_RAD QUADPI/180
04053
04054
04055
04056
04057
04058
04059
04060
04061
04062
04063
04064
04065
04066
04067
04068
04069
04070
04071
04072
04073
04074
04075
04076
04077
04078
04079
04080
04081
04082
04083
04084
04085
04086
04087
04088
04089
04090
04091
04092
04093
04094
04095
04096
04097
04098
04099
04100
04101
04102
04103
04104
04105
04106
04107 EMData* EMData::fouriergridrot2d(float ang, float scale, Util::KaiserBessel& kb) {
04108 if (2 != get_ndim())
04109 throw ImageDimensionException("fouriergridrot2d needs a 2-D image.");
04110 if (!is_complex())
04111 throw ImageFormatException("fouriergridrot2d requires a fourier image");
04112 int nxreal = nx - 2 + int(is_fftodd());
04113 if (nxreal != ny)
04114 throw ImageDimensionException("fouriergridrot2d requires ny == nx(real)");
04115 if (0 != nxreal%2)
04116 throw ImageDimensionException("fouriergridrot2d needs an even image.");
04117 if (scale == 0.0f) scale = 1.0f;
04118 int nxhalf = nxreal/2;
04119 int nyhalf = ny/2;
04120 float cir = (float)((nxhalf-1)*(nxhalf-1));
04121
04122 if (!is_shuffled()) fft_shuffle();
04123
04124 EMData* result = copy_head();
04125 set_array_offsets(0,-nyhalf);
04126 result->set_array_offsets(0,-nyhalf);
04127
04128
04129
04130 ang = ang*(float)DGR_TO_RAD;
04131 float cang = cos(ang);
04132 float sang = sin(ang);
04133 for (int iy = -nyhalf; iy < nyhalf; iy++) {
04134 float ycang = iy*cang;
04135 float ysang = iy*sang;
04136 for (int ix = 0; ix <= nxhalf; ix++) {
04137 float nuxold = (ix*cang - ysang)*scale;
04138 float nuyold = (ix*sang + ycang)*scale;
04139 if (nuxold*nuxold+nuyold*nuyold<cir) result->cmplx(ix,iy) = Util::extractpoint2(nx, ny, nuxold, nuyold, this, kb);
04140
04141 }
04142 }
04143 result->set_array_offsets();
04144 result->fft_shuffle();
04145 result->update();
04146 set_array_offsets();
04147 fft_shuffle();
04148 return result;
04149 }
04150
04151 EMData* EMData::fouriergridrot_shift2d(float ang, float sx, float sy, Util::KaiserBessel& kb) {
04152 if (2 != get_ndim())
04153 throw ImageDimensionException("fouriergridrot_shift2d needs a 2-D image.");
04154 if (!is_complex())
04155 throw ImageFormatException("fouriergridrot_shift2d requires a fourier image");
04156 int nxreal = nx - 2 + int(is_fftodd());
04157 if (nxreal != ny)
04158 throw ImageDimensionException("fouriergridrot_shift2d requires ny == nx(real)");
04159 if (0 != nxreal%2)
04160 throw ImageDimensionException("fouriergridrot_shift2d needs an even image.");
04161 int nxhalf = nxreal/2;
04162 int nyhalf = ny/2;
04163
04164 if (!is_shuffled()) fft_shuffle();
04165
04166 EMData* result = copy_head();
04167 set_array_offsets(0, -nyhalf);
04168 result->set_array_offsets(0, -nyhalf);
04169
04170 ang = ang*(float)DGR_TO_RAD;
04171 float cang = cos(ang);
04172 float sang = sin(ang);
04173 float temp = -2.0f*M_PI/nxreal;
04174 for (int iy = -nyhalf; iy < nyhalf; iy++) {
04175 float ycang = iy*cang;
04176 float ysang = iy*sang;
04177 for (int ix = 0; ix <= nxhalf; ix++) {
04178 float nuxold = ix*cang - ysang;
04179 float nuyold = ix*sang + ycang;
04180 result->cmplx(ix,iy) = Util::extractpoint2(nx, ny, nuxold, nuyold, this, kb);
04181
04182 float phase_ang = temp*(sx*ix+sy*iy);
04183 result->cmplx(ix,iy) *= complex<float>(cos(phase_ang), sin(phase_ang));
04184 }
04185 }
04186 result->set_array_offsets();
04187 result->fft_shuffle();
04188 result->update();
04189 set_array_offsets();
04190 fft_shuffle();
04191 return result;
04192 }
04193
04194 #undef QUADPI
04195 #undef DGR_TO_RAD
04196
04197 void EMData::divkbsinh(const Util::KaiserBessel& kb) {
04198
04199 if (is_complex())
04200 throw ImageFormatException("divkbsinh requires a real image.");
04201 vector<int> saved_offsets = get_array_offsets();
04202 set_array_offsets(0,0,0);
04203
04204
04205
04206
04207 for (int iz=0; iz < nz; iz++) {
04208 float wz = kb.sinhwin(static_cast<float>(iz-nz/2));
04209 for (int iy=0; iy < ny; iy++) {
04210 float wy = kb.sinhwin(static_cast<float>(iy-ny/2));
04211 for (int ix=0; ix < nx; ix++) {
04212 float wx = kb.sinhwin(static_cast<float>(ix-nx/2));
04213 float w = wx*wy*wz;
04214 (*this)(ix,iy,iz) /= w;
04215 }
04216 }
04217 }
04218 set_array_offsets(saved_offsets);
04219 }
04220
04221 void EMData::divkbsinh_rect(const Util::KaiserBessel& kbx, const Util::KaiserBessel& kby, const Util::KaiserBessel& kbz) {
04222
04223 if (is_complex())
04224 throw ImageFormatException("divkbsinh requires a real image.");
04225 vector<int> saved_offsets = get_array_offsets();
04226 set_array_offsets(0,0,0);
04227
04228
04229
04230
04231 for (int iz=0; iz < nz; iz++) {
04232 float wz = kbz.sinhwin(static_cast<float>(iz-nz/2));
04233 for (int iy=0; iy < ny; iy++) {
04234 float wy = kby.sinhwin(static_cast<float>(iy-ny/2));
04235 for (int ix=0; ix < nx; ix++) {
04236 float wx = kbx.sinhwin(static_cast<float>(ix-nx/2));
04237 float w = wx*wy*wz;
04238 (*this)(ix,iy,iz) /= w;
04239 }
04240 }
04241 }
04242
04243 set_array_offsets(saved_offsets);
04244 }
04245
04246
04247
04248
04249
04250
04251
04252
04253
04254
04255
04256
04257
04258
04259
04260
04261
04262
04263
04264
04265
04266
04267
04268
04269
04270
04271
04272 EMData* EMData::extract_plane(const Transform& tf, Util::KaiserBessel& kb) {
04273 if (!is_complex())
04274 throw ImageFormatException("extractplane requires a complex image");
04275 if (nx%2 != 0)
04276 throw ImageDimensionException("extractplane requires nx to be even");
04277 int nxreal = nx - 2;
04278 if (nxreal != ny || nxreal != nz)
04279 throw ImageDimensionException("extractplane requires ny == nx == nz");
04280
04281 EMData* res = new EMData();
04282 res->set_size(nx,ny,1);
04283 res->to_zero();
04284 res->set_complex(true);
04285 res->set_fftodd(false);
04286 res->set_fftpad(true);
04287 res->set_ri(true);
04288
04289 int n = nxreal;
04290 int nhalf = n/2;
04291 vector<int> saved_offsets = get_array_offsets();
04292 set_array_offsets(0,-nhalf,-nhalf);
04293 res->set_array_offsets(0,-nhalf,0);
04294
04295 int kbsize = kb.get_window_size();
04296 int kbmin = -kbsize/2;
04297 int kbmax = -kbmin;
04298 float* wy0 = new float[kbmax - kbmin + 1];
04299 float* wy = wy0 - kbmin;
04300 float* wx0 = new float[kbmax - kbmin + 1];
04301 float* wx = wx0 - kbmin;
04302 float* wz0 = new float[kbmax - kbmin + 1];
04303 float* wz = wz0 - kbmin;
04304 float rim = nhalf*float(nhalf);
04305 int count = 0;
04306 float wsum = 0.f;
04307 Transform tftrans = tf;
04308 tftrans.invert();
04309 for (int jy = -nhalf; jy < nhalf; jy++)
04310 {
04311 for (int jx = 0; jx <= nhalf; jx++)
04312 {
04313 Vec3f nucur((float)jx, (float)jy, 0.f);
04314 Vec3f nunew = tftrans*nucur;
04315 float xnew = nunew[0], ynew = nunew[1], znew = nunew[2];
04316 if (xnew*xnew+ynew*ynew+znew*znew <= rim)
04317 {
04318 count++;
04319 std::complex<float> btq(0.f,0.f);
04320 bool flip = false;
04321 if (xnew < 0.f) {
04322 flip = true;
04323 xnew = -xnew;
04324 ynew = -ynew;
04325 znew = -znew;
04326 }
04327 int ixn = int(Util::round(xnew));
04328 int iyn = int(Util::round(ynew));
04329 int izn = int(Util::round(znew));
04330
04331 for (int i=kbmin; i <= kbmax; i++) {
04332 int izp = izn + i;
04333 wz[i] = kb.i0win_tab(znew - izp);
04334 int iyp = iyn + i;
04335 wy[i] = kb.i0win_tab(ynew - iyp);
04336 int ixp = ixn + i;
04337 wx[i] = kb.i0win_tab(xnew - ixp);
04338
04339 }
04340
04341 int lnbz = 0;
04342 for (int iz = kbmin; iz <= -1; iz++) {
04343 if (wz[iz] != 0.f) {
04344 lnbz = iz;
04345 break;
04346 }
04347 }
04348 int lnez = 0;
04349 for (int iz = kbmax; iz >= 1; iz--) {
04350 if (wz[iz] != 0.f) {
04351 lnez = iz;
04352 break;
04353 }
04354 }
04355 int lnby = 0;
04356 for (int iy = kbmin; iy <= -1; iy++) {
04357 if (wy[iy] != 0.f) {
04358 lnby = iy;
04359 break;
04360 }
04361 }
04362 int lney = 0;
04363 for (int iy = kbmax; iy >= 1; iy--) {
04364 if (wy[iy] != 0.f) {
04365 lney = iy;
04366 break;
04367 }
04368 }
04369 int lnbx = 0;
04370 for (int ix = kbmin; ix <= -1; ix++) {
04371 if (wx[ix] != 0.f) {
04372 lnbx = ix;
04373 break;
04374 }
04375 }
04376 int lnex = 0;
04377 for (int ix = kbmax; ix >= 1; ix--) {
04378 if (wx[ix] != 0.f) {
04379 lnex = ix;
04380 break;
04381 }
04382 }
04383 if (ixn >= -kbmin && ixn <= nhalf-1-kbmax
04384 && iyn >= -nhalf-kbmin && iyn <= nhalf-1-kbmax
04385 && izn >= -nhalf-kbmin && izn <= nhalf-1-kbmax) {
04386
04387 for (int lz = lnbz; lz <= lnez; lz++) {
04388 int izp = izn + lz;
04389 for (int ly=lnby; ly<=lney; ly++) {
04390 int iyp = iyn + ly;
04391 float ty = wz[lz]*wy[ly];
04392 for (int lx=lnbx; lx<=lnex; lx++) {
04393 int ixp = ixn + lx;
04394 float wg = wx[lx]*ty;
04395 btq += cmplx(ixp,iyp,izp)*wg;
04396 wsum += wg;
04397 }
04398 }
04399 }
04400 } else {
04401
04402 for (int lz = lnbz; lz <= lnez; lz++) {
04403 int izp = izn + lz;
04404 for (int ly=lnby; ly<=lney; ly++) {
04405 int iyp = iyn + ly;
04406 float ty = wz[lz]*wy[ly];
04407 for (int lx=lnbx; lx<=lnex; lx++) {
04408 int ixp = ixn + lx;
04409 float wg = wx[lx]*ty;
04410 bool mirror = false;
04411 int ixt(ixp), iyt(iyp), izt(izp);
04412 if (ixt > nhalf || ixt < -nhalf) {
04413 ixt = Util::sgn(ixt)
04414 *(n - abs(ixt));
04415 iyt = -iyt;
04416 izt = -izt;
04417 mirror = !mirror;
04418 }
04419 if (iyt >= nhalf || iyt < -nhalf) {
04420 if (ixt != 0) {
04421 ixt = -ixt;
04422 iyt = Util::sgn(iyt)
04423 *(n - abs(iyt));
04424 izt = -izt;
04425 mirror = !mirror;
04426 } else {
04427 iyt -= n*Util::sgn(iyt);
04428 }
04429 }
04430 if (izt >= nhalf || izt < -nhalf) {
04431 if (ixt != 0) {
04432 ixt = -ixt;
04433 iyt = -iyt;
04434 izt = Util::sgn(izt)
04435 *(n - abs(izt));
04436 mirror = !mirror;
04437 } else {
04438 izt -= Util::sgn(izt)*n;
04439 }
04440 }
04441 if (ixt < 0) {
04442 ixt = -ixt;
04443 iyt = -iyt;
04444 izt = -izt;
04445 mirror = !mirror;
04446 }
04447 if (iyt == nhalf) iyt = -nhalf;
04448 if (izt == nhalf) izt = -nhalf;
04449 if (mirror) btq += conj(cmplx(ixt,iyt,izt))*wg;
04450 else btq += cmplx(ixt,iyt,izt)*wg;
04451 wsum += wg;
04452 }
04453 }
04454 }
04455 }
04456 if (flip) res->cmplx(jx,jy) = conj(btq);
04457 else res->cmplx(jx,jy) = btq;
04458 }
04459 }
04460 }
04461 for (int jy = -nhalf; jy < nhalf; jy++)
04462 for (int jx = 0; jx <= nhalf; jx++)
04463 res->cmplx(jx,jy) *= count/wsum;
04464 delete[] wx0; delete[] wy0; delete[] wz0;
04465 set_array_offsets(saved_offsets);
04466 res->set_array_offsets(0,0,0);
04467 res->set_shuffled(true);
04468 return res;
04469 }
04470
04471
04473
04474
04475
04476 EMData* EMData::extract_plane_rect(const Transform& tf, Util::KaiserBessel& kbx,Util::KaiserBessel& kby, Util::KaiserBessel& kbz) {
04477
04478
04479 if (!is_complex())
04480 throw ImageFormatException("extractplane requires a complex image");
04481 if (nx%2 != 0)
04482 throw ImageDimensionException("extractplane requires nx to be even");
04483
04484 int nxfromz = nz+2;
04485 int nxcircal = nxfromz - 2;
04486 EMData* res = new EMData();
04487 res->set_size(nxfromz,nz,1);
04488 res->to_zero();
04489 res->set_complex(true);
04490 res->set_fftodd(false);
04491 res->set_fftpad(true);
04492 res->set_ri(true);
04493
04494 int n = nxcircal;
04495 int nhalf = n/2;
04496 int nxhalf = (nx-2)/2;
04497 int nyhalf = ny/2;
04498 int nzhalf = nz/2;
04499
04500 vector<int> saved_offsets = get_array_offsets();
04501 set_array_offsets(0, -nyhalf, -nzhalf);
04502 res->set_array_offsets(0,-nhalf,0);
04503
04504 int kbxsize = kbx.get_window_size();
04505 int kbxmin = -kbxsize/2;
04506 int kbxmax = -kbxmin;
04507
04508 int kbysize = kby.get_window_size();
04509 int kbymin = -kbysize/2;
04510 int kbymax = -kbymin;
04511
04512 int kbzsize = kbz.get_window_size();
04513 int kbzmin = -kbzsize/2;
04514 int kbzmax = -kbzmin;
04515
04516
04517 float* wy0 = new float[kbymax - kbymin + 1];
04518 float* wy = wy0 - kbymin;
04519 float* wx0 = new float[kbxmax - kbxmin + 1];
04520 float* wx = wx0 - kbxmin;
04521 float* wz0 = new float[kbzmax - kbzmin + 1];
04522 float* wz = wz0 - kbzmin;
04523 float rim = nhalf*float(nhalf);
04524 int count = 0;
04525 float wsum = 0.f;
04526 Transform tftrans = tf;
04527 tftrans.invert();
04528 float xratio=float(nx-2)/float(nz);
04529 float yratio=float(ny)/float(nz);
04530
04531 for (int jy = -nhalf; jy < nhalf; jy++)
04532 {
04533 for (int jx = 0; jx <= nhalf; jx++)
04534 {
04535 Vec3f nucur((float)jx, (float)jy, 0.f);
04536 Vec3f nunew = tftrans*nucur;
04537 float xnew = nunew[0]*xratio, ynew = nunew[1]*yratio, znew = nunew[2];
04538
04539 if (nunew[0]*nunew[0]+nunew[1]*nunew[1]+nunew[2]*nunew[2] <= rim)
04540 {
04541 count++;
04542 std::complex<float> btq(0.f,0.f);
04543 bool flip = false;
04544 if (xnew < 0.f) {
04545 flip = true;
04546 xnew = -xnew;
04547 ynew = -ynew;
04548 znew = -znew;
04549 }
04550 int ixn = int(Util::round(xnew));
04551 int iyn = int(Util::round(ynew));
04552 int izn = int(Util::round(znew));
04553
04554 for (int i=kbzmin; i <= kbzmax; i++) {
04555 int izp = izn + i;
04556 wz[i] = kbz.i0win_tab(znew - izp);
04557 }
04558 for (int i=kbymin; i <= kbymax; i++) {
04559 int iyp = iyn + i;
04560 wy[i] = kby.i0win_tab(ynew - iyp);
04561 }
04562 for (int i=kbxmin; i <= kbxmax; i++) {
04563 int ixp = ixn + i;
04564 wx[i] = kbx.i0win_tab(xnew - ixp);
04565 }
04566
04567
04568
04569
04570 int lnbz = 0;
04571 for (int iz = kbzmin; iz <= -1; iz++) {
04572 if (wz[iz] != 0.f) {
04573 lnbz = iz;
04574 break;
04575 }
04576 }
04577 int lnez = 0;
04578 for (int iz = kbzmax; iz >= 1; iz--) {
04579 if (wz[iz] != 0.f) {
04580 lnez = iz;
04581 break;
04582 }
04583 }
04584 int lnby = 0;
04585 for (int iy = kbymin; iy <= -1; iy++) {
04586 if (wy[iy] != 0.f) {
04587 lnby = iy;
04588 break;
04589 }
04590 }
04591 int lney = 0;
04592 for (int iy = kbymax; iy >= 1; iy--) {
04593 if (wy[iy] != 0.f) {
04594 lney = iy;
04595 break;
04596 }
04597 }
04598 int lnbx = 0;
04599 for (int ix = kbxmin; ix <= -1; ix++) {
04600 if (wx[ix] != 0.f) {
04601 lnbx = ix;
04602 break;
04603 }
04604 }
04605 int lnex = 0;
04606 for (int ix = kbxmax; ix >= 1; ix--) {
04607 if (wx[ix] != 0.f) {
04608 lnex = ix;
04609 break;
04610 }
04611 }
04612 if (ixn >= -kbxmin && ixn <= nxhalf-1-kbxmax
04613 && iyn >= -nyhalf-kbymin && iyn <= nyhalf-1-kbymax
04614 && izn >= -nzhalf-kbzmin && izn <= nzhalf-1-kbzmax) {
04615
04616 for (int lz = lnbz; lz <= lnez; lz++) {
04617 int izp = izn + lz;
04618 for (int ly=lnby; ly<=lney; ly++) {
04619 int iyp = iyn + ly;
04620 float ty = wz[lz]*wy[ly];
04621 for (int lx=lnbx; lx<=lnex; lx++) {
04622 int ixp = ixn + lx;
04623 float wg = wx[lx]*ty;
04624 btq += cmplx(ixp,iyp,izp)*wg;
04625 wsum += wg;
04626 }
04627 }
04628 }
04629 }
04630 else {
04631
04632 for (int lz = lnbz; lz <= lnez; lz++) {
04633 int izp = izn + lz;
04634 for (int ly=lnby; ly<=lney; ly++) {
04635 int iyp = iyn + ly;
04636 float ty = wz[lz]*wy[ly];
04637 for (int lx=lnbx; lx<=lnex; lx++) {
04638 int ixp = ixn + lx;
04639 float wg = wx[lx]*ty;
04640 bool mirror = false;
04641 int ixt(ixp), iyt(iyp), izt(izp);
04642 if (ixt > nxhalf || ixt < -nxhalf) {
04643 ixt = Util::sgn(ixt)
04644 *(nx-2-abs(ixt));
04645 iyt = -iyt;
04646 izt = -izt;
04647 mirror = !mirror;
04648 }
04649 if (iyt >= nyhalf || iyt < -nyhalf) {
04650 if (ixt != 0) {
04651 ixt = -ixt;
04652 iyt = Util::sgn(iyt)
04653 *(ny - abs(iyt));
04654 izt = -izt;
04655 mirror = !mirror;
04656 } else {
04657 iyt -= ny*Util::sgn(iyt);
04658 }
04659 }
04660 if (izt >= nzhalf || izt < -nzhalf) {
04661 if (ixt != 0) {
04662 ixt = -ixt;
04663 iyt = -iyt;
04664 izt = Util::sgn(izt)
04665 *(nz - abs(izt));
04666 mirror = !mirror;
04667 } else {
04668 izt -= Util::sgn(izt)*nz;
04669 }
04670 }
04671 if (ixt < 0) {
04672 ixt = -ixt;
04673 iyt = -iyt;
04674 izt = -izt;
04675 mirror = !mirror;
04676 }
04677 if (iyt == nyhalf) iyt = -nyhalf;
04678 if (izt == nzhalf) izt = -nzhalf;
04679 if (mirror) btq += conj(cmplx(ixt,iyt,izt))*wg;
04680 else btq += cmplx(ixt,iyt,izt)*wg;
04681 wsum += wg;
04682 }
04683 }
04684 }
04685 }
04686 if (flip) res->cmplx(jx,jy) = conj(btq);
04687 else res->cmplx(jx,jy) = btq;
04688 }
04689 }
04690 }
04691 for (int jy = -nhalf; jy < nhalf; jy++)
04692 for (int jx = 0; jx <= nhalf; jx++)
04693 res->cmplx(jx,jy) *= count/wsum;
04694 delete[] wx0; delete[] wy0; delete[] wz0;
04695 set_array_offsets(saved_offsets);
04696 res->set_array_offsets(0,0,0);
04697 res->set_shuffled(true);
04698 return res;
04699 }
04700
04701
04702
04703 EMData* EMData::extract_plane_rect_fast(const Transform& tf, Util::KaiserBessel& kbx,Util::KaiserBessel& kby, Util::KaiserBessel& kbz) {
04704
04705
04706
04707 if (!is_complex())
04708 throw ImageFormatException("extractplane requires a complex image");
04709 if (nx%2 != 0)
04710 throw ImageDimensionException("extractplane requires nx to be even");
04711
04712 int nxfromz=nz+2;
04713 int nxcircal = nxfromz - 2;
04714
04715
04716 float xratio=float(nx-2)/float(nz);
04717 float yratio=float(ny)/float(nz);
04718 Vec3f axis_newx,axis_newy;
04719 axis_newx[0] = xratio*0.5*nz*tf[0][0];
04720 axis_newx[1] = yratio*0.5*nz*tf[0][1];
04721 axis_newx[2] = 0.5*nz*tf[0][2];
04722
04723
04724 float ellipse_length_x=std::sqrt(axis_newx[0]*axis_newx[0]+axis_newx[1]*axis_newx[1]+axis_newx[2]*axis_newx[2]);
04725
04726 int ellipse_length_x_int=int(ellipse_length_x);
04727 float ellipse_step_x=0.5*nz/float(ellipse_length_x_int);
04728 float xscale=ellipse_step_x;
04729
04730 axis_newy[0] = xratio*0.5*nz*tf[1][0];
04731 axis_newy[1] = yratio*0.5*nz*tf[1][1];
04732 axis_newy[2] = 0.5*nz*tf[1][2];
04733
04734
04735 float ellipse_length_y=std::sqrt(axis_newy[0]*axis_newy[0]+axis_newy[1]*axis_newy[1]+axis_newy[2]*axis_newy[2]);
04736 int ellipse_length_y_int=int(ellipse_length_y);
04737 float ellipse_step_y=0.5*nz/float(ellipse_length_y_int);
04738 float yscale=ellipse_step_y;
04739
04740 int nx_e=ellipse_length_x_int*2;
04741 int ny_e=ellipse_length_y_int*2;
04742 int nx_ec=nx_e+2;
04743
04744 EMData* res = new EMData();
04745 res->set_size(nx_ec,ny_e,1);
04746 res->to_zero();
04747 res->set_complex(true);
04748 res->set_fftodd(false);
04749 res->set_fftpad(true);
04750 res->set_ri(true);
04751
04752
04753
04754 int n = nxcircal;
04755 int nhalf = n/2;
04756 int nhalfx_e = nx_e/2;
04757 int nhalfy_e = ny_e/2;
04758 int nxhalf=(nx-2)/2;
04759 int nyhalf=ny/2;
04760 int nzhalf=nz/2;
04761
04762 vector<int> saved_offsets = get_array_offsets();
04763 set_array_offsets(0,-nyhalf,-nzhalf);
04764 res->set_array_offsets(0,-nhalfy_e,0);
04765
04766 int kbxsize = kbx.get_window_size();
04767 int kbxmin = -kbxsize/2;
04768 int kbxmax = -kbxmin;
04769
04770 int kbysize = kby.get_window_size();
04771 int kbymin = -kbysize/2;
04772 int kbymax = -kbymin;
04773
04774 int kbzsize = kbz.get_window_size();
04775 int kbzmin = -kbzsize/2;
04776 int kbzmax = -kbzmin;
04777
04778
04779 float* wy0 = new float[kbymax - kbymin + 1];
04780 float* wy = wy0 - kbymin;
04781 float* wx0 = new float[kbxmax - kbxmin + 1];
04782 float* wx = wx0 - kbxmin;
04783 float* wz0 = new float[kbzmax - kbzmin + 1];
04784 float* wz = wz0 - kbzmin;
04785 float rim = nhalf*float(nhalf);
04786 int count = 0;
04787 float wsum = 0.f;
04788 Transform tftrans = tf;
04789 tftrans.invert();
04790
04791
04792 for (int jy = -nhalfy_e; jy < nhalfy_e; jy++)
04793 {
04794 for (int jx = 0; jx <= nhalfx_e; jx++)
04795 {
04796 Vec3f nucur((float)jx, (float)jy, 0.f);
04797 nucur[0]=nucur[0]*xscale;nucur[1]=nucur[1]*yscale;;
04798 Vec3f nunew = tftrans*nucur;
04799 float xnew = nunew[0]*xratio, ynew = nunew[1]*yratio, znew = nunew[2];
04800
04801 if (nunew[0]*nunew[0]+nunew[1]*nunew[1]+nunew[2]*nunew[2] <= rim)
04802 {
04803 count++;
04804 std::complex<float> btq(0.f,0.f);
04805 bool flip = false;
04806 if (xnew < 0.f) {
04807 flip = true;
04808 xnew = -xnew;
04809 ynew = -ynew;
04810 znew = -znew;
04811 }
04812 int ixn = int(Util::round(xnew));
04813 int iyn = int(Util::round(ynew));
04814 int izn = int(Util::round(znew));
04815
04816 for (int i=kbzmin; i <= kbzmax; i++) {
04817 int izp = izn + i;
04818 wz[i] = kbz.i0win_tab(znew - izp);
04819 }
04820 for (int i=kbymin; i <= kbymax; i++) {
04821 int iyp = iyn + i;
04822 wy[i] = kby.i0win_tab(ynew - iyp);
04823 }
04824 for (int i=kbxmin; i <= kbxmax; i++) {
04825 int ixp = ixn + i;
04826 wx[i] = kbx.i0win_tab(xnew - ixp);
04827 }
04828
04829
04830
04831
04832 int lnbz = 0;
04833 for (int iz = kbzmin; iz <= -1; iz++) {
04834 if (wz[iz] != 0.f) {
04835 lnbz = iz;
04836 break;
04837 }
04838 }
04839 int lnez = 0;
04840 for (int iz = kbzmax; iz >= 1; iz--) {
04841 if (wz[iz] != 0.f) {
04842 lnez = iz;
04843 break;
04844 }
04845 }
04846 int lnby = 0;
04847 for (int iy = kbymin; iy <= -1; iy++) {
04848 if (wy[iy] != 0.f) {
04849 lnby = iy;
04850 break;
04851 }
04852 }
04853 int lney = 0;
04854 for (int iy = kbymax; iy >= 1; iy--) {
04855 if (wy[iy] != 0.f) {
04856 lney = iy;
04857 break;
04858 }
04859 }
04860 int lnbx = 0;
04861 for (int ix = kbxmin; ix <= -1; ix++) {
04862 if (wx[ix] != 0.f) {
04863 lnbx = ix;
04864 break;
04865 }
04866 }
04867 int lnex = 0;
04868 for (int ix = kbxmax; ix >= 1; ix--) {
04869 if (wx[ix] != 0.f) {
04870 lnex = ix;
04871 break;
04872 }
04873 }
04874 if (ixn >= -kbxmin && ixn <= nxhalf-1-kbxmax
04875 && iyn >= -nyhalf-kbymin && iyn <= nyhalf-1-kbymax
04876 && izn >= -nzhalf-kbzmin && izn <= nzhalf-1-kbzmax) {
04877
04878 for (int lz = lnbz; lz <= lnez; lz++) {
04879 int izp = izn + lz;
04880 for (int ly=lnby; ly<=lney; ly++) {
04881 int iyp = iyn + ly;
04882 float ty = wz[lz]*wy[ly];
04883 for (int lx=lnbx; lx<=lnex; lx++) {
04884 int ixp = ixn + lx;
04885 float wg = wx[lx]*ty;
04886 btq += cmplx(ixp,iyp,izp)*wg;
04887 wsum += wg;
04888 }
04889 }
04890 }
04891 }
04892 else {
04893
04894 for (int lz = lnbz; lz <= lnez; lz++) {
04895 int izp = izn + lz;
04896 for (int ly=lnby; ly<=lney; ly++) {
04897 int iyp = iyn + ly;
04898 float ty = wz[lz]*wy[ly];
04899 for (int lx=lnbx; lx<=lnex; lx++) {
04900 int ixp = ixn + lx;
04901 float wg = wx[lx]*ty;
04902 bool mirror = false;
04903 int ixt(ixp), iyt(iyp), izt(izp);
04904 if (ixt > nxhalf || ixt < -nxhalf) {
04905 ixt = Util::sgn(ixt)
04906 *(nx-2-abs(ixt));
04907 iyt = -iyt;
04908 izt = -izt;
04909 mirror = !mirror;
04910 }
04911 if (iyt >= nyhalf || iyt < -nyhalf) {
04912 if (ixt != 0) {
04913 ixt = -ixt;
04914 iyt = Util::sgn(iyt)
04915 *(ny - abs(iyt));
04916 izt = -izt;
04917 mirror = !mirror;
04918 } else {
04919 iyt -= ny*Util::sgn(iyt);
04920 }
04921 }
04922 if (izt >= nzhalf || izt < -nzhalf) {
04923 if (ixt != 0) {
04924 ixt = -ixt;
04925 iyt = -iyt;
04926 izt = Util::sgn(izt)
04927 *(nz - abs(izt));
04928 mirror = !mirror;
04929 } else {
04930 izt -= Util::sgn(izt)*nz;
04931 }
04932 }
04933 if (ixt < 0) {
04934 ixt = -ixt;
04935 iyt = -iyt;
04936 izt = -izt;
04937 mirror = !mirror;
04938 }
04939 if (iyt == nyhalf) iyt = -nyhalf;
04940 if (izt == nzhalf) izt = -nzhalf;
04941 if (mirror) btq += conj(cmplx(ixt,iyt,izt))*wg;
04942 else btq += cmplx(ixt,iyt,izt)*wg;
04943 wsum += wg;
04944 }
04945 }
04946 }
04947 }
04948 if (flip) res->cmplx(jx,jy) = conj(btq);
04949 else res->cmplx(jx,jy) = btq;
04950 }
04951 }
04952 }
04953 for (int jy = -nhalfy_e; jy < nhalfy_e; jy++)
04954 for (int jx = 0; jx <= nhalfx_e; jx++)
04955 res->cmplx(jx,jy) *= count/wsum;
04956 delete[] wx0; delete[] wy0; delete[] wz0;
04957 set_array_offsets(saved_offsets);
04958 res->set_array_offsets(0,0,0);
04959 res->set_shuffled(true);
04960 return res;
04961 }
04962
04963
04964
04965
04966 bool EMData::peakcmp(const Pixel& p1, const Pixel& p2) {
04967 return (p1.value > p2.value);
04968 }
04969
04970 ostream& operator<< (ostream& os, const Pixel& peak) {
04971 os << peak.x << peak.y << peak.z << peak.value;
04972 return os;
04973 }
04974
04975
04976
04977
04978
04979
04980
04981
04982
04983
04984
04985
04986
04987
04988
04989
04990
04991
04992
04993
04994
04995
04996
04997
04998
04999
05000
05001
05002
05003
05004
05005
05006
05007
05008
05009
05010
05011
05012
05013
05014
05015
05016
05017
05018
05019
05020
05021
05022
05023
05024
05025
05026
05027
05028
05029
05030
05031
05032
05033
05034
05035
05036
05037
05038
05039 vector<float> EMData::peak_search(int ml, float invert) {
05040
05041 EMData& buf = *this;
05042 vector<Pixel> peaks;
05043 int img_dim;
05044 int i, j, k;
05045 int i__1, i__2;
05046 int j__1, j__2;
05047
05048 bool peak_check;
05049 img_dim=buf.get_ndim();
05050 vector<int> ix, jy, kz;
05051 vector<float>res;
05052 int nx = buf.get_xsize();
05053 int ny = buf.get_ysize();
05054 int nz = buf.get_zsize();
05055 if(invert <= 0.0f) invert=-1.0f;
05056 else invert=1.0f ;
05057 int count = 0;
05058 switch (img_dim) {
05059 case(1):
05060 for(i=0;i<=nx-1;++i) {
05061 i__1 = (i-1+nx)%nx;
05062 i__2 = (i+1)%nx;
05063
05064
05065
05066 float qbf = buf(i)*invert;
05067 peak_check = qbf > buf(i__1)*invert && qbf > buf(i__2)*invert;
05068 if(peak_check) {
05069 if(count < ml) {
05070 count++;
05071 peaks.push_back( Pixel(i, 0, 0, qbf) );
05072 if(count == ml-1) sort(peaks.begin(), peaks.end(), peakcmp);
05073 } else {
05074 if( qbf > (peaks.back()).value ) {
05075
05076 peaks.pop_back();
05077 peaks.push_back( Pixel(i, 0, 0, qbf) );
05078 if(ml > 1) sort(peaks.begin(), peaks.end(), peakcmp);
05079 }
05080 }
05081 }
05082 }
05083 break;
05084 case(2):
05085
05086
05087
05088
05089
05090
05091
05092
05093 for(j=1;j<=ny-2;++j) {
05094 j__1 = j-1;
05095 j__2 = j+1;
05096 for(i=1;i<=nx-2;++i) {
05097 i__1 = i-1;
05098 i__2 = i+1;
05099 float qbf = buf(i,j)*invert;
05100 peak_check = (qbf > buf(i,j__1)*invert) && (qbf > buf(i,j__2)*invert);
05101 if(peak_check) {
05102 peak_check = (qbf > buf(i__1,j)*invert) && (qbf > buf(i__2,j)*invert);
05103 if(peak_check) {
05104 peak_check = (qbf > buf(i__1,j__1)*invert) && (qbf > buf(i__1,j__2)*invert);
05105 if(peak_check) {
05106 peak_check = (qbf > buf(i__2,j__1)*invert) && (qbf > buf(i__2,j__2)*invert);
05107 if(peak_check) {
05108 if(count < ml) {
05109 count++;
05110 peaks.push_back( Pixel(i, j, 0, qbf) );
05111 if(count == ml-1) sort(peaks.begin(), peaks.end(), peakcmp);
05112 } else {
05113 if( qbf > (peaks.back()).value ) {
05114
05115 peaks.pop_back();
05116 peaks.push_back( Pixel(i, j, 0, qbf) );
05117 if(ml > 1) sort(peaks.begin(), peaks.end(), peakcmp);
05118 }
05119 }
05120 }
05121 }
05122 }
05123 }
05124 }
05125 }
05126 break;
05127 case(3):
05128
05129
05130
05131
05132
05133
05134
05135
05136
05137
05138
05139
05140
05141
05142
05143
05144
05145
05146
05147
05148 for(k=1; k<=nz-2; ++k) {
05149 kz.clear();
05150 kz.push_back(k-1);
05151 kz.push_back(k);
05152 kz.push_back(k+1);
05153 for(j=1; j<=ny-2; ++j) {
05154 jy.clear();
05155 jy.push_back(j-1);
05156 jy.push_back(j);
05157 jy.push_back(j+1);
05158 for(i=1; i<=nx-2; ++i) {
05159 ix.clear();
05160 ix.push_back(i-1);
05161 ix.push_back(i);
05162 ix.push_back(i+1);
05163 float qbf = buf(i,j,k)*invert;
05164 peak_check = qbf > buf(ix[0],jy[0],kz[0])*invert;
05165 if( peak_check ) {peak_check = qbf > buf(ix[1],jy[0],kz[0])*invert;
05166 if( peak_check ) {peak_check = qbf > buf(ix[2],jy[0],kz[0])*invert;
05167 if( peak_check ) {peak_check = qbf > buf(ix[0],jy[1],kz[0])*invert;
05168 if( peak_check ) {peak_check = qbf > buf(ix[1],jy[1],kz[0])*invert;
05169 if( peak_check ) {peak_check = qbf > buf(ix[2],jy[1],kz[0])*invert;
05170 if( peak_check ) {peak_check = qbf > buf(ix[0],jy[2],kz[0])*invert;
05171 if( peak_check ) {peak_check = qbf > buf(ix[1],jy[2],kz[0])*invert;
05172 if( peak_check ) {peak_check = qbf > buf(ix[2],jy[2],kz[0])*invert;
05173 if( peak_check ) {peak_check = qbf > buf(ix[0],jy[0],kz[1])*invert;
05174 if( peak_check ) {peak_check = qbf > buf(ix[1],jy[0],kz[1])*invert;
05175 if( peak_check ) {peak_check = qbf > buf(ix[2],jy[0],kz[1])*invert;
05176 if( peak_check ) {peak_check = qbf > buf(ix[0],jy[1],kz[1])*invert;
05177
05178 if( peak_check ) {peak_check = qbf > buf(ix[2],jy[1],kz[1])*invert;
05179 if( peak_check ) {peak_check = qbf > buf(ix[0],jy[2],kz[1])*invert;
05180 if( peak_check ) {peak_check = qbf > buf(ix[1],jy[2],kz[1])*invert;
05181 if( peak_check ) {peak_check = qbf > buf(ix[2],jy[2],kz[1])*invert;
05182 if( peak_check ) {peak_check = qbf > buf(ix[0],jy[0],kz[2])*invert;
05183 if( peak_check ) {peak_check = qbf > buf(ix[1],jy[0],kz[2])*invert;
05184 if( peak_check ) {peak_check = qbf > buf(ix[2],jy[0],kz[2])*invert;
05185 if( peak_check ) {peak_check = qbf > buf(ix[0],jy[1],kz[2])*invert;
05186 if( peak_check ) {peak_check = qbf > buf(ix[1],jy[1],kz[2])*invert;
05187 if( peak_check ) {peak_check = qbf > buf(ix[2],jy[1],kz[2])*invert;
05188 if( peak_check ) {peak_check = qbf > buf(ix[0],jy[2],kz[2])*invert;
05189 if( peak_check ) {peak_check = qbf > buf(ix[1],jy[2],kz[2])*invert;
05190 if( peak_check ) {peak_check = qbf > buf(ix[2],jy[2],kz[2])*invert;
05191 if(peak_check) {
05192 if(count < ml) {
05193 count++;
05194 peaks.push_back( Pixel(i, j, k, qbf) );
05195 if(count == ml-1) sort(peaks.begin(), peaks.end(), peakcmp);
05196 } else {
05197 if( qbf > (peaks.back()).value ) {
05198
05199
05200 peaks.pop_back();
05201 peaks.push_back( Pixel(i, j, k, qbf) );
05202 if(ml > 1) sort(peaks.begin(), peaks.end(), peakcmp);
05203 }
05204 }
05205 }
05206 }}}}}}}}}}}}}}}}}}}}}}}}}
05207 }
05208 }
05209 }
05210
05211
05212 for(k=1; k<=nz-2; ++k) {
05213 kz.clear();
05214 kz.push_back(k-1);
05215 kz.push_back(k);
05216 kz.push_back(k+1);
05217 for(j=1; j<=ny-2; ++j) {
05218 jy.clear();
05219 jy.push_back(j-1);
05220 jy.push_back(j);
05221 jy.push_back(j+1);
05222 for(i=0; i<=0; ++i) {
05223 ix.clear();
05224 ix.push_back(nx-1);
05225 ix.push_back(i);
05226 ix.push_back(i+1);
05227 float qbf = buf(i,j,k)*invert;
05228 peak_check = qbf > buf(ix[0],jy[0],kz[0])*invert;
05229 if( peak_check ) {peak_check = qbf > buf(ix[1],jy[0],kz[0])*invert;
05230 if( peak_check ) {peak_check = qbf > buf(ix[2],jy[0],kz[0])*invert;
05231 if( peak_check ) {peak_check = qbf > buf(ix[0],jy[1],kz[0])*invert;
05232 if( peak_check ) {peak_check = qbf > buf(ix[1],jy[1],kz[0])*invert;
05233 if( peak_check ) {peak_check = qbf > buf(ix[2],jy[1],kz[0])*invert;
05234 if( peak_check ) {peak_check = qbf > buf(ix[0],jy[2],kz[0])*invert;
05235 if( peak_check ) {peak_check = qbf > buf(ix[1],jy[2],kz[0])*invert;
05236 if( peak_check ) {peak_check = qbf > buf(ix[2],jy[2],kz[0])*invert;
05237 if( peak_check ) {peak_check = qbf > buf(ix[0],jy[0],kz[1])*invert;
05238 if( peak_check ) {peak_check = qbf > buf(ix[1],jy[0],kz[1])*invert;
05239 if( peak_check ) {peak_check = qbf > buf(ix[2],jy[0],kz[1])*invert;
05240 if( peak_check ) {peak_check = qbf > buf(ix[0],jy[1],kz[1])*invert;
05241
05242 if( peak_check ) {peak_check = qbf > buf(ix[2],jy[1],kz[1])*invert;
05243 if( peak_check ) {peak_check = qbf > buf(ix[0],jy[2],kz[1])*invert;
05244 if( peak_check ) {peak_check = qbf > buf(ix[1],jy[2],kz[1])*invert;
05245 if( peak_check ) {peak_check = qbf > buf(ix[2],jy[2],kz[1])*invert;
05246 if( peak_check ) {peak_check = qbf > buf(ix[0],jy[0],kz[2])*invert;
05247 if( peak_check ) {peak_check = qbf > buf(ix[1],jy[0],kz[2])*invert;
05248 if( peak_check ) {peak_check = qbf > buf(ix[2],jy[0],kz[2])*invert;
05249 if( peak_check ) {peak_check = qbf > buf(ix[0],jy[1],kz[2])*invert;
05250 if( peak_check ) {peak_check = qbf > buf(ix[1],jy[1],kz[2])*invert;
05251 if( peak_check ) {peak_check = qbf > buf(ix[2],jy[1],kz[2])*invert;
05252 if( peak_check ) {peak_check = qbf > buf(ix[0],jy[2],kz[2])*invert;
05253 if( peak_check ) {peak_check = qbf > buf(ix[1],jy[2],kz[2])*invert;
05254 if( peak_check ) {peak_check = qbf > buf(ix[2],jy[2],kz[2])*invert;
05255 if(peak_check) {
05256 if(count < ml) {
05257 count++;
05258 peaks.push_back( Pixel(i, j, k, qbf) );
05259 if(count == ml-1) sort(peaks.begin(), peaks.end(), peakcmp);
05260 } else {
05261 if( qbf > (peaks.back()).value ) {
05262
05263
05264 peaks.pop_back();
05265 peaks.push_back( Pixel(i, j, k, qbf) );
05266 if(ml > 1) sort(peaks.begin(), peaks.end(), peakcmp);
05267 }
05268 }
05269 }
05270 }}}}}}}}}}}}}}}}}}}}}}}}}
05271 }
05272 for(i=nx-1; i<=nx-1; ++i) {
05273 ix.clear();
05274 ix.push_back(i-1);
05275 ix.push_back(i);
05276 ix.push_back(0);
05277 float qbf = buf(i,j,k)*invert;
05278 peak_check = qbf > buf(ix[0],jy[0],kz[0])*invert;
05279 if( peak_check ) {peak_check = qbf > buf(ix[1],jy[0],kz[0])*invert;
05280 if( peak_check ) {peak_check = qbf > buf(ix[2],jy[0],kz[0])*invert;
05281 if( peak_check ) {peak_check = qbf > buf(ix[0],jy[1],kz[0])*invert;
05282 if( peak_check ) {peak_check = qbf > buf(ix[1],jy[1],kz[0])*invert;
05283 if( peak_check ) {peak_check = qbf > buf(ix[2],jy[1],kz[0])*invert;
05284 if( peak_check ) {peak_check = qbf > buf(ix[0],jy[2],kz[0])*invert;
05285 if( peak_check ) {peak_check = qbf > buf(ix[1],jy[2],kz[0])*invert;
05286 if( peak_check ) {peak_check = qbf > buf(ix[2],jy[2],kz[0])*invert;
05287 if( peak_check ) {peak_check = qbf > buf(ix[0],jy[0],kz[1])*invert;
05288 if( peak_check ) {peak_check = qbf > buf(ix[1],jy[0],kz[1])*invert;
05289 if( peak_check ) {peak_check = qbf > buf(ix[2],jy[0],kz[1])*invert;
05290 if( peak_check ) {peak_check = qbf > buf(ix[0],jy[1],kz[1])*invert;
05291
05292 if( peak_check ) {peak_check = qbf > buf(ix[2],jy[1],kz[1])*invert;
05293 if( peak_check ) {peak_check = qbf > buf(ix[0],jy[2],kz[1])*invert;
05294 if( peak_check ) {peak_check = qbf > buf(ix[1],jy[2],kz[1])*invert;
05295 if( peak_check ) {peak_check = qbf > buf(ix[2],jy[2],kz[1])*invert;
05296 if( peak_check ) {peak_check = qbf > buf(ix[0],jy[0],kz[2])*invert;
05297 if( peak_check ) {peak_check = qbf > buf(ix[1],jy[0],kz[2])*invert;
05298 if( peak_check ) {peak_check = qbf > buf(ix[2],jy[0],kz[2])*invert;
05299 if( peak_check ) {peak_check = qbf > buf(ix[0],jy[1],kz[2])*invert;
05300 if( peak_check ) {peak_check = qbf > buf(ix[1],jy[1],kz[2])*invert;
05301 if( peak_check ) {peak_check = qbf > buf(ix[2],jy[1],kz[2])*invert;
05302 if( peak_check ) {peak_check = qbf > buf(ix[0],jy[2],kz[2])*invert;
05303 if( peak_check ) {peak_check = qbf > buf(ix[1],jy[2],kz[2])*invert;
05304 if( peak_check ) {peak_check = qbf > buf(ix[2],jy[2],kz[2])*invert;
05305 if(peak_check) {
05306 if(count < ml) {
05307 count++;
05308 peaks.push_back( Pixel(i, j, k, qbf) );
05309 if(count == ml-1) sort(peaks.begin(), peaks.end(), peakcmp);
05310 } else {
05311 if( qbf > (peaks.back()).value ) {
05312
05313
05314 peaks.pop_back();
05315 peaks.push_back( Pixel(i, j, k, qbf) );
05316 if(ml > 1) sort(peaks.begin(), peaks.end(), peakcmp);
05317 }
05318 }
05319 }
05320 }}}}}}}}}}}}}}}}}}}}}}}}}
05321 }
05322 }
05323 }
05324 break;
05325
05326
05327
05328
05329
05330
05331
05332
05333
05334
05335
05336
05337
05338
05339
05340
05341
05342
05343
05344
05345
05346
05347
05348
05349
05350
05351
05352
05353
05354
05355
05356
05357
05358
05359
05360
05361
05362
05363
05364
05365
05366
05367
05368
05369
05370
05371
05372
05373
05374
05375
05376
05377
05378
05379
05380
05381
05382
05383
05384
05385
05386
05387
05388
05389
05390
05391
05392
05393
05394
05395
05396
05397
05398
05399
05400
05401
05402
05403
05404
05405
05406
05407
05408
05409
05410
05411
05412
05413
05414
05415
05416
05417
05418
05419
05420
05421
05422
05423
05424
05425
05426
05427
05428
05429
05430
05431
05432
05433
05434
05435
05436
05437
05438
05439
05440
05441
05442
05443
05444
05445
05446
05447
05448
05449
05450
05451
05452
05453
05454
05455
05456
05457
05458
05459
05460
05461
05462
05463
05464
05465
05466
05467
05468
05469
05470
05471
05472
05473
05474
05475
05476
05477
05478
05479
05480
05481
05482
05483
05484
05485
05486
05487
05488
05489
05490
05491
05492
05493
05494
05495
05496
05497
05498
05499
05500
05501
05502
05503
05504
05505
05506
05507
05508
05509
05510
05511
05512
05513
05514
05515
05516
05517
05518
05519
05520
05521
05522
05523
05524
05525
05526
05527
05528
05529
05530
05531
05532
05533
05534
05535
05536
05537
05538
05539
05540
05541
05542
05543
05544
05545
05546
05547
05548
05549
05550
05551
05552
05553
05554
05555
05556
05557
05558
05559
05560
05561
05562
05563
05564
05565
05566
05567
05568
05569
05570
05571
05572
05573
05574
05575
05576
05577
05578
05579
05580
05581
05582
05583
05584
05585
05586
05587
05588
05589
05590
05591
05592
05593
05594
05595
05596
05597
05598
05599
05600
05601
05602
05603
05604
05605
05606
05607
05608
05609
05610
05611
05612
05613
05614
05615
05616
05617
05618
05619
05620
05621
05622
05623
05624
05625
05626
05627
05628
05629
05630
05631
05632
05633
05634
05635
05636
05637
05638
05639
05640
05641
05642
05643
05644
05645
05646
05647
05648
05649
05650
05651
05652
05653
05654
05655
05656
05657
05658
05659
05660
05661
05662
05663
05664
05665
05666
05667
05668
05669
05670
05671
05672
05673
05674
05675
05676
05677
05678
05679
05680
05681
05682
05683
05684
05685
05686
05687
05688
05689
05690
05691
05692
05693
05694
05695
05696
05697
05698
05699
05700
05701
05702
05703
05704
05705
05706
05707
05708
05709
05710
05711
05712
05713
05714
05715
05716
05717
05718
05719
05720
05721
05722
05723
05724
05725
05726
05727
05728
05729
05730
05731
05732
05733
05734
05735
05736
05737
05738
05739
05740
05741
05742
05743
05744
05745
05746
05747
05748
05749
05750
05751
05752
05753
05754
05755
05756
05757
05758
05759
05760
05761
05762
05763
05764 }
05765
05766 if (peaks.begin() != peaks.end()) {
05767
05768 sort(peaks.begin(), peaks.end(), peakcmp);
05769
05770 int count = 0;
05771
05772 float xval = (*peaks.begin()).value;
05773
05774 for (vector<Pixel>::iterator it = peaks.begin(); it != peaks.end(); it++) {
05775
05776 count++;
05777
05778 if(count <= ml) {
05779
05780 res.push_back((*it).value);
05781 res.push_back(static_cast<float>((*it).x));
05782
05783 if(img_dim > 1) {
05784 res.push_back(static_cast<float>((*it).y));
05785 if(nz > 1) res.push_back(static_cast<float>((*it).z));
05786 }
05787
05788 if(xval != 0.0) res.push_back((*it).value/xval);
05789 else res.push_back((*it).value);
05790 res.push_back((*it).x-float(int(nx/2)));
05791 if(img_dim >1) {
05792 res.push_back((*it).y-float(int(ny/2)));
05793 if(nz>1) res.push_back((*it).z-float(nz/2));
05794 }
05795 }
05796 }
05797 res.insert(res.begin(),1,img_dim);
05798 } else {
05799
05800 res.push_back(buf(0,0,0));
05801 res.insert(res.begin(),1,0.0);
05802 }
05803
05804
05805 return res;
05806 }
05807
05808 #define rdata(i,j,k) rdata[(i-1)+((j-1)+(k-1)*ny)*nx]
05809 #define X(i) X[i-1]
05810 #define Y(j) Y[j-1]
05811 #define Z(k) Z[k-1]
05812 vector<float> EMData::phase_cog()
05813 {
05814 vector<float> ph_cntog;
05815 int i=1,j=1,k=1;
05816 float C=0.f,S=0.f,P=0.f,F1=0.f,SNX;
05817 if (get_ndim()==1) {
05818 P = 8*atan(1.0f)/nx;
05819 for (i=1;i<=nx;i++) {
05820 C += cos(P * (i-1)) * rdata(i,j,k);
05821 S += sin(P * (i-1)) * rdata(i,j,k);
05822 }
05823 F1 = atan2(S,C);
05824 if (F1 < 0.0) F1 += 8*atan(1.0f);
05825 SNX = F1/P +1.0f;
05826 SNX = SNX - ((nx/2)+1);
05827 ph_cntog.push_back(SNX);
05828 #ifdef _WIN32
05829 ph_cntog.push_back((float)Util::round(SNX));
05830 #else
05831 ph_cntog.push_back(round(SNX));
05832 #endif //_WIN32
05833 } else if (get_ndim()==2) {
05834 #ifdef _WIN32
05835 float SNY;
05836 float T=0.0f;
05837 vector<float> X;
05838 X.resize(nx);
05839 #else
05840 float SNY,X[nx],T=0.f;
05841 #endif //_WIN32
05842 for ( i=1;i<=nx;i++) X(i)=0.0;
05843 P = 8*atan(1.0f)/ny;
05844 for(j=1;j<=ny;j++) {
05845 T=0.f;
05846 for(i=1;i<=nx;i++) {
05847 T += rdata(i,j,k);
05848 X(i)+=rdata(i,j,k);
05849 }
05850 C += cos(P*(j-1))*T;
05851 S += sin(P*(j-1))*T;
05852 }
05853 F1=atan2(S,C);
05854 if(F1<0.0) F1 += 8*atan(1.0f);
05855 SNY = F1/P +1.0f;
05856 C=0.f; S=0.f;
05857 P = 8*atan(1.0f)/nx;
05858 for(i=1;i<=nx;i++) {
05859 C += cos(P*(i-1))*X(i);
05860 S += sin(P*(i-1))*X(i);
05861 }
05862 F1=atan2(S,C);
05863 if(F1<0.0) F1 += 8*atan(1.0f);
05864 SNX = F1/P +1.0f;
05865 SNX = SNX - ((nx/2)+1);
05866 SNY = SNY - ((ny/2)+1);
05867 ph_cntog.push_back(SNX); ph_cntog.push_back(SNY);
05868 #ifdef _WIN32
05869 ph_cntog.push_back((float)Util::round(SNX)); ph_cntog.push_back((float)Util::round(SNY));
05870 #else
05871 ph_cntog.push_back(round(SNX)); ph_cntog.push_back(round(SNY));
05872 #endif //_WIN32
05873 } else {
05874 #ifdef _WIN32
05875 float val=0.f,sum1=0.f, SNY,SNZ;
05876 vector<float> X;
05877 X.resize(nx);
05878 vector<float> Y;
05879 Y.resize(ny);
05880 vector<float> Z;
05881 Z.resize(nz);
05882 #else
05883 float val=0.f, sum1=0.f, X[nx], Y[ny], Z[nz], SNY, SNZ;
05884 #endif //_WIN32
05885 for (i=1;i<=nx;i++) X(i)=0.0;
05886 for (j=1;j<=ny;j++) Y(j)=0.0;
05887 for (k=1;k<=nz;k++) Z(k)=0.0;
05888 for(k=1;k<=nz;k++) {
05889 for(j=1;j<=ny;j++) {
05890 sum1=0.f;
05891 for(i=1;i<=nx;i++) {
05892 val = rdata(i,j,k);
05893 sum1 += val;
05894 X(i) += val;
05895 }
05896 Y(j) += sum1;
05897 Z(k) += sum1;
05898 }
05899 }
05900 P = 8*atan(1.0f)/nx;
05901 for (i=1;i<=nx;i++) {
05902 C += cos(P*(i-1))*X(i);
05903 S += sin(P*(i-1))*X(i);
05904 }
05905 F1=atan2(S,C);
05906 if(F1<0.0) F1 += 8*atan(1.0f);
05907 SNX = F1/P +1.0f;
05908 C=0.f; S=0.f;
05909 P = 8*atan(1.0f)/ny;
05910 for(j=1;j<=ny;j++) {
05911 C += cos(P*(j-1))*Y(j);
05912 S += sin(P*(j-1))*Y(j);
05913 }
05914 F1=atan2(S,C);
05915 if(F1<0.0) F1 += 8*atan(1.0f);
05916 SNY = F1/P +1.0f;
05917 C=0.f; S=0.f;
05918 P = 8*atan(1.0f)/nz;
05919 for(k=1;k<=nz;k++) {
05920 C += cos(P*(k-1))*Z(k);
05921 S += sin(P*(k-1))*Z(k);
05922 }
05923 F1=atan2(S,C);
05924 if(F1<0.0) F1 += 8*atan(1.0f);
05925 SNZ = F1/P +1.0f;
05926 SNX = SNX - ((nx/2)+1);
05927 SNY = SNY - ((ny/2)+1);
05928 SNZ = SNZ - ((nz/2)+1);
05929 ph_cntog.push_back(SNX); ph_cntog.push_back(SNY); ph_cntog.push_back(SNZ);
05930 #ifdef _WIN32
05931 ph_cntog.push_back((float)Util::round(SNX)); ph_cntog.push_back((float)Util::round(SNY)); ph_cntog.push_back((float)Util::round(SNZ));
05932 #else
05933 ph_cntog.push_back(round(SNX)); ph_cntog.push_back(round(SNY));ph_cntog.push_back(round(SNZ));
05934 #endif
05935 }
05936 return ph_cntog;
05937 }
05938 #undef rdata
05939 #undef X
05940 #undef Y
05941 #undef Z
05942
05943 #define avagadro (6.023*(double)pow(10.0,23.0))
05944 #define density_protein (1.36)
05945 #define R (0.61803399f)
05946 #define C (1.f-R)
05947 float EMData::find_3d_threshold(float mass, float pixel_size)
05948 {
05949
05950 if(get_ndim()!=3)
05951 throw ImageDimensionException("The image should be 3D");
05952
05953
05954
05955 float density_1_mole, vol_1_mole, vol_angstrom;
05956 int vol_voxels;
05957 density_1_mole = static_cast<float>( (mass*1000.0f)/avagadro );
05958 vol_1_mole = static_cast<float>( density_1_mole/density_protein );
05959 vol_angstrom = static_cast<float>( vol_1_mole*(double)pow((double)pow(10.0,8),3) );
05960 vol_voxels = static_cast<int> (vol_angstrom/(double)pow(pixel_size,3));
05961
05962
05963
05964 float thr1 = get_attr("maximum");
05965 float thr3 = get_attr("minimum");
05966 float thr2 = (thr1-thr3)/2 + thr3;
05967 int size = nx*ny*nz;
05968 float x0 = thr1,x3 = thr3,x1,x2,THR=0;
05969
05970 #ifdef _WIN32
05971 int ILE = _cpp_min(nx*ny*nx,_cpp_max(1,vol_voxels));
05972 #else
05973 int ILE = std::min(nx*ny*nx,std::max(1,vol_voxels));
05974 #endif //_WIN32
05975
05976 if (abs(thr3-thr2)>abs(thr2-thr1)) {
05977 x1=thr2;
05978 x2=thr2+C*(thr3-thr2);
05979 } else {
05980 x2=thr2;
05981 x1=thr2-C*(thr2-thr1);
05982 }
05983
05984 int cnt1=0,cnt2=0;
05985 for (int i=0;i<size;i++) {
05986 if(rdata[i]>=x1) cnt1++;
05987 if(rdata[i]>=x2) cnt2++;
05988 }
05989 float LF1 = static_cast<float>( cnt1 - ILE );
05990 float F1 = LF1*LF1;
05991 float LF2 = static_cast<float>( cnt2 - ILE );
05992 float F2 = LF2*LF2;
05993
05994 while ((LF1 != 0 || LF2 != 0) && (fabs(LF1-LF2) >= 1.f) && (abs(x1-x2) > (double)pow(10.0,-5) && abs(x1-x3) > (double)pow(10.0,-5) && abs(x2-x3) > (double)pow(10.0,-5)))
05995 {
05996 if(F2 < F1) {
05997 x0=x1;
05998 x1=x2;
05999 x2 = R*x1 + C*x3;
06000 F1=F2;
06001 int cnt=0;
06002 for(int i=0;i<size;i++)
06003 if(rdata[i]>=x2)
06004 cnt++;
06005 LF2 = static_cast<float>( cnt - ILE );
06006 F2 = LF2*LF2;
06007 } else {
06008 x3=x2;
06009 x2=x1;
06010 x1=R*x2 + C*x0;
06011 F2=F1;
06012 int cnt=0;
06013 for(int i=0;i<size;i++)
06014 if(rdata[i]>=x1)
06015 cnt++;
06016 LF1 = static_cast<float>( cnt - ILE );
06017 F1 = LF1*LF1;
06018 }
06019 }
06020
06021 if(F1 < F2) {
06022 ILE = static_cast<int> (LF1 + ILE);
06023 THR = x1;
06024 } else {
06025 ILE = static_cast<int> (LF2 + ILE);
06026 THR = x2;
06027 }
06028 return THR;
06029
06030 }
06031 #undef avagadro
06032 #undef density_protein
06033 #undef R
06034 #undef C
06035
06036
06037
06038
06039
06040
06041
06042 vector<float> EMData::peak_ccf(float hf_p)
06043 {
06044
06045
06046
06047 EMData & buf = *this;
06048 vector<Pixel> peaks;
06049 int half=int(hf_p);
06050 float hf_p2 = hf_p*hf_p;
06051 int i,j;
06052 int i__1,i__2;
06053 int j__1,j__2;
06054 vector<float>res;
06055 int nx = buf.get_xsize()-half;
06056 int ny = buf.get_ysize()-half;
06057
06058 for(i=half; i<=nx; ++i) {
06059
06060 i__1 = i-1;
06061 i__2 = i+1;
06062 for (j=half;j<=ny;++j) {
06063 j__1 = j-1;
06064 j__2 = j+1;
06065
06066 if((buf(i,j)>0.0f)&&buf(i,j)>buf(i,j__1)) {
06067 if(buf(i,j)>buf(i,j__2)) {
06068 if(buf(i,j)>buf(i__1,j)) {
06069 if(buf(i,j)>buf(i__2,j)) {
06070 if(buf(i,j)>buf(i__1,j__1)) {
06071 if((buf(i,j))> buf(i__1,j__2)) {
06072 if(buf(i,j)>buf(i__2,j__1)) {
06073 if(buf(i,j)> buf(i__2,j__2)) {
06074
06075
06076
06077 if (peaks.size()==0) {
06078
06079 peaks.push_back(Pixel(i,j,0,buf(i,j)));
06080
06081 } else {
06082
06083
06084 bool overlap = false;
06085
06086
06087
06088
06089
06090 std::stack <vector<Pixel>::iterator> delete_stack;
06091
06092
06093 for (vector<Pixel>::iterator it=peaks.begin();it!=peaks.end();++it) {
06094
06095
06096
06097
06098 float radius=((*it).x-float(i))*((*it).x-float(i))+((*it).y-float(j))*((*it).y-float(j));
06099 if (radius <= hf_p2 ) {
06100
06101 if( buf(i,j) > (*it).value) {
06102
06103
06104
06105
06106
06107
06108 delete_stack.push(it);
06109
06110
06111
06112
06113 } else {
06114 overlap = true;
06115
06116
06117 break;
06118 }
06119 }
06120 }
06121
06122
06123
06124 if (false == overlap) {
06125 vector<Pixel>::iterator delete_iterator;
06126 while (!delete_stack.empty()) {
06127
06128
06129 delete_iterator = delete_stack.top();
06130 peaks.erase(delete_iterator);
06131 delete_stack.pop();
06132 }
06133
06134
06135
06136 if (! (peaks.size() < 2000 )) {
06137
06138
06139
06140
06141 sort(peaks.begin(), peaks.end(), peakcmp);
06142
06143
06144 peaks.pop_back();
06145 }
06146
06147
06148 peaks.push_back(Pixel(i,j,0,buf(i,j)));
06149
06150
06151 } else {
06152
06153
06154 while (!delete_stack.empty()) delete_stack.pop();
06155 }
06156 }
06157 }
06158 }}}}}}}
06159 }
06160 }
06161
06162
06163 if(peaks.size()>0) {
06164
06165 sort(peaks.begin(),peaks.end(), peakcmp);
06166
06167 for (vector<Pixel>::iterator it = peaks.begin(); it != peaks.end(); it++) {
06168
06169 res.push_back((*it).value);
06170 res.push_back(static_cast<float>((*it).x));
06171 res.push_back(static_cast<float>((*it).y));
06172 }
06173 } else {
06174
06175 res.push_back(buf(0,0,0));
06176 res.insert(res.begin(),1,0.0);
06177 }
06178 return res;
06179 }
06180
06181 EMData* EMData::get_pow(float n_pow)
06182 {
06183 EMData* buf_new = this->copy_head();
06184 float *in = this->get_data();
06185 float *out = buf_new->get_data();
06186 for(int i=0; i<nx*ny*nz; i++) out[i] = pow(in[i],n_pow);
06187 return buf_new;
06188 }
06189
06190 EMData* EMData::conjg()
06191 {
06192 if(this->is_complex()) {
06193 EMData* buf_new = this->copy_head();
06194 float *in = this->get_data();
06195 float *out = buf_new->get_data();
06196 for(int i=0; i<nx*ny*nz; i+=2) {out[i] = in[i]; out[i+1] = -in[i+1];}
06197 return buf_new;
06198 } else throw ImageFormatException("image has to be complex");
06199 }
06200
06201 EMData* EMData::delete_disconnected_regions(int ix, int iy, int iz) {
06202 if (3 != get_ndim())
06203 throw ImageDimensionException("delete_disconnected_regions needs a 3-D image.");
06204 if (is_complex())
06205 throw ImageFormatException("delete_disconnected_regions requires a real image");
06206 if ((*this)(ix+nx/2,iy+ny/2,iz+nz/2) == 0)
06207 throw ImageDimensionException("delete_disconnected_regions starting point is zero.");
06208
06209 EMData* result = this->copy_head();
06210 result->to_zero();
06211 (*result)(ix+nx/2,iy+ny/2,iz+nz/2) = (*this)(ix+nx/2,iy+ny/2,iz+nz/2);
06212 bool kpt = true;
06213
06214 while(kpt) {
06215 kpt = false;
06216 for (int cz = 1; cz < nz-1; cz++) {
06217 for (int cy = 1; cy < ny-1; cy++) {
06218 for (int cx = 1; cx < nx-1; cx++) {
06219 if((*result)(cx,cy,cz) == 1) {
06220 for (int lz = -1; lz <= 1; lz++) {
06221 for (int ly = -1; ly <= 1; ly++) {
06222 for (int lx = -1; lx <= 1; lx++) {
06223 if(((*this)(cx+lx,cy+ly,cz+lz) == 1) && ((*result)(cx+lx,cy+ly,cz+lz) == 0)) {
06224 (*result)(cx+lx,cy+ly,cz+lz) = 1;
06225 kpt = true;
06226 }
06227 }
06228 }
06229 }
06230 }
06231 }
06232 }
06233 }
06234 }
06235 result->update();
06236 return result;
06237 }
06238
06239 #define QUADPI 3.141592653589793238462643383279502884197
06240 #define DGR_TO_RAD QUADPI/180
06241
06242 EMData* EMData::helicise(float pixel_size, float dp, float dphi, float section_use, float radius, float minrad) {
06243 if (3 != get_ndim())
06244 throw ImageDimensionException("helicise needs a 3-D image.");
06245 if (is_complex())
06246 throw ImageFormatException("helicise requires a real image");
06247
06248 EMData* result = this->copy_head();
06249 result->to_zero();
06250 int nyc = ny/2;
06251 int nxc = nx/2;
06252 int nb = int(nz*(1.0f - section_use)/2.);
06253 int ne = nz - nb -1;
06254 int numst = int((ne - nb)/dp*pixel_size + 0.5);
06255
06256 int nst = int(nz*pixel_size/dp+0.5);
06257 float r2, ir;
06258 if(radius < 0.0f) r2 = (float)((nxc-1)*(nxc-1));
06259 else r2 = radius*radius;
06260 if(minrad < 0.0f) ir = 0.0f;
06261 else ir = minrad*minrad;
06262 for (int k = 0; k<nz; k++) {
06263 for (int j = 0; j<ny; j++) {
06264 int jy = j - nyc;
06265 int jj = jy*jy;
06266 for (int i = 0; i<nx; i++) {
06267 int ix = i - nxc;
06268 float d2 = (float)(ix*ix + jj);
06269 if(d2 <= r2 && d2>=ir) {
06270 int nq = 1;
06271 for ( int ist = -nst; ist <= nst; ist++) {
06272 float zold = (k*pixel_size + ist*dp)/pixel_size;
06273 int IOZ = int(zold);
06274 if(IOZ >= nb && IOZ <= ne) {
06275
06276 float cphi = ist*dphi*(float)DGR_TO_RAD;
06277 float ca = cos(cphi);
06278 float sa = sin(cphi);
06279 float xold = ix*ca - jy*sa + nxc;
06280 float yold = ix*sa + jy*ca + nyc;
06281 nq++;
06282
06283
06284
06285 int IOX = int(xold);
06286 int IOY = int(yold);
06287
06288
06289 #ifdef _WIN32
06290 int IOXp1 = _cpp_min( nx-1 ,IOX+1);
06291 #else
06292 int IOXp1 = std::min( nx-1 ,IOX+1);
06293 #endif //_WIN32
06294
06295 #ifdef _WIN32
06296 int IOYp1 = _cpp_min( ny-1 ,IOY+1);
06297 #else
06298 int IOYp1 = std::min( ny-1 ,IOY+1);
06299 #endif //_WIN32
06300
06301 #ifdef _WIN32
06302 int IOZp1 = _cpp_min( nz-1 ,IOZ+1);
06303 #else
06304 int IOZp1 = std::min( nz-1 ,IOZ+1);
06305 #endif //_WIN32
06306
06307 float dx = xold-IOX;
06308 float dy = yold-IOY;
06309 float dz = zold-IOZ;
06310
06311 float a1 = (*this)(IOX,IOY,IOZ);
06312 float a2 = (*this)(IOXp1,IOY,IOZ) - (*this)(IOX,IOY,IOZ);
06313 float a3 = (*this)(IOX,IOYp1,IOZ) - (*this)(IOX,IOY,IOZ);
06314 float a4 = (*this)(IOX,IOY,IOZp1) - (*this)(IOX,IOY,IOZ);
06315 float a5 = (*this)(IOX,IOY,IOZ) - (*this)(IOXp1,IOY,IOZ) - (*this)(IOX,IOYp1,IOZ) + (*this)(IOXp1,IOYp1,IOZ);
06316 float a6 = (*this)(IOX,IOY,IOZ) - (*this)(IOXp1,IOY,IOZ) - (*this)(IOX,IOY,IOZp1) + (*this)(IOXp1,IOY,IOZp1);
06317 float a7 = (*this)(IOX,IOY,IOZ) - (*this)(IOX,IOYp1,IOZ) - (*this)(IOX,IOY,IOZp1) + (*this)(IOX,IOYp1,IOZp1);
06318 float a8 = (*this)(IOXp1,IOY,IOZ) + (*this)(IOX,IOYp1,IOZ)+ (*this)(IOX,IOY,IOZp1)
06319 - (*this)(IOX,IOY,IOZ)- (*this)(IOXp1,IOYp1,IOZ) - (*this)(IOXp1,IOY,IOZp1)
06320 - (*this)(IOX,IOYp1,IOZp1) + (*this)(IOXp1,IOYp1,IOZp1);
06321 (*result)(i,j,k) += a1 + dz*(a4 + a6*dx + (a7 + a8*dx)*dy) + a3*dy + dx*(a2 + a5*dy);
06322
06323
06324 if(nq == numst) break;
06325 }
06326 }
06327 if(nq != numst)
06328 throw InvalidValueException(nq, "incorrect number of repeats encoutered.");
06329 }
06330 }
06331 }
06332 }
06333 for (int k = 0; k<nz; k++) for (int j = 0; j<ny; j++) for (int i = 0; i<nx; i++) (*result)(i,j,k) /= numst ;
06334
06335 result->update();
06336 return result;
06337 }
06338
06339
06340 EMData* EMData::helicise_rect(float pixel_size, float dp, float dphi, float section_use, float radius, float minrad) {
06341 if (3 != get_ndim())
06342 throw ImageDimensionException("helicise needs a 3-D image.");
06343 if (is_complex())
06344 throw ImageFormatException("helicise requires a real image");
06345
06346 EMData* result = this->copy_head();
06347 result->to_zero();
06348 int nyc = ny/2;
06349 int nxc = nx/2;
06350 int nb = int(nz*(1.0f - section_use)/2.);
06351 int ne = nz - nb -1;
06352 int numst = int((ne - nb)/dp*pixel_size + 0.5);
06353
06354 int nst = int(nz*pixel_size/dp+0.5);
06355 float r2, ir;
06356 if(radius < 0.0f) r2 = (float)((nxc-1)*(nxc-1));
06357 else r2 = radius*radius;
06358 if(minrad < 0.0f) ir = 0.0f;
06359 else ir = minrad*minrad;
06360 for (int k = 0; k<nz; k++) {
06361 for (int j = 0; j<ny; j++) {
06362 int jy = j - nyc;
06363 int jj = jy*jy;
06364 for (int i = 0; i<nx; i++) {
06365 int ix = i - nxc;
06366 float d2 = (float)(ix*ix + jj);
06367 if(d2 <= r2 && d2>=ir) {
06368 int nq = 1;
06369 for ( int ist = -nst; ist <= nst; ist++) {
06370 float zold = (k*pixel_size + ist*dp)/pixel_size;
06371 int IOZ = int(zold);
06372 if(IOZ >= nb && IOZ <= ne) {
06373
06374 float cphi = ist*dphi*(float)DGR_TO_RAD;
06375 float ca = cos(cphi);
06376 float sa = sin(cphi);
06377 float xold = ix*ca - jy*sa + nxc;
06378 float yold = ix*sa + jy*ca + nyc;
06379 nq++;
06380
06381
06382
06383 int IOX = int(xold);
06384 int IOY = int(yold);
06385
06386
06387 #ifdef _WIN32
06388 int IOXp1 = _cpp_min( nx-1 ,IOX+1);
06389 #else
06390 int IOXp1 = std::min( nx-1 ,IOX+1);
06391 #endif //_WIN32
06392
06393 #ifdef _WIN32
06394 int IOYp1 = _cpp_min( ny-1 ,IOY+1);
06395 #else
06396 int IOYp1 = std::min( ny-1 ,IOY+1);
06397 #endif //_WIN32
06398
06399 #ifdef _WIN32
06400 int IOZp1 = _cpp_min( nz-1 ,IOZ+1);
06401 #else
06402 int IOZp1 = std::min( nz-1 ,IOZ+1);
06403 #endif //_WIN32
06404
06405 float dx = xold-IOX;
06406 float dy = yold-IOY;
06407 float dz = zold-IOZ;
06408
06409 float a1 = (*this)(IOX,IOY,IOZ);
06410 float a2 = (*this)(IOXp1,IOY,IOZ) - (*this)(IOX,IOY,IOZ);
06411 float a3 = (*this)(IOX,IOYp1,IOZ) - (*this)(IOX,IOY,IOZ);
06412 float a4 = (*this)(IOX,IOY,IOZp1) - (*this)(IOX,IOY,IOZ);
06413 float a5 = (*this)(IOX,IOY,IOZ) - (*this)(IOXp1,IOY,IOZ) - (*this)(IOX,IOYp1,IOZ) + (*this)(IOXp1,IOYp1,IOZ);
06414 float a6 = (*this)(IOX,IOY,IOZ) - (*this)(IOXp1,IOY,IOZ) - (*this)(IOX,IOY,IOZp1) + (*this)(IOXp1,IOY,IOZp1);
06415 float a7 = (*this)(IOX,IOY,IOZ) - (*this)(IOX,IOYp1,IOZ) - (*this)(IOX,IOY,IOZp1) + (*this)(IOX,IOYp1,IOZp1);
06416 float a8 = (*this)(IOXp1,IOY,IOZ) + (*this)(IOX,IOYp1,IOZ)+ (*this)(IOX,IOY,IOZp1)
06417 - (*this)(IOX,IOY,IOZ)- (*this)(IOXp1,IOYp1,IOZ) - (*this)(IOXp1,IOY,IOZp1)
06418 - (*this)(IOX,IOYp1,IOZp1) + (*this)(IOXp1,IOYp1,IOZp1);
06419 (*result)(i,j,k) += a1 + dz*(a4 + a6*dx + (a7 + a8*dx)*dy) + a3*dy + dx*(a2 + a5*dy);
06420
06421
06422 if(nq == numst) break;
06423 }
06424 }
06425 if(nq != numst)
06426 throw InvalidValueException(nq, "incorrect number of repeats encoutered.");
06427 }
06428 }
06429 }
06430 }
06431 for (int k = 0; k<nz; k++) for (int j = 0; j<ny; j++) for (int i = 0; i<nx; i++) (*result)(i,j,k) /= numst ;
06432
06433 result->update();
06434 return result;
06435 }
06436
06437
06438
06439
06440
06441
06442
06443
06444
06445
06446 void EMData::depad() {
06447 if (is_complex())
06448 throw ImageFormatException("Depadding of complex images not supported");
06449 vector<int> saved_offsets = get_array_offsets();
06450 set_array_offsets(0,0,0);
06451 int npad = attr_dict["npad"];
06452 if (0 == npad) npad = 1;
06453 int offset = is_fftodd() ? 1 : 2;
06454 int nxold = (nx - offset)/npad;
06455 #ifdef _WIN32
06456 int nyold = _cpp_max(ny/npad, 1);
06457 int nzold = _cpp_max(nz/npad, 1);
06458 #else
06459 int nyold = std::max<int>(ny/npad, 1);
06460 int nzold = std::max<int>(nz/npad, 1);
06461 #endif //_WIN32
06462 int xstart = 0, ystart = 0, zstart = 0;
06463 if( npad > 1) {
06464 xstart = (nx - offset - nxold)/2 + nxold%2;
06465 if(ny > 1) {
06466 ystart = (ny - nyold)/2 + nyold%2;
06467 if(nz > 1) {
06468 zstart = (nz - nzold)/2 + nzold%2;
06469 }
06470 }
06471 }
06472 int bytes = nxold*sizeof(float);
06473 float* dest = get_data();
06474 for (int iz=0; iz < nzold; iz++) {
06475 for (int iy = 0; iy < nyold; iy++) {
06476 memmove(dest, &(*this)(xstart,iy+ystart,iz+zstart), bytes);
06477 dest += nxold;
06478 }
06479 }
06480 set_size(nxold, nyold, nzold);
06481 set_attr("npad", 1);
06482 set_fftpad(false);
06483 set_fftodd(false);
06484 set_complex(false);
06485 if(ny==1 && nz==1) set_complex_x(false);
06486 set_array_offsets(saved_offsets);
06487 update();
06488 EXITFUNC;
06489 }
06490
06491
06492
06493
06494
06495
06496
06497
06498 void EMData::depad_corner() {
06499 if(is_complex())
06500 throw ImageFormatException("Depadding of complex images not allowed");
06501 vector<int> saved_offsets = get_array_offsets();
06502 set_array_offsets(0,0,0);
06503 int npad = attr_dict["npad"];
06504 if(0 == npad) npad = 1;
06505 int offset = is_fftodd() ? 1 : 2;
06506 int nxold = (nx - offset)/npad;
06507 #ifdef _WIN32
06508 int nyold = _cpp_max(ny/npad, 1);
06509 int nzold = _cpp_max(nz/npad, 1);
06510 #else
06511 int nyold = std::max<int>(ny/npad, 1);
06512 int nzold = std::max<int>(nz/npad, 1);
06513 #endif //_WIN32
06514 int bytes = nxold*sizeof(float);
06515 float* dest = get_data();
06516 for (int iz=0; iz < nzold; iz++) {
06517 for (int iy = 0; iy < nyold; iy++) {
06518 memmove(dest, &(*this)(0,iy,iz), bytes);
06519 dest += nxold;
06520 }
06521 }
06522 set_size(nxold, nyold, nzold);
06523 set_attr("npad", 1);
06524 set_fftpad(false);
06525 set_fftodd(false);
06526 set_complex(false);
06527 if(ny==1 && nz==1) set_complex_x(false);
06528 set_array_offsets(saved_offsets);
06529 update();
06530 EXITFUNC;
06531 }
06532
06533
06534
06535 float circumference( EMData* emdata, int npixel )
06536 {
06537 int nx = emdata->get_xsize();
06538 int ny = emdata->get_ysize();
06539 int nz = emdata->get_zsize();
06540
06541 float* data = emdata->get_data();
06542 if( ny==1 && nz==1 ) {
06543
06544 float sumf=0.0;
06545 int sumn=0;
06546 for( int i=0; i < npixel; ++i ) {
06547 sumf += data[i];
06548 sumf += data[nx-1-i];
06549 sumn += 2;
06550 }
06551 return sumf/sumn;
06552 }
06553
06554 if( nz==1 ) {
06555 float sumf=0.0;
06556 int sumn=0;
06557 int id=0;
06558 for( int iy=0; iy < ny; ++iy ) {
06559 for( int ix=0; ix < nx; ++ix ) {
06560 if( iy<npixel || iy>ny-1-npixel || ix<npixel || ix>nx-1-npixel ) {
06561 sumf += data[id];
06562 sumn += 1;
06563 }
06564 id++;
06565 }
06566 }
06567
06568 Assert( id==nx*ny );
06569 Assert( sumn == nx*ny - (nx-2*npixel)*(ny-2*npixel) );
06570 return sumf/sumn;
06571 }
06572
06573
06574
06575 float sumf = 0.0;
06576 int sumn = 0;
06577 int id = 0;
06578 for( int iz=0; iz < nz; ++iz) {
06579 for( int iy=0; iy < ny; ++iy) {
06580 for( int ix=0; ix < nx; ++ix ) {
06581 if( iz<npixel||iz>nz-1-npixel||iy<npixel||iy>ny-1-npixel||ix<npixel||ix>nx-1-npixel) {
06582 sumf += data[id];
06583 sumn += 1;
06584 }
06585 id++;
06586 }
06587 }
06588 }
06589
06590
06591 Assert( id==nx*ny*nz);
06592 Assert( sumn==nx*ny*nz-(nx-2*npixel)*(ny-2*npixel)*(nz-2*npixel) );
06593 return sumf/sumn;
06594 }
06595
06596
06597
06598
06599
06600
06601
06602
06603 EMData* EMData::norm_pad(bool donorm, int npad, int valtype) {
06604 if (this->is_complex())
06605 throw ImageFormatException("Padding of complex images not supported");
06606 int nx = this->get_xsize();
06607 int ny = this->get_ysize();
06608 int nz = this->get_zsize();
06609 float mean = 0., stddev = 1.;
06610 if(donorm) {
06611 mean = this->get_attr("mean");
06612 stddev = this->get_attr("sigma");
06613 }
06614
06615 if (npad < 1) npad = 1;
06616 int nxpad = npad*nx;
06617 int nypad = npad*ny;
06618 int nzpad = npad*nz;
06619 if (1 == ny) {
06620
06621
06622 nypad = ny;
06623 nzpad = nz;
06624 } else if (nz == 1) {
06625
06626 nzpad = nz;
06627 }
06628 size_t bytes;
06629 size_t offset;
06630
06631 offset = 2 - nxpad%2;
06632 bytes = nx*sizeof(float);
06633 EMData* fpimage = copy_head();
06634 fpimage->set_size(nxpad+offset, nypad, nzpad);
06635 int xstart = 0, ystart = 0, zstart = 0;
06636 if( npad > 1) {
06637 if( valtype==0 ) {
06638 fpimage->to_zero();
06639 } else {
06640 float val = circumference(this, 1);
06641 float* data = fpimage->get_data();
06642 int nxyz = (nxpad+offset)*nypad*nzpad;
06643 for( int i=0; i < nxyz; ++i ) data[i] = val;
06644 }
06645
06646 xstart = (nxpad - nx)/2 + nx%2;
06647 if(ny > 1) {
06648 ystart = (nypad - ny)/2 + ny%2;
06649 if(nz > 1) {
06650 zstart = (nzpad - nz)/2 + nz%2;
06651 }
06652 }
06653 }
06654
06655
06656 vector<int> saved_offsets = this->get_array_offsets();
06657 this->set_array_offsets( 0, 0, 0 );
06658 for (int iz = 0; iz < nz; iz++) {
06659 for (int iy = 0; iy < ny; iy++) {
06660 memcpy(&(*fpimage)(xstart,iy+ystart,iz+zstart), &(*this)(0,iy,iz), bytes);
06661 }
06662 }
06663 this->set_array_offsets( saved_offsets );
06664
06665
06666
06667
06668 if (donorm) {
06669 for (int iz = zstart; iz < nz+zstart; iz++)
06670 for (int iy = ystart; iy < ny+ystart; iy++)
06671 for (int ix = xstart; ix < nx+xstart; ix++)
06672 (*fpimage)(ix,iy,iz) = ((*fpimage)(ix,iy,iz)-mean)/stddev;
06673 }
06674
06675 fpimage->set_fftpad(true);
06676 fpimage->set_attr("npad", npad);
06677 if (offset == 1) fpimage->set_fftodd(true);
06678 else fpimage->set_fftodd(false);
06679 return fpimage;
06680 }
06681
06682 void EMData::center_origin()
06683 {
06684 ENTERFUNC;
06685 if (is_complex()) {
06686 LOGERR("Real image expected. Input image is complex.");
06687 throw ImageFormatException("Real image expected. Input image is complex.");
06688 }
06689 for (int iz = 0; iz < nz; iz++) {
06690 for (int iy = 0; iy < ny; iy++) {
06691 for (int ix = 0; ix < nx; ix++) {
06692
06693 (*this)(ix,iy,iz) *= -2*((ix+iy+iz)%2) + 1;
06694 }
06695 }
06696 }
06697 update();
06698 EXITFUNC;
06699 }
06700
06701 void EMData::center_origin_yz()
06702 {
06703 ENTERFUNC;
06704 if (is_complex()) {
06705 LOGERR("Real image expected. Input image is complex.");
06706 throw ImageFormatException("Real image expected. Input image is complex.");
06707 }
06708 for (int iz = 0; iz < nz; iz++) {
06709 for (int iy = (iz+1)%2; iy < ny; iy+=2) {
06710 for (int ix = 0; ix < nx; ix++) {
06711 (*this)(ix,iy,iz) *= -1;
06712 }
06713 }
06714 }
06715 update();
06716 EXITFUNC;
06717 }
06718
06719 void EMData::center_origin_fft()
06720 {
06721 ENTERFUNC;
06722 if (!is_complex()) {
06723 LOGERR("complex image expected. Input image is real image.");
06724 throw ImageFormatException("complex image expected. Input image is real image.");
06725 }
06726
06727 if (!is_ri()) {
06728 LOGWARN("Only RI should be used. ");
06729 }
06730 vector<int> saved_offsets = get_array_offsets();
06731
06732
06733
06734 set_array_offsets(0,1,1);
06735 int nxc = nx/2;
06736
06737 if (is_fftodd()) {
06738 for (int iz = 1; iz <= nz; iz++) {
06739 for (int iy = 1; iy <= ny; iy++) {
06740 for (int ix = 0; ix < nxc; ix++) {
06741 cmplx(ix,iy,iz) *= float(-2*((ix+iy+iz)%2) + 1);
06742 float temp = float(iz-1+iy-1+ix)/float(ny)*M_PI;
06743 complex<float> temp2 = complex<float>(cos(temp), -sin(temp));
06744 cmplx(ix,iy,iz) *= temp2;
06745 }
06746 }
06747 }
06748 } else {
06749 for (int iz = 1; iz <= nz; iz++) {
06750 for (int iy = 1; iy <= ny; iy++) {
06751 for (int ix = 0; ix < nxc; ix++) {
06752
06753 cmplx(ix,iy,iz) *= float(-2*((ix+iy+iz)%2) + 1);
06754 }
06755 }
06756 }
06757 }
06758 set_array_offsets(saved_offsets);
06759 update();
06760 EXITFUNC;
06761 }
06762
06763
06764 #define fint(i,j,k) fint[(i-1) + ((j-1) + (k-1)*ny)*lsd]
06765 #define fout(i,j,k) fout[(i-1) + ((j-1) + (k-1)*nyn)*lsdn]
06766 EMData *EMData::FourInterpol(int nxn, int nyni, int nzni, bool RetReal) {
06767
06768 int nyn, nzn, lsd, lsdn, inx, iny, inz;
06769 int i, j, k;
06770 if (is_complex())
06771 throw ImageFormatException("Input image has to be real");
06772
06773 if(ny > 1) {
06774 nyn = nyni;
06775 if(nz > 1) {
06776 nzn = nzni;
06777 } else {
06778 nzn = 1;
06779 }
06780 } else {
06781 nyn = 1; nzn = 1;
06782 }
06783 if(nxn<nx || nyn<ny || nzn<nz) throw ImageDimensionException("Cannot reduce the image size");
06784 lsd = nx + 2 - nx%2;
06785 lsdn = nxn + 2 - nxn%2;
06786
06787 EMData *temp_ft = do_fft();
06788 EMData *ret = this->copy();
06789 ret->set_size(lsdn, nyn, nzn);
06790 ret->to_zero();
06791 float *fout = ret->get_data();
06792 float *fint = temp_ft->get_data();
06793
06794
06795 float sq2 = 1.0f/std::sqrt(2.0f);
06796 float anorm = (float) nxn* (float) nyn* (float) nzn/(float) nx/ (float) ny/ (float) nz;
06797 for (i = 0; i < lsd*ny*nz; i++) fint[i] *= anorm;
06798 inx = nxn-nx; iny = nyn - ny; inz = nzn - nz;
06799 for (k=1; k<=nz/2+1; k++) for (j=1; j<=ny/2+1; j++) for (i=1; i<=lsd; i++) fout(i,j,k)=fint(i,j,k);
06800 if(nyn>1) {
06801
06802 for (k=1; k<=nz/2+1; k++) for (j=ny/2+2+iny; j<=nyn; j++) for (i=1; i<=lsd; i++) fout(i,j,k)=fint(i,j-iny,k);
06803 if(nzn>1) {
06804 for (k=nz/2+2+inz; k<=nzn; k++) {
06805 for (j=1; j<=ny/2+1; j++) {
06806 for (i=1; i<=lsd; i++) {
06807 fout(i,j,k)=fint(i,j,k-inz);
06808 }
06809 }
06810 for (j=ny/2+2+iny; j<=nyn; j++) {
06811 for (i=1; i<=lsd; i++) {
06812 fout(i,j,k)=fint(i,j-iny,k-inz);
06813 }
06814 }
06815 }
06816 }
06817 }
06818
06819
06820
06821 if(nx%2 == 0 && inx !=0) {
06822 for (k=1; k<=nzn; k++) {
06823 for (j=1; j<=nyn; j++) {
06824 fout(nx+1,j,k) *= sq2;
06825 fout(nx+2,j,k) *= sq2;
06826 }
06827 }
06828 if(nyn>1) {
06829 for (k=1; k<=nzn; k++) {
06830 for (i=1; i<=lsd; i++) {
06831 fout(i,ny/2+1+iny,k) = sq2*fout(i,ny/2+1,k);
06832 fout(i,ny/2+1,k) *= sq2;
06833 }
06834 }
06835 if(nzn>1) {
06836 for (j=1; j<=nyn; j++) {
06837 for (i=1; i<=lsd; i++) {
06838 fout(i,j,nz/2+1+inz) = sq2*fout(i,j,nz/2+1);
06839 fout(i,j,nz/2+1) *= sq2;
06840 }
06841 }
06842 }
06843 }
06844 }
06845 ret->set_complex(true);
06846
06847
06848
06849
06850
06851
06852
06853
06854
06855
06856
06857
06858
06859
06860
06861
06862
06863
06864
06865
06866
06867
06868
06869
06870
06871
06872
06873
06874
06875
06876
06877
06878
06879 ret->set_ri(1);
06880 ret->set_fftpad(true);
06881 ret->set_attr("npad", 1);
06882 if (nxn%2 == 1) {ret->set_fftodd(true);} else {ret->set_fftodd(false);}
06883 if(RetReal) {
06884 ret->do_ift_inplace();
06885 ret->depad();
06886 }
06887 ret->update();
06888
06889
06890
06891
06892
06893
06894
06895 delete temp_ft;
06896 temp_ft = 0;
06897 return ret;
06898 }
06899
06900 EMData *EMData::FourTruncate(int nxn, int nyni, int nzni, bool RetReal) {
06901
06902 int nyn, nzn, lsd, lsdn, inx, iny, inz;
06903 int i, j, k;
06904 float *fint;
06905 EMData *temp_ft = NULL;
06906
06907
06908
06909 if(ny > 1) {
06910 nyn = nyni;
06911 if(nz > 1) {
06912 nzn = nzni;
06913 } else {
06914 nzn = 1;
06915 }
06916 } else {
06917 nyn = 1; nzn = 1;
06918 }
06919 if (is_complex()) {
06920 nx = nx - 2 + nx%2;
06921 fint = get_data();
06922 } else {
06923
06924 temp_ft = do_fft();
06925 fint = temp_ft->get_data();
06926 }
06927 if(nxn>nx || nyn>ny || nzn>nz) throw ImageDimensionException("Cannot increase the image size");
06928 lsd = nx + 2 - nx%2;
06929 lsdn = nxn + 2 - nxn%2;
06930 EMData *ret = this->copy_head();
06931 ret->set_size(lsdn, nyn, nzn);
06932 float *fout = ret->get_data();
06933
06934
06935
06936 float anorm = (float) nxn* (float) nyn* (float) nzn/(float) nx/ (float) ny/ (float) nz;
06937 for (i = 0; i < lsd*ny*nz; i++) fint[i] *= anorm;
06938 inx = nx - nxn; iny = ny - nyn; inz = nz - nzn;
06939 for (k=1; k<=nzn/2+1; k++) for (j=1; j<=nyn/2+1; j++) for (i=1; i<=lsdn; i++) fout(i,j,k)=fint(i,j,k);
06940 if(nyn>1) {
06941 for (k=1; k<=nzn/2+1; k++) for (j=nyn/2+2; j<=nyn; j++) for (i=1; i<=lsdn; i++) fout(i,j,k)=fint(i,j+iny,k);
06942 if(nzn>1) {
06943 for (k=nzn/2+2; k<=nzn; k++) {
06944 for (j=1; j<=nyn/2+1; j++) {
06945 for (i=1; i<=lsdn; i++) {
06946 fout(i,j,k)=fint(i,j,k+inz);
06947 }
06948 }
06949 for (j=nyn/2+2; j<=nyn; j++) {
06950 for (i=1; i<=lsdn; i++) {
06951 fout(i,j,k)=fint(i,j+iny,k+inz);
06952 }
06953 }
06954 }
06955 }
06956 }
06957
06958
06959
06960
06961
06962
06963
06964
06965
06966
06967
06968
06969
06970
06971
06972
06973
06974
06975
06976
06977
06978
06979
06980
06981
06982
06983
06984
06985 ret->set_complex(true);
06986 ret->set_ri(1);
06987 ret->set_fftpad(true);
06988 ret->set_attr("npad", 1);
06989 if (nxn%2 == 1) {ret->set_fftodd(true);} else {ret->set_fftodd(false);}
06990 if(RetReal) {
06991 ret->do_ift_inplace();
06992 ret->depad();
06993 }
06994 ret->update();
06995
06996
06997
06998
06999
07000
07001
07002 if (!is_complex()) {
07003 delete temp_ft;
07004 temp_ft = 0;
07005 }
07006 return ret;
07007 }
07008
07009
07010
07011
07012
07013
07014
07015
07016
07017
07018
07019
07020
07021
07022
07023
07024
07025
07026
07027
07028
07029
07030
07031
07032
07033
07034
07035
07036
07037
07038
07039
07040
07041
07042
07043
07044
07045
07046
07047
07048
07049
07050
07051
07052
07053
07054
07055
07056
07057
07058
07059
07060
07061
07062
07063
07064
07065
07066
07067
07068
07069
07070
07071
07072
07073
07074
07075
07076
07077
07078
07079
07080
07081
07082
07083
07084
07085
07086
07087
07088
07089
07090
07091
07092
07093
07094
07095
07096
07097
07098
07099
07100
07101
07102
07103 EMData *EMData::Four_ds(int nxn, int nyni, int nzni, bool RetReal) {
07104
07105 int nyn, nzn, lsd, lsdn, inx, iny, inz;
07106 int i, j;
07107
07108 if(ny > 1) {
07109 nyn = nyni;
07110 if(nz > 1) {
07111 nzn = nzni;
07112 } else {
07113 nzn = 1;
07114 }
07115 } else {
07116 nyn = 1; nzn = 1;
07117 }
07118 lsd = nx-2 + 2 - nx%2;
07119 lsdn = nxn + 2 - nxn%2;
07120
07121 EMData *temp_ft = this->copy();
07122 EMData *ret = this->copy();
07123 ret->set_size(lsdn, nyn, nzn);
07124 ret->to_zero();
07125 float *fout = ret->get_data();
07126 float *fint = temp_ft->get_data();
07127
07128
07129
07130 float anorm = (float) nxn* (float) nyn* (float) nzn/(float) nx/ (float) ny/ (float) nz;
07131 for (i = 0; i < lsd*ny*nz; i++) fint[i] *= anorm;
07132 inx = nxn-(nx-2); iny = nyn - ny; inz = nzn - nz;
07133 for (j=1; j<=nyn; j++)
07134 for (i=1; i<=lsdn; i++)
07135 fout(i,j,1)=fint((i-1)/2*4+2-i%2,j*2-1,1);
07136 ret->set_complex(true);
07137 ret->set_ri(1);
07138
07139
07140 if (nxn%2 == 1) {ret->set_fftodd(true);} else {ret->set_fftodd(false);}
07141 if(RetReal) {
07142 ret->do_ift_inplace();
07143 ret->depad();
07144 }
07145 ret->update();
07146
07147 delete temp_ft;
07148 temp_ft = 0;
07149 return ret;
07150 }
07151
07152 EMData *EMData::Four_shuf_ds_cen_us(int nxn, int nyni, int, bool RetReal) {
07153
07154 int nyn, nzn, lsd, lsdn, inx, iny, inz;
07155 int i, j;
07156
07157 nyn = nyni;
07158 nzn = 1;
07159 lsd = nx;
07160 lsdn = nxn + 2 - nxn%2;
07161
07162 EMData *temp_ft = this->copy();
07163 EMData *ret = this->copy();
07164 ret->set_size(lsdn, nyn, nzn);
07165 ret->to_zero();
07166 float *fout = ret->get_data();
07167 float *fint = temp_ft->get_data();
07168
07169
07170 float sq2 = 1.0f/std::sqrt(2.0f);
07171
07172 for (i = 0; i < lsd*ny*nz; i++) fint[i] *= 4;
07173
07174 inx = nxn-(nx-2); iny = nyn - ny; inz = nzn - nz;
07175 for (j=1; j<=ny/4; j++)
07176 for (i=1; i<=(nx-2)/2+2; i++) {
07177 int g = (i-1)/2+1;
07178 if ((g+j)%2 == 0) {
07179 fout(i,j,1)=fint(g*4-2-i%2,j*2-1+ny/2,1);
07180 } else {
07181 fout(i,j,1)=-fint(g*4-2-i%2,j*2-1+ny/2,1);
07182 }
07183 }
07184
07185 for (j=ny/4+1; j<=ny/4+1; j++)
07186 for (i=1; i<=(nx-2)/2+2; i++) {
07187 int g = (i-1)/2+1;
07188 if ((g+j)%2 == 0) {
07189 fout(i,j,1)=fint(g*4-2-i%2,j*2-1-ny/2,1);
07190 } else {
07191 fout(i,j,1)=-fint(g*4-2-i%2,j*2-1-ny/2,1);
07192 }
07193 }
07194
07195 for (j=ny/4+2; j<=ny/2; j++)
07196 for (i=1; i<=(nx-2)/2+2; i++) {
07197 int g = (i-1)/2+1;
07198 if ((g+j)%2 == 0) {
07199 fout(i,j+ny/2,1)=fint(g*4-2-i%2,j*2-1-ny/2,1);
07200 } else {
07201 fout(i,j+ny/2,1)=-fint(g*4-2-i%2,j*2-1-ny/2,1);
07202 }
07203 }
07204
07205 if (nx%2 == 0) {
07206 for (j=1; j<=nyn; j++) {
07207 fout((nx-2)/2+1,j,1) *= sq2;
07208 fout((nx-2)/2+2,j,1) *= sq2;
07209 }
07210 for (i=1; i<=lsd/2+1; i++) {
07211 fout(i,ny/4+1+ny/2,1) = sq2*fout(i,ny/4+1,1);
07212 fout(i,ny/4+1,1) *= sq2;
07213 }
07214 }
07215
07216 ret->set_complex(true);
07217 ret->set_ri(1);
07218
07219 if (nxn%2 == 1) {ret->set_fftodd(true);} else {ret->set_fftodd(false);}
07220 if(RetReal) {
07221 ret->do_ift_inplace();
07222 ret->depad();
07223 }
07224 ret->update();
07225
07226 delete temp_ft;
07227 temp_ft = 0;
07228 return ret;
07229 }
07230
07231 #undef fint
07232 #undef fout
07233
07234 #define fint(jx,jy,jz) fint[jx + (jy + jz*ny)*nox]
07235 EMData *EMData::filter_by_image(EMData* image, bool RetReal) {
07236
07237
07238 bool complex_input = this->is_complex();
07239 nx = this->get_xsize();
07240 ny = this->get_ysize();
07241 nz = this->get_zsize();
07242 int nox;
07243 if (complex_input) nox = (nx - 2 + this->is_fftodd()); else nox = nx;
07244
07245 int lsd2 = (nox + 2 - nox%2) / 2;
07246
07247 EMData* fp = NULL;
07248 if(complex_input) {
07249
07250 fp = this->copy();
07251 } else {
07252 fp = this->norm_pad( false, 1);
07253 fp->do_fft_inplace();
07254 }
07255 fp->set_array_offsets(1,1,1);
07256 int nx2 = nox/2;
07257 int ny2 = ny/2;
07258 int nz2 = nz/2;
07259 float *fint = image->get_data();
07260 for ( int iz = 1; iz <= nz; iz++) {
07261 int jz=nz2-iz+1; if(jz<0) jz += nz;
07262 for ( int iy = 1; iy <= ny; iy++) {
07263 int jy=ny2-iy+1; if(jy<0) jy += ny;
07264 for ( int ix = 1; ix <= lsd2; ix++) {
07265 int jx = nx2-ix+1;
07266 fp->cmplx(ix,iy,iz) *= fint(jx,jy,jz);
07267 }
07268 }
07269 }
07270
07271 fp->set_ri(1);
07272 fp->set_fftpad(true);
07273 fp->set_attr("npad", 1);
07274 if (nx%2 == 1) fp->set_fftodd(true);
07275 else fp->set_fftodd(false);
07276 if(RetReal) {
07277 fp->do_ift_inplace();
07278 fp->depad();
07279 }
07280 fp->set_array_offsets(0,0,0);
07281 fp->update();
07282
07283 return fp;
07284 }
07285 #undef fint
07286 #define fint(jx,jy,jz) fint[jx + (jy + jz*ny)*nx]
07287 #define fout(jx,jy,jz) fout[jx + (jy + jz*ny)*nx]
07288 EMData *EMData::replace_amplitudes(EMData* image, bool RetReal) {
07289
07290
07291 bool complex_input = this->is_complex();
07292 nx = this->get_xsize();
07293 ny = this->get_ysize();
07294 nz = this->get_zsize();
07295 int nox;
07296 if (complex_input) nox = (nx - 2 + this->is_fftodd()); else nox = nx;
07297
07298 EMData* fp = NULL;
07299 if(complex_input) {
07300
07301 fp = this->copy();
07302 } else {
07303 fp = this->norm_pad( false, 1);
07304 fp->do_fft_inplace();
07305 }
07306 float *fout = fp->get_data();
07307 float *fint = image->get_data();
07308 for ( int iz = 0; iz < nz; iz++) {
07309 for ( int iy = 0; iy < ny; iy++) {
07310 for ( int ix = 0; ix < nx; ix+=2) {
07311 float qt = fint(ix,iy,iz)*fint(ix,iy,iz)+fint(ix+1,iy,iz)*fint(ix+1,iy,iz);
07312 float rt = fout(ix,iy,iz)*fout(ix,iy,iz)+fout(ix+1,iy,iz)*fout(ix+1,iy,iz);
07313 if(rt > 1.0e-20) {
07314 fout(ix,iy,iz) *= (qt/rt);
07315 fout(ix+1,iy,iz) *= (qt/rt);
07316 } else {
07317 qt = std::sqrt(qt/2.0f);
07318 fout(ix,iy,iz) = qt;
07319 fout(ix+1,iy,iz) = qt;
07320 }
07321 }
07322 }
07323 }
07324
07325 fp->set_ri(1);
07326 fp->set_fftpad(true);
07327 fp->set_attr("npad", 1);
07328 if (nx%2 == 1) fp->set_fftodd(true);
07329 else fp->set_fftodd(false);
07330 if(RetReal) {
07331 fp->do_ift_inplace();
07332 fp->depad();
07333 }
07334 fp->set_array_offsets(0,0,0);
07335 fp->update();
07336
07337 return fp;
07338 }
07339 #undef fint
07340 #undef fout
07341
07342
07343 #undef QUADPI
07344 #undef DGR_TO_RAD