util_sparx.cpp

Go to the documentation of this file.
00001 
00005 /*
00006  * Author: Pawel A.Penczek, 09/09/2006 (Pawel.A.Penczek@uth.tmc.edu)
00007  * Copyright (c) 2000-2006 The University of Texas - Houston Medical School
00008  *
00009  * This software is issued under a joint BSD/GNU license. You may use the
00010  * source code in this file under either license. However, note that the
00011  * complete EMAN2 and SPARX software packages have some GPL dependencies,
00012  * so you are responsible for compliance with the licenses of these packages
00013  * if you opt to use BSD licensing. The warranty disclaimer below holds
00014  * in either instance.
00015  *
00016  * This complete copyright notice must be included in any revised version of the
00017  * source code. Additional authorship citations may be added, but existing
00018  * author citations must be preserved.
00019  *
00020  * This program is free software; you can redistribute it and/or modify
00021  * it under the terms of the GNU General Public License as published by
00022  * the Free Software Foundation; either version 2 of the License, or
00023  * (at your option) any later version.
00024  *
00025  * This program is distributed in the hope that it will be useful,
00026  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00027  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00028  * GNU General Public License for more details.
00029  *
00030  * You should have received a copy of the GNU General Public License
00031  * along with this program; if not, write to the Free Software
00032  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00033  *
00034  */
00035 
00036 #ifdef _WIN32
00037         #pragma warning(disable:4819)
00038 #endif  //_WIN32
00039 
00040 #include <cstring>
00041 #include <ctime>
00042 #include <iostream>
00043 #include <cstdio>
00044 #include <cstdlib>
00045 #include <boost/format.hpp>
00046 #include "emdata.h"
00047 #include "util.h"
00048 #include "fundamentals.h"
00049 #include "lapackblas.h"
00050 #include "lbfgsb.h"
00051 using namespace EMAN;
00052 #include "steepest.h"
00053 #include "emassert.h"
00054 #include "randnum.h"
00055 
00056 #include <gsl/gsl_sf_bessel.h>
00057 #include <gsl/gsl_sf_bessel.h>
00058 #include <cmath>
00059 using namespace std;
00060 using std::complex;
00061 
00062 vector<float> Util::infomask(EMData* Vol, EMData* mask, bool flip = false)
00063 //  flip true:  find statistics under the mask (mask >0.5)
00064 //  flip false: find statistics ourside the mask (mask <0.5)
00065 {
00066         ENTERFUNC;
00067         vector<float> stats;
00068         float *Volptr, *maskptr,MAX,MIN;
00069         long double Sum1,Sum2;
00070         long count;
00071 
00072         MAX = -FLT_MAX;
00073         MIN =  FLT_MAX;
00074         count = 0L;
00075         Sum1 = 0.0L;
00076         Sum2 = 0.0L;
00077 
00078         if (mask == NULL) {
00079            //Vol->update_stat();
00080            stats.push_back(Vol->get_attr("mean"));
00081            stats.push_back(Vol->get_attr("sigma"));
00082            stats.push_back(Vol->get_attr("minimum"));
00083            stats.push_back(Vol->get_attr("maximum"));
00084            return stats;
00085         }
00086 
00087         /* Check if the sizes of the mask and image are same */
00088 
00089         size_t nx = Vol->get_xsize();
00090         size_t ny = Vol->get_ysize();
00091         size_t nz = Vol->get_zsize();
00092 
00093         size_t mask_nx = mask->get_xsize();
00094         size_t mask_ny = mask->get_ysize();
00095         size_t mask_nz = mask->get_zsize();
00096 
00097         if  (nx != mask_nx || ny != mask_ny || nz != mask_nz )
00098                 throw ImageDimensionException("The dimension of the image does not match the dimension of the mask!");
00099 
00100  /*       if (nx != mask_nx ||
00101             ny != mask_ny ||
00102             nz != mask_nz  ) {
00103            // should throw an exception here!!! (will clean it up later CY)
00104            fprintf(stderr, "The dimension of the image does not match the dimension of the mask!\n");
00105            fprintf(stderr, " nx = %d, mask_nx = %d\n", nx, mask_nx);
00106            fprintf(stderr, " ny = %d, mask_ny = %d\n", ny, mask_ny);
00107            fprintf(stderr, " nz = %d, mask_nz = %d\n", nz, mask_nz);
00108            exit(1);
00109         }
00110  */
00111         Volptr = Vol->get_data();
00112         maskptr = mask->get_data();
00113 
00114         for (size_t i = 0; i < nx*ny*nz; i++) {
00115               if (maskptr[i]>0.5f == flip) {
00116                 Sum1 += Volptr[i];
00117                 Sum2 += Volptr[i]*Volptr[i];
00118                 MAX = (MAX < Volptr[i])?Volptr[i]:MAX;
00119                 MIN = (MIN > Volptr[i])?Volptr[i]:MIN;
00120                 count++;
00121               }
00122         }
00123 
00124         if (count == 0) {
00125                 LOGERR("Invalid mask");
00126                 throw ImageFormatException( "Invalid mask");
00127         }
00128 
00129        float avg = static_cast<float>(Sum1/count);
00130        float sig2 = static_cast<float>(Sum2 - count*avg*avg)/(count-1);
00131        float sig = sqrt(sig2);
00132 
00133        stats.push_back(avg);
00134        stats.push_back(sig);
00135        stats.push_back(MIN);
00136        stats.push_back(MAX);
00137 
00138        return stats;
00139 }
00140 
00141 
00142 //----------------------------------------------------------------------------------------------------------
00143 
00144 Dict Util::im_diff(EMData* V1, EMData* V2, EMData* mask)
00145 {
00146         ENTERFUNC;
00147 
00148         if (!EMUtil::is_same_size(V1, V2)) {
00149                 LOGERR("images not same size");
00150                 throw ImageFormatException( "images not same size");
00151         }
00152 
00153         size_t nx = V1->get_xsize();
00154         size_t ny = V1->get_ysize();
00155         size_t nz = V1->get_zsize();
00156         size_t size = nx*ny*nz;
00157 
00158         EMData *BD = new EMData();
00159         BD->set_size(nx, ny, nz);
00160 
00161         float *params = new float[2];
00162 
00163         float *V1ptr, *V2ptr, *MASKptr, *BDptr, A, B;
00164         long double S1=0.L,S2=0.L,S3=0.L,S4=0.L;
00165         int nvox = 0L;
00166 
00167         V1ptr = V1->get_data();
00168         V2ptr = V2->get_data();
00169         BDptr = BD->get_data();
00170 
00171 
00172         if(!mask){
00173                 EMData * Mask = new EMData();
00174                 Mask->set_size(nx,ny,nz);
00175                 Mask->to_one();
00176                 MASKptr = Mask->get_data();
00177         } else {
00178                 if (!EMUtil::is_same_size(V1, mask)) {
00179                         LOGERR("mask not same size");
00180                         throw ImageFormatException( "mask not same size");
00181                 }
00182 
00183                 MASKptr = mask->get_data();
00184         }
00185 
00186 
00187 
00188 //       calculation of S1,S2,S3,S3,nvox
00189 
00190         for (size_t i = 0L;i < size; i++) {
00191               if (MASKptr[i]>0.5f) {
00192                S1 += V1ptr[i]*V2ptr[i];
00193                S2 += V1ptr[i]*V1ptr[i];
00194                S3 += V2ptr[i];
00195                S4 += V1ptr[i];
00196                nvox ++;
00197               }
00198         }
00199 
00200         if ((nvox*S1 - S3*S4) == 0. || (nvox*S2 - S4*S4) == 0) {
00201                 A =1.0f ;
00202         } else {
00203                 A = static_cast<float>( (nvox*S1 - S3*S4)/(nvox*S2 - S4*S4) );
00204         }
00205         B = static_cast<float> (A*S4  -  S3)/nvox;
00206 
00207         // calculation of the difference image
00208 
00209         for (size_t i = 0L;i < size; i++) {
00210              if (MASKptr[i]>0.5f) {
00211                BDptr[i] = A*V1ptr[i] -  B  - V2ptr[i];
00212              }  else  {
00213                BDptr[i] = 0.f;
00214              }
00215         }
00216 
00217         BD->update();
00218 
00219         params[0] = A;
00220         params[1] = B;
00221 
00222         Dict BDnParams;
00223         BDnParams["imdiff"] = BD;
00224         BDnParams["A"] = params[0];
00225         BDnParams["B"] = params[1];
00226 
00227         EXITFUNC;
00228         return BDnParams;
00229  }
00230 
00231 //----------------------------------------------------------------------------------------------------------
00232 
00233 
00234 
00235 EMData *Util::TwoDTestFunc(int Size, float p, float q,  float a, float b, int flag, float alphaDeg) //PRB
00236 {
00237         ENTERFUNC;
00238         int Mid= (Size+1)/2;
00239 
00240         if (flag==0) { // This is the real function
00241                 EMData* ImBW = new EMData();
00242                 ImBW->set_size(Size,Size,1);
00243                 ImBW->to_zero();
00244 
00245                 float tempIm;
00246                 float x,y;
00247 
00248                 for (int ix=(1-Mid);  ix<Mid; ix++){
00249                         for (int iy=(1-Mid);  iy<Mid; iy++){
00250                                 x = (float)ix;
00251                                 y = (float)iy;
00252                         tempIm= static_cast<float>( (1/(2*M_PI)) * cos(p*x)* cos(q*y) * exp(-.5*x*x/(a*a))* exp(-.5*y*y/(b*b)) );
00253                                 (*ImBW)(ix+Mid-1,iy+Mid-1) = tempIm * exp(.5f*p*p*a*a)* exp(.5f*q*q*b*b);
00254                         }
00255                 }
00256                 ImBW->update();
00257                 ImBW->set_complex(false);
00258                 ImBW->set_ri(true);
00259 
00260                 return ImBW;
00261         }
00262         else if (flag==1) {  // This is the Fourier Transform
00263                 EMData* ImBWFFT = new EMData();
00264                 ImBWFFT ->set_size(2*Size,Size,1);
00265                 ImBWFFT ->to_zero();
00266 
00267                 float r,s;
00268 
00269                 for (int ir=(1-Mid);  ir<Mid; ir++){
00270                         for (int is=(1-Mid);  is<Mid; is++){
00271                                 r = (float)ir;
00272                                 s = (float)is;
00273                         (*ImBWFFT)(2*(ir+Mid-1),is+Mid-1)= cosh(p*r*a*a) * cosh(q*s*b*b) *
00274                                 exp(-.5f*r*r*a*a)* exp(-.5f*s*s*b*b);
00275                         }
00276                 }
00277                 ImBWFFT->update();
00278                 ImBWFFT->set_complex(true);
00279                 ImBWFFT->set_ri(true);
00280                 ImBWFFT->set_shuffled(true);
00281                 ImBWFFT->set_fftodd(true);
00282 
00283                 return ImBWFFT;
00284         }
00285         else if (flag==2 || flag==3) { //   This is the projection in Real Space
00286                 float alpha = static_cast<float>( alphaDeg*M_PI/180.0 );
00287                 float C=cos(alpha);
00288                 float S=sin(alpha);
00289                 float D= sqrt(S*S*b*b + C*C*a*a);
00290                 //float D2 = D*D;   PAP - to get rid of warning
00291 
00292                 float P = p * C *a*a/D ;
00293                 float Q = q * S *b*b/D ;
00294 
00295                 if (flag==2) {
00296                         EMData* pofalpha = new EMData();
00297                         pofalpha ->set_size(Size,1,1);
00298                         pofalpha ->to_zero();
00299 
00300                         float Norm0 =  D*(float)sqrt(2*pi);
00301                         float Norm1 =  exp( .5f*(P+Q)*(P+Q)) / Norm0 ;
00302                         float Norm2 =  exp( .5f*(P-Q)*(P-Q)) / Norm0 ;
00303                         float sD;
00304 
00305                         for (int is=(1-Mid);  is<Mid; is++){
00306                                 sD = is/D ;
00307                                 (*pofalpha)(is+Mid-1) =  Norm1 * exp(-.5f*sD*sD)*cos(sD*(P+Q))
00308                          + Norm2 * exp(-.5f*sD*sD)*cos(sD*(P-Q));
00309                         }
00310                         pofalpha-> update();
00311                         pofalpha-> set_complex(false);
00312                         pofalpha-> set_ri(true);
00313 
00314                         return pofalpha;
00315                 }
00316                 if (flag==3) { // This is the projection in Fourier Space
00317                         float vD;
00318 
00319                         EMData* pofalphak = new EMData();
00320                         pofalphak ->set_size(2*Size,1,1);
00321                         pofalphak ->to_zero();
00322 
00323                         for (int iv=(1-Mid);  iv<Mid; iv++){
00324                                 vD = iv*D ;
00325                                 (*pofalphak)(2*(iv+Mid-1)) =  exp(-.5f*vD*vD)*(cosh(vD*(P+Q)) + cosh(vD*(P-Q)) );
00326                         }
00327                         pofalphak-> update();
00328                         pofalphak-> set_complex(false);
00329                         pofalphak-> set_ri(true);
00330 
00331                         return pofalphak;
00332                 }
00333         }
00334         else if (flag==4) {
00335                 cout <<" FH under construction";
00336                 EMData* OutFT= TwoDTestFunc(Size, p, q, a, b, 1);
00337                 EMData* TryFH= OutFT -> real2FH(4.0);
00338                 return TryFH;
00339         } else {
00340                 cout <<" flag must be 0,1,2,3, or 4";
00341         }
00342 
00343         EXITFUNC;
00344         return 0;
00345 }
00346 
00347 
00348 void Util::spline_mat(float *x, float *y, int n,  float *xq, float *yq, int m) //PRB
00349 {
00350 
00351         float x0= x[0];
00352         float x1= x[1];
00353         float x2= x[2];
00354         float y0= y[0];
00355         float y1= y[1];
00356         float y2= y[2];
00357         float yp1 =  (y1-y0)/(x1-x0) +  (y2-y0)/(x2-x0) - (y2-y1)/(x2-x1)  ;
00358         float xn  = x[n];
00359         float xnm1= x[n-1];
00360         float xnm2= x[n-2];
00361         float yn  = y[n];
00362         float ynm1= y[n-1];
00363         float ynm2= y[n-2];
00364         float ypn=  (yn-ynm1)/(xn-xnm1) +  (yn-ynm2)/(xn-xnm2) - (ynm1-ynm2)/(xnm1-xnm2) ;
00365         float *y2d = new float[n];
00366         Util::spline(x,y,n,yp1,ypn,y2d);
00367         Util::splint(x,y,y2d,n,xq,yq,m); //PRB
00368         delete [] y2d;
00369         return;
00370 }
00371 
00372 
00373 void Util::spline(float *x, float *y, int n, float yp1, float ypn, float *y2) //PRB
00374 {
00375         int i,k;
00376         float p, qn, sig, un, *u;
00377         u = new float[n-1];
00378 
00379         if (yp1 > .99e30){
00380                 y2[0]=u[0]=0.0;
00381         } else {
00382                 y2[0]=-.5f;
00383                 u[0] =(3.0f/ (x[1] -x[0]))*( (y[1]-y[0])/(x[1]-x[0]) -yp1);
00384         }
00385 
00386         for (i=1; i < n-1; i++) {
00387                 sig= (x[i] - x[i-1])/(x[i+1] - x[i-1]);
00388                 p = sig*y2[i-1] + 2.0f;
00389                 y2[i]  = (sig-1.0f)/p;
00390                 u[i] = (y[i+1] - y[i] )/(x[i+1]-x[i] ) -  (y[i] - y[i-1] )/(x[i] -x[i-1]);
00391                 u[i] = (6.0f*u[i]/ (x[i+1]-x[i-1]) - sig*u[i-1])/p;
00392         }
00393 
00394         if (ypn>.99e30){
00395                 qn=0; un=0;
00396         } else {
00397                 qn= .5f;
00398                 un= (3.0f/(x[n-1] -x[n-2])) * (ypn -  (y[n-1]-y[n-2])/(x[n-1]-x[n-2]));
00399         }
00400         y2[n-1]= (un - qn*u[n-2])/(qn*y2[n-2]+1.0f);
00401         for (k=n-2; k>=0; k--){
00402                 y2[k]=y2[k]*y2[k+1]+u[k];
00403         }
00404         delete [] u;
00405 }
00406 
00407 
00408 void Util::splint( float *xa, float *ya, float *y2a, int n,  float *xq, float *yq, int m) //PRB
00409 {
00410         int klo, khi, k;
00411         float h, b, a;
00412 
00413 //      klo=0; // can try to put here
00414         for (int j=0; j<m;j++){
00415                 klo=0;
00416                 khi=n-1;
00417                 while (khi-klo >1) {
00418                         k=(khi+klo) >>1;
00419                         if  (xa[k]>xq[j]){ khi=k;}
00420                         else { klo=k;}
00421                 }
00422                 h=xa[khi]- xa[klo];
00423                 if (h==0.0) printf("Bad XA input to routine SPLINT \n");
00424                 a =(xa[khi]-xq[j])/h;
00425                 b=(xq[j]-xa[klo])/h;
00426                 yq[j]=a*ya[klo] + b*ya[khi]
00427                         + ((a*a*a-a)*y2a[klo]
00428                              +(b*b*b-b)*y2a[khi]) *(h*h)/6.0f;
00429         }
00430 //      printf("h=%f, a = %f, b=%f, ya[klo]=%f, ya[khi]=%f , yq=%f\n",h, a, b, ya[klo], ya[khi],yq[0]);
00431 }
00432 
00433 
00434 void Util::Radialize(int *PermMatTr, float *kValsSorted,   // PRB
00435                float *weightofkValsSorted, int Size, int *SizeReturned)
00436 {
00437         int iMax = (int) floor( (Size-1.0)/2 +.01);
00438         int CountMax = (iMax+2)*(iMax+1)/2;
00439         int Count=-1;
00440         float *kVals     = new float[CountMax];
00441         float *weightMat = new float[CountMax];
00442         int *PermMat     = new   int[CountMax];
00443         SizeReturned[0] = CountMax;
00444 
00445 //      printf("Aa \n");        fflush(stdout);
00446         for (int jkx=0; jkx< iMax+1; jkx++) {
00447                 for (int jky=0; jky< jkx+1; jky++) {
00448                         Count++;
00449                         kVals[Count] = sqrtf((float) (jkx*jkx +jky*jky));
00450                         weightMat[Count]=  1.0;
00451                         if (jkx!=0)  { weightMat[Count] *=2;}
00452                         if (jky!=0)  { weightMat[Count] *=2;}
00453                         if (jkx!=jky){ weightMat[Count] *=2;}
00454                         PermMat[Count]=Count+1;
00455                 }
00456         }
00457 
00458         int lkVals = Count+1;
00459 //      printf("Cc \n");fflush(stdout);
00460 
00461         sort_mat(&kVals[0],&kVals[Count],
00462              &PermMat[0],  &PermMat[Count]);  //PermMat is
00463                                 //also returned as well as kValsSorted
00464         fflush(stdout);
00465 
00466         int newInd;
00467 
00468         for (int iP=0; iP < lkVals ; iP++ ) {
00469                 newInd =  PermMat[iP];
00470                 PermMatTr[newInd-1] = iP+1;
00471         }
00472 
00473 //      printf("Ee \n"); fflush(stdout);
00474 
00475         int CountA=-1;
00476         int CountB=-1;
00477 
00478         while (CountB< (CountMax-1)) {
00479                 CountA++;
00480                 CountB++;
00481 //              printf("CountA=%d ; CountB=%d \n", CountA,CountB);fflush(stdout);
00482                 kValsSorted[CountA] = kVals[CountB] ;
00483                 if (CountB<(CountMax-1) ) {
00484                         while (fabs(kVals[CountB] -kVals[CountB+1])<.0000001  ) {
00485                                 SizeReturned[0]--;
00486                                 for (int iP=0; iP < lkVals; iP++){
00487 //                                      printf("iP=%d \n", iP);fflush(stdout);
00488                                         if  (PermMatTr[iP]>CountA+1) {
00489                                                 PermMatTr[iP]--;
00490                                         }
00491                                 }
00492                                 CountB++;
00493                         }
00494                 }
00495         }
00496 
00497 
00498         for (int CountD=0; CountD < CountMax; CountD++) {
00499             newInd = PermMatTr[CountD];
00500             weightofkValsSorted[newInd-1] += weightMat[CountD];
00501         }
00502 
00503 }
00504 
00505 
00506 vector<float>
00507 Util::even_angles(float delta, float t1, float t2, float p1, float p2)
00508 {
00509         vector<float> angles;
00510         float psi = 0.0;
00511         if ((0.0 == t1)&&(0.0 == t2)||(t1 >= t2)) {
00512                 t1 = 0.0f;
00513                 t2 = 90.0f;
00514         }
00515         if ((0.0 == p1)&&(0.0 == p2)||(p1 >= p2)) {
00516                 p1 = 0.0f;
00517                 p2 = 359.9f;
00518         }
00519         bool skip = ((t1 < 90.0)&&(90.0 == t2)&&(0.0 == p1)&&(p2 > 180.0));
00520         for (float theta = t1; theta <= t2; theta += delta) {
00521                 float detphi;
00522                 int lt;
00523                 if ((0.0 == theta)||(180.0 == theta)) {
00524                         detphi = 360.0f;
00525                         lt = 1;
00526                 } else {
00527                         detphi = delta/sin(theta*static_cast<float>(dgr_to_rad));
00528                         lt = int((p2 - p1)/detphi)-1;
00529                         if (lt < 1) lt = 1;
00530                         detphi = (p2 - p1)/lt;
00531                 }
00532                 for (int i = 0; i < lt; i++) {
00533                         float phi = p1 + i*detphi;
00534                         if (skip&&(90.0 == theta)&&(phi > 180.0)) continue;
00535                         angles.push_back(phi);
00536                         angles.push_back(theta);
00537                         angles.push_back(psi);
00538                 }
00539         }
00540         return angles;
00541 }
00542 
00543 
00544 #define  fdata(i,j)      fdata[ i-1 + (j-1)*nxdata ]
00545 /*float Util::quadri(float xx, float yy, int nxdata, int nydata, float* fdata)
00546 {
00547 
00548 //  purpose: quadratic interpolation
00549 //
00550 //  parameters:       xx,yy treated as circularly closed.
00551 //                    fdata - image 1..nxdata, 1..nydata
00552 //
00553 //                    f3    fc       f0, f1, f2, f3 are the values
00554 //                     +             at the grid points.  x is the
00555 //                     + x           point at which the function
00556 //              f2++++f0++++f1       is to be estimated. (it need
00557 //                     +             not be in the first quadrant).
00558 //                     +             fc - the outer corner point
00559 //                    f4             nearest x.
00560 c
00561 //                                   f0 is the value of the fdata at
00562 //                                   fdata(i,j), it is the interior mesh
00563 //                                   point nearest  x.
00564 //                                   the coordinates of f0 are (x0,y0),
00565 //                                   the coordinates of f1 are (xb,y0),
00566 //                                   the coordinates of f2 are (xa,y0),
00567 //                                   the coordinates of f3 are (x0,yb),
00568 //                                   the coordinates of f4 are (x0,ya),
00569 //                                   the coordinates of fc are (xc,yc),
00570 c
00571 //                   o               hxa, hxb are the mesh spacings
00572 //                   +               in the x-direction to the left
00573 //                  hyb              and right of the center point.
00574 //                   +
00575 //            ++hxa++o++hxb++o       hyb, hya are the mesh spacings
00576 //                   +               in the y-direction.
00577 //                  hya
00578 //                   +               hxc equals either  hxb  or  hxa
00579 //                   o               depending on where the corner
00580 //                                   point is located.
00581 c
00582 //                                   construct the interpolant
00583 //                                   f = f0 + c1*(x-x0) +
00584 //                                       c2*(x-x0)*(x-x1) +
00585 //                                       c3*(y-y0) + c4*(y-y0)*(y-y1)
00586 //                                       + c5*(x-x0)*(y-y0)
00587 //
00588 //
00589 
00590     float x, y, dx0, dy0, f0, c1, c2, c3, c4, c5, dxb, dyb;
00591     float quadri;
00592     int   i, j, ip1, im1, jp1, jm1, ic, jc, hxc, hyc;
00593 
00594     x = xx;
00595     y = yy;
00596 
00597     // circular closure
00598         while ( x < 1.0 ) x += nxdata;
00599         while ( x >= (float)(nxdata+1) )  x -= nxdata;
00600         while ( y < 1.0 ) y += nydata;
00601         while ( y >= (float)(nydata+1) )  y -= nydata;
00602 
00603 
00604     i   = (int) x;
00605     j   = (int) y;
00606 
00607     dx0 = x - i;
00608     dy0 = y - j;
00609 
00610     ip1 = i + 1;
00611     im1 = i - 1;
00612     jp1 = j + 1;
00613     jm1 = j - 1;
00614 
00615     if (ip1 > nxdata) ip1 = ip1 - nxdata;
00616     if (im1 < 1)      im1 = im1 + nxdata;
00617     if (jp1 > nydata) jp1 = jp1 - nydata;
00618     if (jm1 < 1)      jm1 = jm1 + nydata;
00619 
00620     f0  = fdata(i,j);
00621     c1  = fdata(ip1,j) - f0;
00622     c2  = (c1 - f0 + fdata(im1,j)) * 0.5;
00623     c3  = fdata(i,jp1) - f0;
00624     c4  = (c3 - f0 + fdata(i,jm1)) * 0.5;
00625 
00626     dxb = dx0 - 1;
00627     dyb = dy0 - 1;
00628 
00629     // hxc & hyc are either 1 or -1
00630     if (dx0 >= 0) { hxc = 1; } else { hxc = -1; }
00631     if (dy0 >= 0) { hyc = 1; } else { hyc = -1; }
00632 
00633     ic  = i + hxc;
00634     jc  = j + hyc;
00635 
00636     if (ic > nxdata) { ic = ic - nxdata; }  else if (ic < 1) { ic = ic + nxdata; }
00637     if (jc > nydata) { jc = jc - nydata; } else if (jc < 1) { jc = jc + nydata; }
00638 
00639     c5  =  ( (fdata(ic,jc) - f0 - hxc * c1 - (hxc * (hxc - 1.0)) * c2
00640             - hyc * c3 - (hyc * (hyc - 1.0)) * c4) * (hxc * hyc));
00641 
00642     quadri = f0 + dx0 * (c1 + dxb * c2 + dy0 * c5) + dy0 * (c3 + dyb * c4);
00643 
00644     return quadri;
00645 }*/
00646 float Util::quadri(float xx, float yy, int nxdata, int nydata, float* fdata)
00647 {
00648 //  purpose: quadratic interpolation
00649 //  Optimized for speed, circular closer removed, checking of ranges removed
00650         float  x, y, dx0, dy0, f0, c1, c2, c3, c4, c5, dxb, dyb;
00651         float  quadri;
00652         int    i, j, ip1, im1, jp1, jm1, ic, jc, hxc, hyc;
00653 
00654         x = xx;
00655         y = yy;
00656 
00657         //     any xx and yy
00658         while ( x < 1.0 )                 x += nxdata;
00659         while ( x >= (float)(nxdata+1) )  x -= nxdata;
00660         while ( y < 1.0 )                 y += nydata;
00661         while ( y >= (float)(nydata+1) )  y -= nydata;
00662 
00663         i   = (int) x;
00664         j   = (int) y;
00665 
00666         dx0 = x - i;
00667         dy0 = y - j;
00668 
00669         ip1 = i + 1;
00670         im1 = i - 1;
00671         jp1 = j + 1;
00672         jm1 = j - 1;
00673 
00674         if (ip1 > nxdata) ip1 -= nxdata;
00675         if (im1 < 1)      im1 += nxdata;
00676         if (jp1 > nydata) jp1 -= nydata;
00677         if (jm1 < 1)      jm1 += nydata;
00678 
00679         f0  = fdata(i,j);
00680         c1  = fdata(ip1,j) - f0;
00681         c2  = (c1 - f0 + fdata(im1,j)) * 0.5f;
00682         c3  = fdata(i,jp1) - f0;
00683         c4  = (c3 - f0 + fdata(i,jm1)) * 0.5f;
00684 
00685         dxb = dx0 - 1;
00686         dyb = dy0 - 1;
00687 
00688         // hxc & hyc are either 1 or -1
00689         if (dx0 >= 0) hxc = 1; else hxc = -1;
00690         if (dy0 >= 0) hyc = 1; else hyc = -1;
00691 
00692         ic  = i + hxc;
00693         jc  = j + hyc;
00694 
00695         if (ic > nxdata) ic -= nxdata;  else if (ic < 1) ic += nxdata;
00696         if (jc > nydata) jc -= nydata;  else if (jc < 1) jc += nydata;
00697 
00698         c5  =  ( (fdata(ic,jc) - f0 - hxc * c1 - (hxc * (hxc - 1.0f)) * c2
00699                 - hyc * c3 - (hyc * (hyc - 1.0f)) * c4) * (hxc * hyc));
00700 
00701 
00702         quadri = f0 + dx0 * (c1 + dxb * c2 + dy0 * c5) + dy0 * (c3 + dyb * c4);
00703 
00704         return quadri;
00705 }
00706 
00707 #undef fdata
00708 
00709 #define  fdata(i,j)      fdata[ i-1 + (j-1)*nxdata ]
00710 float Util::quadri_background(float xx, float yy, int nxdata, int nydata, float* fdata, int xnew, int ynew)
00711 {
00712 //  purpose: quadratic interpolation
00713 //  Optimized for speed, circular closer removed, checking of ranges removed
00714         float  x, y, dx0, dy0, f0, c1, c2, c3, c4, c5, dxb, dyb;
00715         float  quadri;
00716         int    i, j, ip1, im1, jp1, jm1, ic, jc, hxc, hyc;
00717 
00718         x = xx;
00719         y = yy;
00720 
00721         // wrap around is not done circulantly; if (x,y) is not in the image, then x = xnew and y = ynew
00722         if ( (x < 1.0) || ( x >= (float)(nxdata+1) ) || ( y < 1.0 ) || ( y >= (float)(nydata+1) )){
00723               x = xnew;
00724                   y = ynew;
00725      }
00726             
00727 
00728         i   = (int) x;
00729         j   = (int) y;
00730 
00731         dx0 = x - i;
00732         dy0 = y - j;
00733 
00734         ip1 = i + 1;
00735         im1 = i - 1;
00736         jp1 = j + 1;
00737         jm1 = j - 1;
00738 
00739         if (ip1 > nxdata) ip1 -= nxdata;
00740         if (im1 < 1)      im1 += nxdata;
00741         if (jp1 > nydata) jp1 -= nydata;
00742         if (jm1 < 1)      jm1 += nydata;
00743 
00744         f0  = fdata(i,j);
00745         c1  = fdata(ip1,j) - f0;
00746         c2  = (c1 - f0 + fdata(im1,j)) * 0.5f;
00747         c3  = fdata(i,jp1) - f0;
00748         c4  = (c3 - f0 + fdata(i,jm1)) * 0.5f;
00749 
00750         dxb = dx0 - 1;
00751         dyb = dy0 - 1;
00752 
00753         // hxc & hyc are either 1 or -1
00754         if (dx0 >= 0) hxc = 1; else hxc = -1;
00755         if (dy0 >= 0) hyc = 1; else hyc = -1;
00756 
00757         ic  = i + hxc;
00758         jc  = j + hyc;
00759 
00760         if (ic > nxdata) ic -= nxdata;  else if (ic < 1) ic += nxdata;
00761         if (jc > nydata) jc -= nydata;  else if (jc < 1) jc += nydata;
00762 
00763         c5  =  ( (fdata(ic,jc) - f0 - hxc * c1 - (hxc * (hxc - 1.0f)) * c2
00764                 - hyc * c3 - (hyc * (hyc - 1.0f)) * c4) * (hxc * hyc));
00765 
00766 
00767         quadri = f0 + dx0 * (c1 + dxb * c2 + dy0 * c5) + dy0 * (c3 + dyb * c4);
00768 
00769         return quadri;
00770 }
00771 
00772 #undef fdata
00773 
00774 
00775 float  Util::get_pixel_conv_new(int nx, int ny, int nz, float delx, float dely, float delz, float* data, Util::KaiserBessel& kb) {
00776 // Here counting is in C style, so coordinates of the pixel delx should be [0-nx-1]
00777 
00778 /* Commented by Zhengfan Yang on 04/20/07
00779 This function is written to replace get_pixel_conv(), which is too slow to use in practice.
00780 I made the following changes to get_pixel_conv():
00781 1. Use the same data passing scheme as quadri() and move the function from emdata_sparx.cpp to util_sparx.cpp
00782 2. Reduce usage of i0win_tab (from 98 calls to 14 calls in 2D case, from 1029 calls to 21 calls in 3D case!)
00783 3. Unfold the 'for' loop
00784 4. Reduce the usage of multiplications through some bracketing (from 98 times to 57 times in 2D case, from 1029 times to 400 times in 3D case)
00785 
00786 The shortcoming of this routine is that it only works for window size N=7. In case you want to use other window
00787 size, say N=5, you can easily modify it by referring my code.
00788 */
00789         int K = kb.get_window_size();
00790         int kbmin = -K/2;
00791         int kbmax = -kbmin;
00792         int kbc = kbmax+1;
00793 
00794         float pixel =0.0f;
00795         float w=0.0f;
00796 
00797         delx = restrict1(delx, nx);
00798         int inxold = int(round(delx));
00799         if ( ny < 2 ) {  //1D
00800                 float tablex1 = kb.i0win_tab(delx-inxold+3);
00801                 float tablex2 = kb.i0win_tab(delx-inxold+2);
00802                 float tablex3 = kb.i0win_tab(delx-inxold+1);
00803                 float tablex4 = kb.i0win_tab(delx-inxold);
00804                 float tablex5 = kb.i0win_tab(delx-inxold-1);
00805                 float tablex6 = kb.i0win_tab(delx-inxold-2);
00806                 float tablex7 = kb.i0win_tab(delx-inxold-3);
00807 
00808                 int x1, x2, x3, x4, x5, x6, x7;
00809 
00810                 if ( inxold <= kbc || inxold >=nx-kbc-2 )  {
00811                         x1 = (inxold-3+nx)%nx;
00812                         x2 = (inxold-2+nx)%nx;
00813                         x3 = (inxold-1+nx)%nx;
00814                         x4 = (inxold  +nx)%nx;
00815                         x5 = (inxold+1+nx)%nx;
00816                         x6 = (inxold+2+nx)%nx;
00817                         x7 = (inxold+3+nx)%nx;
00818                 } else {
00819                         x1 = inxold-3;
00820                         x2 = inxold-2;
00821                         x3 = inxold-1;
00822                         x4 = inxold;
00823                         x5 = inxold+1;
00824                         x6 = inxold+2;
00825                         x7 = inxold+3;
00826                 }
00827 
00828                 pixel = data[x1]*tablex1 + data[x2]*tablex2 + data[x3]*tablex3 +
00829                         data[x4]*tablex4 + data[x5]*tablex5 + data[x6]*tablex6 +
00830                         data[x7]*tablex7 ;
00831 
00832                 w = tablex1+tablex2+tablex3+tablex4+tablex5+tablex6+tablex7;
00833         } else if ( nz < 2 ) {  // 2D
00834                 dely = restrict1(dely, ny);
00835                 int inyold = int(round(dely));
00836                 float tablex1 = kb.i0win_tab(delx-inxold+3);
00837                 float tablex2 = kb.i0win_tab(delx-inxold+2);
00838                 float tablex3 = kb.i0win_tab(delx-inxold+1);
00839                 float tablex4 = kb.i0win_tab(delx-inxold);
00840                 float tablex5 = kb.i0win_tab(delx-inxold-1);
00841                 float tablex6 = kb.i0win_tab(delx-inxold-2);
00842                 float tablex7 = kb.i0win_tab(delx-inxold-3);
00843 
00844                 float tabley1 = kb.i0win_tab(dely-inyold+3);
00845                 float tabley2 = kb.i0win_tab(dely-inyold+2);
00846                 float tabley3 = kb.i0win_tab(dely-inyold+1);
00847                 float tabley4 = kb.i0win_tab(dely-inyold);
00848                 float tabley5 = kb.i0win_tab(dely-inyold-1);
00849                 float tabley6 = kb.i0win_tab(dely-inyold-2);
00850                 float tabley7 = kb.i0win_tab(dely-inyold-3);
00851 
00852                 int x1, x2, x3, x4, x5, x6, x7, y1, y2, y3, y4, y5, y6, y7;
00853 
00854                 if ( inxold <= kbc || inxold >=nx-kbc-2 || inyold <= kbc || inyold >=ny-kbc-2 )  {
00855                         x1 = (inxold-3+nx)%nx;
00856                         x2 = (inxold-2+nx)%nx;
00857                         x3 = (inxold-1+nx)%nx;
00858                         x4 = (inxold  +nx)%nx;
00859                         x5 = (inxold+1+nx)%nx;
00860                         x6 = (inxold+2+nx)%nx;
00861                         x7 = (inxold+3+nx)%nx;
00862 
00863                         y1 = ((inyold-3+ny)%ny)*nx;
00864                         y2 = ((inyold-2+ny)%ny)*nx;
00865                         y3 = ((inyold-1+ny)%ny)*nx;
00866                         y4 = ((inyold  +ny)%ny)*nx;
00867                         y5 = ((inyold+1+ny)%ny)*nx;
00868                         y6 = ((inyold+2+ny)%ny)*nx;
00869                         y7 = ((inyold+3+ny)%ny)*nx;
00870                 } else {
00871                         x1 = inxold-3;
00872                         x2 = inxold-2;
00873                         x3 = inxold-1;
00874                         x4 = inxold;
00875                         x5 = inxold+1;
00876                         x6 = inxold+2;
00877                         x7 = inxold+3;
00878 
00879                         y1 = (inyold-3)*nx;
00880                         y2 = (inyold-2)*nx;
00881                         y3 = (inyold-1)*nx;
00882                         y4 = inyold*nx;
00883                         y5 = (inyold+1)*nx;
00884                         y6 = (inyold+2)*nx;
00885                         y7 = (inyold+3)*nx;
00886                 }
00887 
00888                 pixel    = ( data[x1+y1]*tablex1 + data[x2+y1]*tablex2 + data[x3+y1]*tablex3 +
00889                              data[x4+y1]*tablex4 + data[x5+y1]*tablex5 + data[x6+y1]*tablex6 +
00890                              data[x7+y1]*tablex7 ) * tabley1 +
00891                            ( data[x1+y2]*tablex1 + data[x2+y2]*tablex2 + data[x3+y2]*tablex3 +
00892                              data[x4+y2]*tablex4 + data[x5+y2]*tablex5 + data[x6+y2]*tablex6 +
00893                              data[x7+y2]*tablex7 ) * tabley2 +
00894                            ( data[x1+y3]*tablex1 + data[x2+y3]*tablex2 + data[x3+y3]*tablex3 +
00895                              data[x4+y3]*tablex4 + data[x5+y3]*tablex5 + data[x6+y3]*tablex6 +
00896                              data[x7+y3]*tablex7 ) * tabley3 +
00897                            ( data[x1+y4]*tablex1 + data[x2+y4]*tablex2 + data[x3+y4]*tablex3 +
00898                              data[x4+y4]*tablex4 + data[x5+y4]*tablex5 + data[x6+y4]*tablex6 +
00899                              data[x7+y4]*tablex7 ) * tabley4 +
00900                            ( data[x1+y5]*tablex1 + data[x2+y5]*tablex2 + data[x3+y5]*tablex3 +
00901                              data[x4+y5]*tablex4 + data[x5+y5]*tablex5 + data[x6+y5]*tablex6 +
00902                              data[x7+y5]*tablex7 ) * tabley5 +
00903                            ( data[x1+y6]*tablex1 + data[x2+y6]*tablex2 + data[x3+y6]*tablex3 +
00904                              data[x4+y6]*tablex4 + data[x5+y6]*tablex5 + data[x6+y6]*tablex6 +
00905                              data[x7+y6]*tablex7 ) * tabley6 +
00906                            ( data[x1+y7]*tablex1 + data[x2+y7]*tablex2 + data[x3+y7]*tablex3 +
00907                              data[x4+y7]*tablex4 + data[x5+y7]*tablex5 + data[x6+y7]*tablex6 +
00908                              data[x7+y7]*tablex7 ) * tabley7;
00909 
00910                 w = (tablex1+tablex2+tablex3+tablex4+tablex5+tablex6+tablex7) *
00911                     (tabley1+tabley2+tabley3+tabley4+tabley5+tabley6+tabley7);
00912         } else {  //  3D
00913                 dely = restrict1(dely, ny);
00914                 int inyold = int(Util::round(dely));
00915                 delz = restrict1(delz, nz);
00916                 int inzold = int(Util::round(delz));
00917 
00918                 float tablex1 = kb.i0win_tab(delx-inxold+3);
00919                 float tablex2 = kb.i0win_tab(delx-inxold+2);
00920                 float tablex3 = kb.i0win_tab(delx-inxold+1);
00921                 float tablex4 = kb.i0win_tab(delx-inxold);
00922                 float tablex5 = kb.i0win_tab(delx-inxold-1);
00923                 float tablex6 = kb.i0win_tab(delx-inxold-2);
00924                 float tablex7 = kb.i0win_tab(delx-inxold-3);
00925 
00926                 float tabley1 = kb.i0win_tab(dely-inyold+3);
00927                 float tabley2 = kb.i0win_tab(dely-inyold+2);
00928                 float tabley3 = kb.i0win_tab(dely-inyold+1);
00929                 float tabley4 = kb.i0win_tab(dely-inyold);
00930                 float tabley5 = kb.i0win_tab(dely-inyold-1);
00931                 float tabley6 = kb.i0win_tab(dely-inyold-2);
00932                 float tabley7 = kb.i0win_tab(dely-inyold-3);
00933 
00934                 float tablez1 = kb.i0win_tab(delz-inzold+3);
00935                 float tablez2 = kb.i0win_tab(delz-inzold+2);
00936                 float tablez3 = kb.i0win_tab(delz-inzold+1);
00937                 float tablez4 = kb.i0win_tab(delz-inzold);
00938                 float tablez5 = kb.i0win_tab(delz-inzold-1);
00939                 float tablez6 = kb.i0win_tab(delz-inzold-2);
00940                 float tablez7 = kb.i0win_tab(delz-inzold-3);
00941 
00942                 int x1, x2, x3, x4, x5, x6, x7, y1, y2, y3, y4, y5, y6, y7, z1, z2, z3, z4, z5, z6, z7;
00943 
00944                 if ( inxold <= kbc || inxold >=nx-kbc-2 || inyold <= kbc || inyold >=ny-kbc-2 || inzold <= kbc || inzold >= nz-kbc-2 )  {
00945                         x1 = (inxold-3+nx)%nx;
00946                         x2 = (inxold-2+nx)%nx;
00947                         x3 = (inxold-1+nx)%nx;
00948                         x4 = (inxold  +nx)%nx;
00949                         x5 = (inxold+1+nx)%nx;
00950                         x6 = (inxold+2+nx)%nx;
00951                         x7 = (inxold+3+nx)%nx;
00952 
00953                         y1 = ((inyold-3+ny)%ny)*nx;
00954                         y2 = ((inyold-2+ny)%ny)*nx;
00955                         y3 = ((inyold-1+ny)%ny)*nx;
00956                         y4 = ((inyold  +ny)%ny)*nx;
00957                         y5 = ((inyold+1+ny)%ny)*nx;
00958                         y6 = ((inyold+2+ny)%ny)*nx;
00959                         y7 = ((inyold+3+ny)%ny)*nx;
00960 
00961                         z1 = ((inzold-3+nz)%nz)*nx*ny;
00962                         z2 = ((inzold-2+nz)%nz)*nx*ny;
00963                         z3 = ((inzold-1+nz)%nz)*nx*ny;
00964                         z4 = ((inzold  +nz)%nz)*nx*ny;
00965                         z5 = ((inzold+1+nz)%nz)*nx*ny;
00966                         z6 = ((inzold+2+nz)%nz)*nx*ny;
00967                         z7 = ((inzold+3+nz)%nz)*nx*ny;
00968                 } else {
00969                         x1 = inxold-3;
00970                         x2 = inxold-2;
00971                         x3 = inxold-1;
00972                         x4 = inxold;
00973                         x5 = inxold+1;
00974                         x6 = inxold+2;
00975                         x7 = inxold+3;
00976 
00977                         y1 = (inyold-3)*nx;
00978                         y2 = (inyold-2)*nx;
00979                         y3 = (inyold-1)*nx;
00980                         y4 = inyold*nx;
00981                         y5 = (inyold+1)*nx;
00982                         y6 = (inyold+2)*nx;
00983                         y7 = (inyold+3)*nx;
00984 
00985                         z1 = (inzold-3)*nx*ny;
00986                         z2 = (inzold-2)*nx*ny;
00987                         z3 = (inzold-1)*nx*ny;
00988                         z4 = inzold*nx*ny;
00989                         z5 = (inzold+1)*nx*ny;
00990                         z6 = (inzold+2)*nx*ny;
00991                         z7 = (inzold+3)*nx*ny;
00992                 }
00993 
00994                 pixel  = ( ( data[x1+y1+z1]*tablex1 + data[x2+y1+z1]*tablex2 + data[x3+y1+z1]*tablex3 +
00995                              data[x4+y1+z1]*tablex4 + data[x5+y1+z1]*tablex5 + data[x6+y1+z1]*tablex6 +
00996                              data[x7+y1+z1]*tablex7 ) * tabley1 +
00997                            ( data[x1+y2+z1]*tablex1 + data[x2+y2+z1]*tablex2 + data[x3+y2+z1]*tablex3 +
00998                              data[x4+y2+z1]*tablex4 + data[x5+y2+z1]*tablex5 + data[x6+y2+z1]*tablex6 +
00999                              data[x7+y2+z1]*tablex7 ) * tabley2 +
01000                            ( data[x1+y3+z1]*tablex1 + data[x2+y3+z1]*tablex2 + data[x3+y3+z1]*tablex3 +
01001                              data[x4+y3+z1]*tablex4 + data[x5+y3+z1]*tablex5 + data[x6+y3+z1]*tablex6 +
01002                              data[x7+y3+z1]*tablex7 ) * tabley3 +
01003                            ( data[x1+y4+z1]*tablex1 + data[x2+y4+z1]*tablex2 + data[x3+y4+z1]*tablex3 +
01004                              data[x4+y4+z1]*tablex4 + data[x5+y4+z1]*tablex5 + data[x6+y4+z1]*tablex6 +
01005                              data[x7+y4+z1]*tablex7 ) * tabley4 +
01006                            ( data[x1+y5+z1]*tablex1 + data[x2+y5+z1]*tablex2 + data[x3+y5+z1]*tablex3 +
01007                              data[x4+y5+z1]*tablex4 + data[x5+y5+z1]*tablex5 + data[x6+y5+z1]*tablex6 +
01008                              data[x7+y5+z1]*tablex7 ) * tabley5 +
01009                            ( data[x1+y6+z1]*tablex1 + data[x2+y6+z1]*tablex2 + data[x3+y6+z1]*tablex3 +
01010                              data[x4+y6+z1]*tablex4 + data[x5+y6+z1]*tablex5 + data[x6+y6+z1]*tablex6 +
01011                              data[x7+y6+z1]*tablex7 ) * tabley6 +
01012                            ( data[x1+y7+z1]*tablex1 + data[x2+y7+z1]*tablex2 + data[x3+y7+z1]*tablex3 +
01013                              data[x4+y7+z1]*tablex4 + data[x5+y7+z1]*tablex5 + data[x6+y7+z1]*tablex6 +
01014                              data[x7+y7+z1]*tablex7 ) * tabley7 ) *tablez1 +
01015                          ( ( data[x1+y1+z2]*tablex1 + data[x2+y1+z2]*tablex2 + data[x3+y1+z2]*tablex3 +
01016                              data[x4+y1+z2]*tablex4 + data[x5+y1+z2]*tablex5 + data[x6+y1+z2]*tablex6 +
01017                              data[x7+y1+z2]*tablex7 ) * tabley1 +
01018                            ( data[x1+y2+z2]*tablex1 + data[x2+y2+z2]*tablex2 + data[x3+y2+z2]*tablex3 +
01019                              data[x4+y2+z2]*tablex4 + data[x5+y2+z2]*tablex5 + data[x6+y2+z2]*tablex6 +
01020                              data[x7+y2+z2]*tablex7 ) * tabley2 +
01021                            ( data[x1+y3+z2]*tablex1 + data[x2+y3+z2]*tablex2 + data[x3+y3+z2]*tablex3 +
01022                              data[x4+y3+z2]*tablex4 + data[x5+y3+z2]*tablex5 + data[x6+y3+z2]*tablex6 +
01023                              data[x7+y3+z2]*tablex7 ) * tabley3 +
01024                            ( data[x1+y4+z2]*tablex1 + data[x2+y4+z2]*tablex2 + data[x3+y4+z2]*tablex3 +
01025                              data[x4+y4+z2]*tablex4 + data[x5+y4+z2]*tablex5 + data[x6+y4+z2]*tablex6 +
01026                              data[x7+y4+z2]*tablex7 ) * tabley4 +
01027                            ( data[x1+y5+z2]*tablex1 + data[x2+y5+z2]*tablex2 + data[x3+y5+z2]*tablex3 +
01028                              data[x4+y5+z2]*tablex4 + data[x5+y5+z2]*tablex5 + data[x6+y5+z2]*tablex6 +
01029                              data[x7+y5+z2]*tablex7 ) * tabley5 +
01030                            ( data[x1+y6+z2]*tablex1 + data[x2+y6+z2]*tablex2 + data[x3+y6+z2]*tablex3 +
01031                              data[x4+y6+z2]*tablex4 + data[x5+y6+z2]*tablex5 + data[x6+y6+z2]*tablex6 +
01032                              data[x7+y6+z2]*tablex7 ) * tabley6 +
01033                            ( data[x1+y7+z2]*tablex1 + data[x2+y7+z2]*tablex2 + data[x3+y7+z2]*tablex3 +
01034                              data[x4+y7+z2]*tablex4 + data[x5+y7+z2]*tablex5 + data[x6+y7+z2]*tablex6 +
01035                              data[x7+y7+z2]*tablex7 ) * tabley7 ) *tablez2 +
01036                          ( ( data[x1+y1+z3]*tablex1 + data[x2+y1+z3]*tablex2 + data[x3+y1+z3]*tablex3 +
01037                              data[x4+y1+z3]*tablex4 + data[x5+y1+z3]*tablex5 + data[x6+y1+z3]*tablex6 +
01038                              data[x7+y1+z3]*tablex7 ) * tabley1 +
01039                            ( data[x1+y2+z3]*tablex1 + data[x2+y2+z3]*tablex2 + data[x3+y2+z3]*tablex3 +
01040                              data[x4+y2+z3]*tablex4 + data[x5+y2+z3]*tablex5 + data[x6+y2+z3]*tablex6 +
01041                              data[x7+y2+z3]*tablex7 ) * tabley2 +
01042                            ( data[x1+y3+z3]*tablex1 + data[x2+y3+z3]*tablex2 + data[x3+y3+z3]*tablex3 +
01043                              data[x4+y3+z3]*tablex4 + data[x5+y3+z3]*tablex5 + data[x6+y3+z3]*tablex6 +
01044                              data[x7+y3+z3]*tablex7 ) * tabley3 +
01045                            ( data[x1+y4+z3]*tablex1 + data[x2+y4+z3]*tablex2 + data[x3+y4+z3]*tablex3 +
01046                              data[x4+y4+z3]*tablex4 + data[x5+y4+z3]*tablex5 + data[x6+y4+z3]*tablex6 +
01047                              data[x7+y4+z3]*tablex7 ) * tabley4 +
01048                            ( data[x1+y5+z3]*tablex1 + data[x2+y5+z3]*tablex2 + data[x3+y5+z3]*tablex3 +
01049                              data[x4+y5+z3]*tablex4 + data[x5+y5+z3]*tablex5 + data[x6+y5+z3]*tablex6 +
01050                              data[x7+y5+z3]*tablex7 ) * tabley5 +
01051                            ( data[x1+y6+z3]*tablex1 + data[x2+y6+z3]*tablex2 + data[x3+y6+z3]*tablex3 +
01052                              data[x4+y6+z3]*tablex4 + data[x5+y6+z3]*tablex5 + data[x6+y6+z3]*tablex6 +
01053                              data[x7+y6+z3]*tablex7 ) * tabley6 +
01054                            ( data[x1+y7+z3]*tablex1 + data[x2+y7+z3]*tablex2 + data[x3+y7+z3]*tablex3 +
01055                              data[x4+y7+z3]*tablex4 + data[x5+y7+z3]*tablex5 + data[x6+y7+z3]*tablex6 +
01056                              data[x7+y7+z3]*tablex7 ) * tabley7 ) *tablez3 +
01057                          ( ( data[x1+y1+z4]*tablex1 + data[x2+y1+z4]*tablex2 + data[x3+y1+z4]*tablex3 +
01058                              data[x4+y1+z4]*tablex4 + data[x5+y1+z4]*tablex5 + data[x6+y1+z4]*tablex6 +
01059                              data[x7+y1+z4]*tablex7 ) * tabley1 +
01060                            ( data[x1+y2+z4]*tablex1 + data[x2+y2+z4]*tablex2 + data[x3+y2+z4]*tablex3 +
01061                              data[x4+y2+z4]*tablex4 + data[x5+y2+z4]*tablex5 + data[x6+y2+z4]*tablex6 +
01062                              data[x7+y2+z4]*tablex7 ) * tabley2 +
01063                            ( data[x1+y3+z4]*tablex1 + data[x2+y3+z4]*tablex2 + data[x3+y3+z4]*tablex3 +
01064                              data[x4+y3+z4]*tablex4 + data[x5+y3+z4]*tablex5 + data[x6+y3+z4]*tablex6 +
01065                              data[x7+y3+z4]*tablex7 ) * tabley3 +
01066                            ( data[x1+y4+z4]*tablex1 + data[x2+y4+z4]*tablex2 + data[x3+y4+z4]*tablex3 +
01067                              data[x4+y4+z4]*tablex4 + data[x5+y4+z4]*tablex5 + data[x6+y4+z4]*tablex6 +
01068                              data[x7+y4+z4]*tablex7 ) * tabley4 +
01069                            ( data[x1+y5+z4]*tablex1 + data[x2+y5+z4]*tablex2 + data[x3+y5+z4]*tablex3 +
01070                              data[x4+y5+z4]*tablex4 + data[x5+y5+z4]*tablex5 + data[x6+y5+z4]*tablex6 +
01071                              data[x7+y5+z4]*tablex7 ) * tabley5 +
01072                            ( data[x1+y6+z4]*tablex1 + data[x2+y6+z4]*tablex2 + data[x3+y6+z4]*tablex3 +
01073                              data[x4+y6+z4]*tablex4 + data[x5+y6+z4]*tablex5 + data[x6+y6+z4]*tablex6 +
01074                              data[x7+y6+z4]*tablex7 ) * tabley6 +
01075                            ( data[x1+y7+z4]*tablex1 + data[x2+y7+z4]*tablex2 + data[x3+y7+z4]*tablex3 +
01076                              data[x4+y7+z4]*tablex4 + data[x5+y7+z4]*tablex5 + data[x6+y7+z4]*tablex6 +
01077                              data[x7+y7+z4]*tablex7 ) * tabley7 ) *tablez4 +
01078                          ( ( data[x1+y1+z5]*tablex1 + data[x2+y1+z5]*tablex2 + data[x3+y1+z5]*tablex3 +
01079                              data[x4+y1+z5]*tablex4 + data[x5+y1+z5]*tablex5 + data[x6+y1+z5]*tablex6 +
01080                              data[x7+y1+z5]*tablex7 ) * tabley1 +
01081                            ( data[x1+y2+z5]*tablex1 + data[x2+y2+z5]*tablex2 + data[x3+y2+z5]*tablex3 +
01082                              data[x4+y2+z5]*tablex4 + data[x5+y2+z5]*tablex5 + data[x6+y2+z5]*tablex6 +
01083                              data[x7+y2+z5]*tablex7 ) * tabley2 +
01084                            ( data[x1+y3+z5]*tablex1 + data[x2+y3+z5]*tablex2 + data[x3+y3+z5]*tablex3 +
01085                              data[x4+y3+z5]*tablex4 + data[x5+y3+z5]*tablex5 + data[x6+y3+z5]*tablex6 +
01086                              data[x7+y3+z5]*tablex7 ) * tabley3 +
01087                            ( data[x1+y4+z5]*tablex1 + data[x2+y4+z5]*tablex2 + data[x3+y4+z5]*tablex3 +
01088                              data[x4+y4+z5]*tablex4 + data[x5+y4+z5]*tablex5 + data[x6+y4+z5]*tablex6 +
01089                              data[x7+y4+z5]*tablex7 ) * tabley4 +
01090                            ( data[x1+y5+z5]*tablex1 + data[x2+y5+z5]*tablex2 + data[x3+y5+z5]*tablex3 +
01091                              data[x4+y5+z5]*tablex4 + data[x5+y5+z5]*tablex5 + data[x6+y5+z5]*tablex6 +
01092                              data[x7+y5+z5]*tablex7 ) * tabley5 +
01093                            ( data[x1+y6+z5]*tablex1 + data[x2+y6+z5]*tablex2 + data[x3+y6+z5]*tablex3 +
01094                              data[x4+y6+z5]*tablex4 + data[x5+y6+z5]*tablex5 + data[x6+y6+z5]*tablex6 +
01095                              data[x7+y6+z5]*tablex7 ) * tabley6 +
01096                            ( data[x1+y7+z5]*tablex1 + data[x2+y7+z5]*tablex2 + data[x3+y7+z5]*tablex3 +
01097                              data[x4+y7+z5]*tablex4 + data[x5+y7+z5]*tablex5 + data[x6+y7+z5]*tablex6 +
01098                              data[x7+y7+z5]*tablex7 ) * tabley7 ) *tablez5 +
01099                          ( ( data[x1+y1+z6]*tablex1 + data[x2+y1+z6]*tablex2 + data[x3+y1+z6]*tablex3 +
01100                              data[x4+y1+z6]*tablex4 + data[x5+y1+z6]*tablex5 + data[x6+y1+z6]*tablex6 +
01101                              data[x7+y1+z6]*tablex7 ) * tabley1 +
01102                            ( data[x1+y2+z6]*tablex1 + data[x2+y2+z6]*tablex2 + data[x3+y2+z6]*tablex3 +
01103                              data[x4+y2+z6]*tablex4 + data[x5+y2+z6]*tablex5 + data[x6+y2+z6]*tablex6 +
01104                              data[x7+y2+z6]*tablex7 ) * tabley2 +
01105                            ( data[x1+y3+z6]*tablex1 + data[x2+y3+z6]*tablex2 + data[x3+y3+z6]*tablex3 +
01106                              data[x4+y3+z6]*tablex4 + data[x5+y3+z6]*tablex5 + data[x6+y3+z6]*tablex6 +
01107                              data[x7+y3+z6]*tablex7 ) * tabley3 +
01108                            ( data[x1+y4+z6]*tablex1 + data[x2+y4+z6]*tablex2 + data[x3+y4+z6]*tablex3 +
01109                              data[x4+y4+z6]*tablex4 + data[x5+y4+z6]*tablex5 + data[x6+y4+z6]*tablex6 +
01110                              data[x7+y4+z6]*tablex7 ) * tabley4 +
01111                            ( data[x1+y5+z6]*tablex1 + data[x2+y5+z6]*tablex2 + data[x3+y5+z6]*tablex3 +
01112                              data[x4+y5+z6]*tablex4 + data[x5+y5+z6]*tablex5 + data[x6+y5+z6]*tablex6 +
01113                              data[x7+y5+z6]*tablex7 ) * tabley5 +
01114                            ( data[x1+y6+z6]*tablex1 + data[x2+y6+z6]*tablex2 + data[x3+y6+z6]*tablex3 +
01115                              data[x4+y6+z6]*tablex4 + data[x5+y6+z6]*tablex5 + data[x6+y6+z6]*tablex6 +
01116                              data[x7+y6+z6]*tablex7 ) * tabley6 +
01117                            ( data[x1+y7+z6]*tablex1 + data[x2+y7+z6]*tablex2 + data[x3+y7+z6]*tablex3 +
01118                              data[x4+y7+z6]*tablex4 + data[x5+y7+z6]*tablex5 + data[x6+y7+z6]*tablex6 +
01119                              data[x7+y7+z6]*tablex7 ) * tabley7 ) *tablez6 +
01120                          ( ( data[x1+y1+z7]*tablex1 + data[x2+y1+z7]*tablex2 + data[x3+y1+z7]*tablex3 +
01121                              data[x4+y1+z7]*tablex4 + data[x5+y1+z7]*tablex5 + data[x6+y1+z7]*tablex6 +
01122                              data[x7+y1+z7]*tablex7 ) * tabley1 +
01123                            ( data[x1+y2+z7]*tablex1 + data[x2+y2+z7]*tablex2 + data[x3+y2+z7]*tablex3 +
01124                              data[x4+y2+z7]*tablex4 + data[x5+y2+z7]*tablex5 + data[x6+y2+z7]*tablex6 +
01125                              data[x7+y2+z7]*tablex7 ) * tabley2 +
01126                            ( data[x1+y3+z7]*tablex1 + data[x2+y3+z7]*tablex2 + data[x3+y3+z7]*tablex3 +
01127                              data[x4+y3+z7]*tablex4 + data[x5+y3+z7]*tablex5 + data[x6+y3+z7]*tablex6 +
01128                              data[x7+y3+z7]*tablex7 ) * tabley3 +
01129                            ( data[x1+y4+z7]*tablex1 + data[x2+y4+z7]*tablex2 + data[x3+y4+z7]*tablex3 +
01130                              data[x4+y4+z7]*tablex4 + data[x5+y4+z7]*tablex5 + data[x6+y4+z7]*tablex6 +
01131                              data[x7+y4+z7]*tablex7 ) * tabley4 +
01132                            ( data[x1+y5+z7]*tablex1 + data[x2+y5+z7]*tablex2 + data[x3+y5+z7]*tablex3 +
01133                              data[x4+y5+z7]*tablex4 + data[x5+y5+z7]*tablex5 + data[x6+y5+z7]*tablex6 +
01134                              data[x7+y5+z7]*tablex7 ) * tabley5 +
01135                            ( data[x1+y6+z7]*tablex1 + data[x2+y6+z7]*tablex2 + data[x3+y6+z7]*tablex3 +
01136                              data[x4+y6+z7]*tablex4 + data[x5+y6+z7]*tablex5 + data[x6+y6+z7]*tablex6 +
01137                              data[x7+y6+z7]*tablex7 ) * tabley6 +
01138                            ( data[x1+y7+z7]*tablex1 + data[x2+y7+z7]*tablex2 + data[x3+y7+z7]*tablex3 +
01139                              data[x4+y7+z7]*tablex4 + data[x5+y7+z7]*tablex5 + data[x6+y7+z7]*tablex6 +
01140                              data[x7+y7+z7]*tablex7 ) * tabley7 ) *tablez7;
01141 
01142                 w = (tablex1+tablex2+tablex3+tablex4+tablex5+tablex6+tablex7) *
01143                     (tabley1+tabley2+tabley3+tabley4+tabley5+tabley6+tabley7) *
01144                     (tablez1+tablez2+tablez3+tablez4+tablez5+tablez6+tablez7);
01145         }
01146         return pixel/w;
01147 }
01148 
01149 float  Util::get_pixel_conv_new_background(int nx, int ny, int nz, float delx, float dely, float delz, float* data, Util::KaiserBessel& kb, int xnew, int ynew) {
01150 // Here counting is in C style, so coordinates of the pixel delx should be [0-nx-1]
01151 
01152 /* Commented by Zhengfan Yang on 04/20/07
01153 This function is written to replace get_pixel_conv(), which is too slow to use in practice.
01154 I made the following changes to get_pixel_conv():
01155 1. Use the same data passing scheme as quadri() and move the function from emdata_sparx.cpp to util_sparx.cpp
01156 2. Reduce usage of i0win_tab (from 98 calls to 14 calls in 2D case, from 1029 calls to 21 calls in 3D case!)
01157 3. Unfold the 'for' loop
01158 4. Reduce the usage of multiplications through some bracketing (from 98 times to 57 times in 2D case, from 1029 times to 400 times in 3D case)
01159 
01160 The shortcoming of this routine is that it only works for window size N=7. In case you want to use other window
01161 size, say N=5, you can easily modify it by referring my code.
01162 */
01163         int K = kb.get_window_size();
01164         int kbmin = -K/2;
01165         int kbmax = -kbmin;
01166         int kbc = kbmax+1;
01167 
01168         float pixel =0.0f;
01169         float w=0.0f;
01170 
01171     float argdelx = delx; // adding this for 2D case where the wrap around is not done circulantly using restrict1.
01172         delx = restrict1(delx, nx);
01173         int inxold = int(round(delx));
01174         if ( ny < 2 ) {  //1D
01175                 float tablex1 = kb.i0win_tab(delx-inxold+3);
01176                 float tablex2 = kb.i0win_tab(delx-inxold+2);
01177                 float tablex3 = kb.i0win_tab(delx-inxold+1);
01178                 float tablex4 = kb.i0win_tab(delx-inxold);
01179                 float tablex5 = kb.i0win_tab(delx-inxold-1);
01180                 float tablex6 = kb.i0win_tab(delx-inxold-2);
01181                 float tablex7 = kb.i0win_tab(delx-inxold-3);
01182 
01183                 int x1, x2, x3, x4, x5, x6, x7;
01184 
01185                 if ( inxold <= kbc || inxold >=nx-kbc-2 )  {
01186                         x1 = (inxold-3+nx)%nx;
01187                         x2 = (inxold-2+nx)%nx;
01188                         x3 = (inxold-1+nx)%nx;
01189                         x4 = (inxold  +nx)%nx;
01190                         x5 = (inxold+1+nx)%nx;
01191                         x6 = (inxold+2+nx)%nx;
01192                         x7 = (inxold+3+nx)%nx;
01193                 } else {
01194                         x1 = inxold-3;
01195                         x2 = inxold-2;
01196                         x3 = inxold-1;
01197                         x4 = inxold;
01198                         x5 = inxold+1;
01199                         x6 = inxold+2;
01200                         x7 = inxold+3;
01201                 }
01202 
01203                 pixel = data[x1]*tablex1 + data[x2]*tablex2 + data[x3]*tablex3 +
01204                         data[x4]*tablex4 + data[x5]*tablex5 + data[x6]*tablex6 +
01205                         data[x7]*tablex7 ;
01206 
01207                 w = tablex1+tablex2+tablex3+tablex4+tablex5+tablex6+tablex7;
01208         } else if ( nz < 2 ) {  // 2D
01209                 
01210                 delx = argdelx;
01211                 // the wrap around is not done circulantly for 2D case; if (argdelx, argdely) is not in the image, then make them (xnew, ynew) which is definitely in the image
01212                 if ((delx < 0.0f) || (delx >= (float) (nx)) || (dely < 0.0f) || (dely >= (float) (ny)) ){
01213                 delx = (float)xnew*2.0;
01214                 dely = (float)ynew*2.0;
01215                 }
01216                 
01217                 int inxold = int(round(delx));
01218                 int inyold = int(round(dely));
01219                 
01220                 float tablex1 = kb.i0win_tab(delx-inxold+3);
01221                 float tablex2 = kb.i0win_tab(delx-inxold+2);
01222                 float tablex3 = kb.i0win_tab(delx-inxold+1);
01223                 float tablex4 = kb.i0win_tab(delx-inxold);
01224                 float tablex5 = kb.i0win_tab(delx-inxold-1);
01225                 float tablex6 = kb.i0win_tab(delx-inxold-2);
01226                 float tablex7 = kb.i0win_tab(delx-inxold-3);
01227 
01228                 float tabley1 = kb.i0win_tab(dely-inyold+3);
01229                 float tabley2 = kb.i0win_tab(dely-inyold+2);
01230                 float tabley3 = kb.i0win_tab(dely-inyold+1);
01231                 float tabley4 = kb.i0win_tab(dely-inyold);
01232                 float tabley5 = kb.i0win_tab(dely-inyold-1);
01233                 float tabley6 = kb.i0win_tab(dely-inyold-2);
01234                 float tabley7 = kb.i0win_tab(dely-inyold-3);
01235 
01236                 int x1, x2, x3, x4, x5, x6, x7, y1, y2, y3, y4, y5, y6, y7;
01237 
01238                 if ( inxold <= kbc || inxold >=nx-kbc-2 || inyold <= kbc || inyold >=ny-kbc-2 )  {
01239                         x1 = (inxold-3+nx)%nx;
01240                         x2 = (inxold-2+nx)%nx;
01241                         x3 = (inxold-1+nx)%nx;
01242                         x4 = (inxold  +nx)%nx;
01243                         x5 = (inxold+1+nx)%nx;
01244                         x6 = (inxold+2+nx)%nx;
01245                         x7 = (inxold+3+nx)%nx;
01246 
01247                         y1 = ((inyold-3+ny)%ny)*nx;
01248                         y2 = ((inyold-2+ny)%ny)*nx;
01249                         y3 = ((inyold-1+ny)%ny)*nx;
01250                         y4 = ((inyold  +ny)%ny)*nx;
01251                         y5 = ((inyold+1+ny)%ny)*nx;
01252                         y6 = ((inyold+2+ny)%ny)*nx;
01253                         y7 = ((inyold+3+ny)%ny)*nx;
01254                 } else {
01255                         x1 = inxold-3;
01256                         x2 = inxold-2;
01257                         x3 = inxold-1;
01258                         x4 = inxold;
01259                         x5 = inxold+1;
01260                         x6 = inxold+2;
01261                         x7 = inxold+3;
01262 
01263                         y1 = (inyold-3)*nx;
01264                         y2 = (inyold-2)*nx;
01265                         y3 = (inyold-1)*nx;
01266                         y4 = inyold*nx;
01267                         y5 = (inyold+1)*nx;
01268                         y6 = (inyold+2)*nx;
01269                         y7 = (inyold+3)*nx;
01270                 }
01271 
01272                 pixel    = ( data[x1+y1]*tablex1 + data[x2+y1]*tablex2 + data[x3+y1]*tablex3 +
01273                              data[x4+y1]*tablex4 + data[x5+y1]*tablex5 + data[x6+y1]*tablex6 +
01274                              data[x7+y1]*tablex7 ) * tabley1 +
01275                            ( data[x1+y2]*tablex1 + data[x2+y2]*tablex2 + data[x3+y2]*tablex3 +
01276                              data[x4+y2]*tablex4 + data[x5+y2]*tablex5 + data[x6+y2]*tablex6 +
01277                              data[x7+y2]*tablex7 ) * tabley2 +
01278                            ( data[x1+y3]*tablex1 + data[x2+y3]*tablex2 + data[x3+y3]*tablex3 +
01279                              data[x4+y3]*tablex4 + data[x5+y3]*tablex5 + data[x6+y3]*tablex6 +
01280                              data[x7+y3]*tablex7 ) * tabley3 +
01281                            ( data[x1+y4]*tablex1 + data[x2+y4]*tablex2 + data[x3+y4]*tablex3 +
01282                              data[x4+y4]*tablex4 + data[x5+y4]*tablex5 + data[x6+y4]*tablex6 +
01283                              data[x7+y4]*tablex7 ) * tabley4 +
01284                            ( data[x1+y5]*tablex1 + data[x2+y5]*tablex2 + data[x3+y5]*tablex3 +
01285                              data[x4+y5]*tablex4 + data[x5+y5]*tablex5 + data[x6+y5]*tablex6 +
01286                              data[x7+y5]*tablex7 ) * tabley5 +
01287                            ( data[x1+y6]*tablex1 + data[x2+y6]*tablex2 + data[x3+y6]*tablex3 +
01288                              data[x4+y6]*tablex4 + data[x5+y6]*tablex5 + data[x6+y6]*tablex6 +
01289                              data[x7+y6]*tablex7 ) * tabley6 +
01290                            ( data[x1+y7]*tablex1 + data[x2+y7]*tablex2 + data[x3+y7]*tablex3 +
01291                              data[x4+y7]*tablex4 + data[x5+y7]*tablex5 + data[x6+y7]*tablex6 +
01292                              data[x7+y7]*tablex7 ) * tabley7;
01293 
01294                 w = (tablex1+tablex2+tablex3+tablex4+tablex5+tablex6+tablex7) *
01295                     (tabley1+tabley2+tabley3+tabley4+tabley5+tabley6+tabley7);
01296         } else {  //  3D
01297                 dely = restrict1(dely, ny);
01298                 int inyold = int(Util::round(dely));
01299                 delz = restrict1(delz, nz);
01300                 int inzold = int(Util::round(delz));
01301 
01302                 float tablex1 = kb.i0win_tab(delx-inxold+3);
01303                 float tablex2 = kb.i0win_tab(delx-inxold+2);
01304                 float tablex3 = kb.i0win_tab(delx-inxold+1);
01305                 float tablex4 = kb.i0win_tab(delx-inxold);
01306                 float tablex5 = kb.i0win_tab(delx-inxold-1);
01307                 float tablex6 = kb.i0win_tab(delx-inxold-2);
01308                 float tablex7 = kb.i0win_tab(delx-inxold-3);
01309 
01310                 float tabley1 = kb.i0win_tab(dely-inyold+3);
01311                 float tabley2 = kb.i0win_tab(dely-inyold+2);
01312                 float tabley3 = kb.i0win_tab(dely-inyold+1);
01313                 float tabley4 = kb.i0win_tab(dely-inyold);
01314                 float tabley5 = kb.i0win_tab(dely-inyold-1);
01315                 float tabley6 = kb.i0win_tab(dely-inyold-2);
01316                 float tabley7 = kb.i0win_tab(dely-inyold-3);
01317 
01318                 float tablez1 = kb.i0win_tab(delz-inzold+3);
01319                 float tablez2 = kb.i0win_tab(delz-inzold+2);
01320                 float tablez3 = kb.i0win_tab(delz-inzold+1);
01321                 float tablez4 = kb.i0win_tab(delz-inzold);
01322                 float tablez5 = kb.i0win_tab(delz-inzold-1);
01323                 float tablez6 = kb.i0win_tab(delz-inzold-2);
01324                 float tablez7 = kb.i0win_tab(delz-inzold-3);
01325 
01326                 int x1, x2, x3, x4, x5, x6, x7, y1, y2, y3, y4, y5, y6, y7, z1, z2, z3, z4, z5, z6, z7;
01327 
01328                 if ( inxold <= kbc || inxold >=nx-kbc-2 || inyold <= kbc || inyold >=ny-kbc-2 || inzold <= kbc || inzold >= nz-kbc-2 )  {
01329                         x1 = (inxold-3+nx)%nx;
01330                         x2 = (inxold-2+nx)%nx;
01331                         x3 = (inxold-1+nx)%nx;
01332                         x4 = (inxold  +nx)%nx;
01333                         x5 = (inxold+1+nx)%nx;
01334                         x6 = (inxold+2+nx)%nx;
01335                         x7 = (inxold+3+nx)%nx;
01336 
01337                         y1 = ((inyold-3+ny)%ny)*nx;
01338                         y2 = ((inyold-2+ny)%ny)*nx;
01339                         y3 = ((inyold-1+ny)%ny)*nx;
01340                         y4 = ((inyold  +ny)%ny)*nx;
01341                         y5 = ((inyold+1+ny)%ny)*nx;
01342                         y6 = ((inyold+2+ny)%ny)*nx;
01343                         y7 = ((inyold+3+ny)%ny)*nx;
01344 
01345                         z1 = ((inzold-3+nz)%nz)*nx*ny;
01346                         z2 = ((inzold-2+nz)%nz)*nx*ny;
01347                         z3 = ((inzold-1+nz)%nz)*nx*ny;
01348                         z4 = ((inzold  +nz)%nz)*nx*ny;
01349                         z5 = ((inzold+1+nz)%nz)*nx*ny;
01350                         z6 = ((inzold+2+nz)%nz)*nx*ny;
01351                         z7 = ((inzold+3+nz)%nz)*nx*ny;
01352                 } else {
01353                         x1 = inxold-3;
01354                         x2 = inxold-2;
01355                         x3 = inxold-1;
01356                         x4 = inxold;
01357                         x5 = inxold+1;
01358                         x6 = inxold+2;
01359                         x7 = inxold+3;
01360 
01361                         y1 = (inyold-3)*nx;
01362                         y2 = (inyold-2)*nx;
01363                         y3 = (inyold-1)*nx;
01364                         y4 = inyold*nx;
01365                         y5 = (inyold+1)*nx;
01366                         y6 = (inyold+2)*nx;
01367                         y7 = (inyold+3)*nx;
01368 
01369                         z1 = (inzold-3)*nx*ny;
01370                         z2 = (inzold-2)*nx*ny;
01371                         z3 = (inzold-1)*nx*ny;
01372                         z4 = inzold*nx*ny;
01373                         z5 = (inzold+1)*nx*ny;
01374                         z6 = (inzold+2)*nx*ny;
01375                         z7 = (inzold+3)*nx*ny;
01376                 }
01377 
01378                 pixel  = ( ( data[x1+y1+z1]*tablex1 + data[x2+y1+z1]*tablex2 + data[x3+y1+z1]*tablex3 +
01379                              data[x4+y1+z1]*tablex4 + data[x5+y1+z1]*tablex5 + data[x6+y1+z1]*tablex6 +
01380                              data[x7+y1+z1]*tablex7 ) * tabley1 +
01381                            ( data[x1+y2+z1]*tablex1 + data[x2+y2+z1]*tablex2 + data[x3+y2+z1]*tablex3 +
01382                              data[x4+y2+z1]*tablex4 + data[x5+y2+z1]*tablex5 + data[x6+y2+z1]*tablex6 +
01383                              data[x7+y2+z1]*tablex7 ) * tabley2 +
01384                            ( data[x1+y3+z1]*tablex1 + data[x2+y3+z1]*tablex2 + data[x3+y3+z1]*tablex3 +
01385                              data[x4+y3+z1]*tablex4 + data[x5+y3+z1]*tablex5 + data[x6+y3+z1]*tablex6 +
01386                              data[x7+y3+z1]*tablex7 ) * tabley3 +
01387                            ( data[x1+y4+z1]*tablex1 + data[x2+y4+z1]*tablex2 + data[x3+y4+z1]*tablex3 +
01388                              data[x4+y4+z1]*tablex4 + data[x5+y4+z1]*tablex5 + data[x6+y4+z1]*tablex6 +
01389                              data[x7+y4+z1]*tablex7 ) * tabley4 +
01390                            ( data[x1+y5+z1]*tablex1 + data[x2+y5+z1]*tablex2 + data[x3+y5+z1]*tablex3 +
01391                              data[x4+y5+z1]*tablex4 + data[x5+y5+z1]*tablex5 + data[x6+y5+z1]*tablex6 +
01392                              data[x7+y5+z1]*tablex7 ) * tabley5 +
01393                            ( data[x1+y6+z1]*tablex1 + data[x2+y6+z1]*tablex2 + data[x3+y6+z1]*tablex3 +
01394                              data[x4+y6+z1]*tablex4 + data[x5+y6+z1]*tablex5 + data[x6+y6+z1]*tablex6 +
01395                              data[x7+y6+z1]*tablex7 ) * tabley6 +
01396                            ( data[x1+y7+z1]*tablex1 + data[x2+y7+z1]*tablex2 + data[x3+y7+z1]*tablex3 +
01397                              data[x4+y7+z1]*tablex4 + data[x5+y7+z1]*tablex5 + data[x6+y7+z1]*tablex6 +
01398                              data[x7+y7+z1]*tablex7 ) * tabley7 ) *tablez1 +
01399                          ( ( data[x1+y1+z2]*tablex1 + data[x2+y1+z2]*tablex2 + data[x3+y1+z2]*tablex3 +
01400                              data[x4+y1+z2]*tablex4 + data[x5+y1+z2]*tablex5 + data[x6+y1+z2]*tablex6 +
01401                              data[x7+y1+z2]*tablex7 ) * tabley1 +
01402                            ( data[x1+y2+z2]*tablex1 + data[x2+y2+z2]*tablex2 + data[x3+y2+z2]*tablex3 +
01403                              data[x4+y2+z2]*tablex4 + data[x5+y2+z2]*tablex5 + data[x6+y2+z2]*tablex6 +
01404                              data[x7+y2+z2]*tablex7 ) * tabley2 +
01405                            ( data[x1+y3+z2]*tablex1 + data[x2+y3+z2]*tablex2 + data[x3+y3+z2]*tablex3 +
01406                              data[x4+y3+z2]*tablex4 + data[x5+y3+z2]*tablex5 + data[x6+y3+z2]*tablex6 +
01407                              data[x7+y3+z2]*tablex7 ) * tabley3 +
01408                            ( data[x1+y4+z2]*tablex1 + data[x2+y4+z2]*tablex2 + data[x3+y4+z2]*tablex3 +
01409                              data[x4+y4+z2]*tablex4 + data[x5+y4+z2]*tablex5 + data[x6+y4+z2]*tablex6 +
01410                              data[x7+y4+z2]*tablex7 ) * tabley4 +
01411                            ( data[x1+y5+z2]*tablex1 + data[x2+y5+z2]*tablex2 + data[x3+y5+z2]*tablex3 +
01412                              data[x4+y5+z2]*tablex4 + data[x5+y5+z2]*tablex5 + data[x6+y5+z2]*tablex6 +
01413                              data[x7+y5+z2]*tablex7 ) * tabley5 +
01414                            ( data[x1+y6+z2]*tablex1 + data[x2+y6+z2]*tablex2 + data[x3+y6+z2]*tablex3 +
01415                              data[x4+y6+z2]*tablex4 + data[x5+y6+z2]*tablex5 + data[x6+y6+z2]*tablex6 +
01416                              data[x7+y6+z2]*tablex7 ) * tabley6 +
01417                            ( data[x1+y7+z2]*tablex1 + data[x2+y7+z2]*tablex2 + data[x3+y7+z2]*tablex3 +
01418                              data[x4+y7+z2]*tablex4 + data[x5+y7+z2]*tablex5 + data[x6+y7+z2]*tablex6 +
01419                              data[x7+y7+z2]*tablex7 ) * tabley7 ) *tablez2 +
01420                          ( ( data[x1+y1+z3]*tablex1 + data[x2+y1+z3]*tablex2 + data[x3+y1+z3]*tablex3 +
01421                              data[x4+y1+z3]*tablex4 + data[x5+y1+z3]*tablex5 + data[x6+y1+z3]*tablex6 +
01422                              data[x7+y1+z3]*tablex7 ) * tabley1 +
01423                            ( data[x1+y2+z3]*tablex1 + data[x2+y2+z3]*tablex2 + data[x3+y2+z3]*tablex3 +
01424                              data[x4+y2+z3]*tablex4 + data[x5+y2+z3]*tablex5 + data[x6+y2+z3]*tablex6 +
01425                              data[x7+y2+z3]*tablex7 ) * tabley2 +
01426                            ( data[x1+y3+z3]*tablex1 + data[x2+y3+z3]*tablex2 + data[x3+y3+z3]*tablex3 +
01427                              data[x4+y3+z3]*tablex4 + data[x5+y3+z3]*tablex5 + data[x6+y3+z3]*tablex6 +
01428                              data[x7+y3+z3]*tablex7 ) * tabley3 +
01429                            ( data[x1+y4+z3]*tablex1 + data[x2+y4+z3]*tablex2 + data[x3+y4+z3]*tablex3 +
01430                              data[x4+y4+z3]*tablex4 + data[x5+y4+z3]*tablex5 + data[x6+y4+z3]*tablex6 +
01431                              data[x7+y4+z3]*tablex7 ) * tabley4 +
01432                            ( data[x1+y5+z3]*tablex1 + data[x2+y5+z3]*tablex2 + data[x3+y5+z3]*tablex3 +
01433                              data[x4+y5+z3]*tablex4 + data[x5+y5+z3]*tablex5 + data[x6+y5+z3]*tablex6 +
01434                              data[x7+y5+z3]*tablex7 ) * tabley5 +
01435                            ( data[x1+y6+z3]*tablex1 + data[x2+y6+z3]*tablex2 + data[x3+y6+z3]*tablex3 +
01436                              data[x4+y6+z3]*tablex4 + data[x5+y6+z3]*tablex5 + data[x6+y6+z3]*tablex6 +
01437                              data[x7+y6+z3]*tablex7 ) * tabley6 +
01438                            ( data[x1+y7+z3]*tablex1 + data[x2+y7+z3]*tablex2 + data[x3+y7+z3]*tablex3 +
01439                              data[x4+y7+z3]*tablex4 + data[x5+y7+z3]*tablex5 + data[x6+y7+z3]*tablex6 +
01440                              data[x7+y7+z3]*tablex7 ) * tabley7 ) *tablez3 +
01441                          ( ( data[x1+y1+z4]*tablex1 + data[x2+y1+z4]*tablex2 + data[x3+y1+z4]*tablex3 +
01442                              data[x4+y1+z4]*tablex4 + data[x5+y1+z4]*tablex5 + data[x6+y1+z4]*tablex6 +
01443                              data[x7+y1+z4]*tablex7 ) * tabley1 +
01444                            ( data[x1+y2+z4]*tablex1 + data[x2+y2+z4]*tablex2 + data[x3+y2+z4]*tablex3 +
01445                              data[x4+y2+z4]*tablex4 + data[x5+y2+z4]*tablex5 + data[x6+y2+z4]*tablex6 +
01446                              data[x7+y2+z4]*tablex7 ) * tabley2 +
01447                            ( data[x1+y3+z4]*tablex1 + data[x2+y3+z4]*tablex2 + data[x3+y3+z4]*tablex3 +
01448                              data[x4+y3+z4]*tablex4 + data[x5+y3+z4]*tablex5 + data[x6+y3+z4]*tablex6 +
01449                              data[x7+y3+z4]*tablex7 ) * tabley3 +
01450                            ( data[x1+y4+z4]*tablex1 + data[x2+y4+z4]*tablex2 + data[x3+y4+z4]*tablex3 +
01451                              data[x4+y4+z4]*tablex4 + data[x5+y4+z4]*tablex5 + data[x6+y4+z4]*tablex6 +
01452                              data[x7+y4+z4]*tablex7 ) * tabley4 +
01453                            ( data[x1+y5+z4]*tablex1 + data[x2+y5+z4]*tablex2 + data[x3+y5+z4]*tablex3 +
01454                              data[x4+y5+z4]*tablex4 + data[x5+y5+z4]*tablex5 + data[x6+y5+z4]*tablex6 +
01455                              data[x7+y5+z4]*tablex7 ) * tabley5 +
01456                            ( data[x1+y6+z4]*tablex1 + data[x2+y6+z4]*tablex2 + data[x3+y6+z4]*tablex3 +
01457                              data[x4+y6+z4]*tablex4 + data[x5+y6+z4]*tablex5 + data[x6+y6+z4]*tablex6 +
01458                              data[x7+y6+z4]*tablex7 ) * tabley6 +
01459                            ( data[x1+y7+z4]*tablex1 + data[x2+y7+z4]*tablex2 + data[x3+y7+z4]*tablex3 +
01460                              data[x4+y7+z4]*tablex4 + data[x5+y7+z4]*tablex5 + data[x6+y7+z4]*tablex6 +
01461                              data[x7+y7+z4]*tablex7 ) * tabley7 ) *tablez4 +
01462                          ( ( data[x1+y1+z5]*tablex1 + data[x2+y1+z5]*tablex2 + data[x3+y1+z5]*tablex3 +
01463                              data[x4+y1+z5]*tablex4 + data[x5+y1+z5]*tablex5 + data[x6+y1+z5]*tablex6 +
01464                              data[x7+y1+z5]*tablex7 ) * tabley1 +
01465                            ( data[x1+y2+z5]*tablex1 + data[x2+y2+z5]*tablex2 + data[x3+y2+z5]*tablex3 +
01466                              data[x4+y2+z5]*tablex4 + data[x5+y2+z5]*tablex5 + data[x6+y2+z5]*tablex6 +
01467                              data[x7+y2+z5]*tablex7 ) * tabley2 +
01468                            ( data[x1+y3+z5]*tablex1 + data[x2+y3+z5]*tablex2 + data[x3+y3+z5]*tablex3 +
01469                              data[x4+y3+z5]*tablex4 + data[x5+y3+z5]*tablex5 + data[x6+y3+z5]*tablex6 +
01470                              data[x7+y3+z5]*tablex7 ) * tabley3 +
01471                            ( data[x1+y4+z5]*tablex1 + data[x2+y4+z5]*tablex2 + data[x3+y4+z5]*tablex3 +
01472                              data[x4+y4+z5]*tablex4 + data[x5+y4+z5]*tablex5 + data[x6+y4+z5]*tablex6 +
01473                              data[x7+y4+z5]*tablex7 ) * tabley4 +
01474                            ( data[x1+y5+z5]*tablex1 + data[x2+y5+z5]*tablex2 + data[x3+y5+z5]*tablex3 +
01475                              data[x4+y5+z5]*tablex4 + data[x5+y5+z5]*tablex5 + data[x6+y5+z5]*tablex6 +
01476                              data[x7+y5+z5]*tablex7 ) * tabley5 +
01477                            ( data[x1+y6+z5]*tablex1 + data[x2+y6+z5]*tablex2 + data[x3+y6+z5]*tablex3 +
01478                              data[x4+y6+z5]*tablex4 + data[x5+y6+z5]*tablex5 + data[x6+y6+z5]*tablex6 +
01479                              data[x7+y6+z5]*tablex7 ) * tabley6 +
01480                            ( data[x1+y7+z5]*tablex1 + data[x2+y7+z5]*tablex2 + data[x3+y7+z5]*tablex3 +
01481                              data[x4+y7+z5]*tablex4 + data[x5+y7+z5]*tablex5 + data[x6+y7+z5]*tablex6 +
01482                              data[x7+y7+z5]*tablex7 ) * tabley7 ) *tablez5 +
01483                          ( ( data[x1+y1+z6]*tablex1 + data[x2+y1+z6]*tablex2 + data[x3+y1+z6]*tablex3 +
01484                              data[x4+y1+z6]*tablex4 + data[x5+y1+z6]*tablex5 + data[x6+y1+z6]*tablex6 +
01485                              data[x7+y1+z6]*tablex7 ) * tabley1 +
01486                            ( data[x1+y2+z6]*tablex1 + data[x2+y2+z6]*tablex2 + data[x3+y2+z6]*tablex3 +
01487                              data[x4+y2+z6]*tablex4 + data[x5+y2+z6]*tablex5 + data[x6+y2+z6]*tablex6 +
01488                              data[x7+y2+z6]*tablex7 ) * tabley2 +
01489                            ( data[x1+y3+z6]*tablex1 + data[x2+y3+z6]*tablex2 + data[x3+y3+z6]*tablex3 +
01490                              data[x4+y3+z6]*tablex4 + data[x5+y3+z6]*tablex5 + data[x6+y3+z6]*tablex6 +
01491                              data[x7+y3+z6]*tablex7 ) * tabley3 +
01492                            ( data[x1+y4+z6]*tablex1 + data[x2+y4+z6]*tablex2 + data[x3+y4+z6]*tablex3 +
01493                              data[x4+y4+z6]*tablex4 + data[x5+y4+z6]*tablex5 + data[x6+y4+z6]*tablex6 +
01494                              data[x7+y4+z6]*tablex7 ) * tabley4 +
01495                            ( data[x1+y5+z6]*tablex1 + data[x2+y5+z6]*tablex2 + data[x3+y5+z6]*tablex3 +
01496                              data[x4+y5+z6]*tablex4 + data[x5+y5+z6]*tablex5 + data[x6+y5+z6]*tablex6 +
01497                              data[x7+y5+z6]*tablex7 ) * tabley5 +
01498                            ( data[x1+y6+z6]*tablex1 + data[x2+y6+z6]*tablex2 + data[x3+y6+z6]*tablex3 +
01499                              data[x4+y6+z6]*tablex4 + data[x5+y6+z6]*tablex5 + data[x6+y6+z6]*tablex6 +
01500                              data[x7+y6+z6]*tablex7 ) * tabley6 +
01501                            ( data[x1+y7+z6]*tablex1 + data[x2+y7+z6]*tablex2 + data[x3+y7+z6]*tablex3 +
01502                              data[x4+y7+z6]*tablex4 + data[x5+y7+z6]*tablex5 + data[x6+y7+z6]*tablex6 +
01503                              data[x7+y7+z6]*tablex7 ) * tabley7 ) *tablez6 +
01504                          ( ( data[x1+y1+z7]*tablex1 + data[x2+y1+z7]*tablex2 + data[x3+y1+z7]*tablex3 +
01505                              data[x4+y1+z7]*tablex4 + data[x5+y1+z7]*tablex5 + data[x6+y1+z7]*tablex6 +
01506                              data[x7+y1+z7]*tablex7 ) * tabley1 +
01507                            ( data[x1+y2+z7]*tablex1 + data[x2+y2+z7]*tablex2 + data[x3+y2+z7]*tablex3 +
01508                              data[x4+y2+z7]*tablex4 + data[x5+y2+z7]*tablex5 + data[x6+y2+z7]*tablex6 +
01509                              data[x7+y2+z7]*tablex7 ) * tabley2 +
01510                            ( data[x1+y3+z7]*tablex1 + data[x2+y3+z7]*tablex2 + data[x3+y3+z7]*tablex3 +
01511                              data[x4+y3+z7]*tablex4 + data[x5+y3+z7]*tablex5 + data[x6+y3+z7]*tablex6 +
01512                              data[x7+y3+z7]*tablex7 ) * tabley3 +
01513                            ( data[x1+y4+z7]*tablex1 + data[x2+y4+z7]*tablex2 + data[x3+y4+z7]*tablex3 +
01514                              data[x4+y4+z7]*tablex4 + data[x5+y4+z7]*tablex5 + data[x6+y4+z7]*tablex6 +
01515                              data[x7+y4+z7]*tablex7 ) * tabley4 +
01516                            ( data[x1+y5+z7]*tablex1 + data[x2+y5+z7]*tablex2 + data[x3+y5+z7]*tablex3 +
01517                              data[x4+y5+z7]*tablex4 + data[x5+y5+z7]*tablex5 + data[x6+y5+z7]*tablex6 +
01518                              data[x7+y5+z7]*tablex7 ) * tabley5 +
01519                            ( data[x1+y6+z7]*tablex1 + data[x2+y6+z7]*tablex2 + data[x3+y6+z7]*tablex3 +
01520                              data[x4+y6+z7]*tablex4 + data[x5+y6+z7]*tablex5 + data[x6+y6+z7]*tablex6 +
01521                              data[x7+y6+z7]*tablex7 ) * tabley6 +
01522                            ( data[x1+y7+z7]*tablex1 + data[x2+y7+z7]*tablex2 + data[x3+y7+z7]*tablex3 +
01523                              data[x4+y7+z7]*tablex4 + data[x5+y7+z7]*tablex5 + data[x6+y7+z7]*tablex6 +
01524                              data[x7+y7+z7]*tablex7 ) * tabley7 ) *tablez7;
01525 
01526                 w = (tablex1+tablex2+tablex3+tablex4+tablex5+tablex6+tablex7) *
01527                     (tabley1+tabley2+tabley3+tabley4+tabley5+tabley6+tabley7) *
01528                     (tablez1+tablez2+tablez3+tablez4+tablez5+tablez6+tablez7);
01529         }
01530         return pixel/w;
01531 }
01532 
01533 /*
01534 complex<float> Util::extractpoint2(int nx, int ny, float nuxnew, float nuynew, EMData *fimage, Util::KaiserBessel& kb) {
01535 
01536         int nxreal = nx - 2;
01537         if (nxreal != ny)
01538                 throw ImageDimensionException("extractpoint requires ny == nx");
01539         int nhalf = nxreal/2;
01540         int kbsize = kb.get_window_size();
01541         int kbmin = -kbsize/2;
01542         int kbmax = -kbmin;
01543         bool flip = (nuxnew < 0.f);
01544         if (flip) {
01545                 nuxnew *= -1;
01546                 nuynew *= -1;
01547         }
01548         // put (xnew,ynew) on a grid.  The indices will be wrong for
01549         // the Fourier elements in the image, but the grid sizing will
01550         // be correct.
01551         int ixn = int(Util::round(nuxnew));
01552         int iyn = int(Util::round(nuynew));
01553         // set up some temporary weighting arrays
01554         float* wy0 = new float[kbmax - kbmin + 1];
01555         float* wy = wy0 - kbmin; // wy[kbmin:kbmax]
01556         float* wx0 = new float[kbmax - kbmin + 1];
01557         float* wx = wx0 - kbmin;
01558         for (int i = kbmin; i <= kbmax; i++) {
01559                         int iyp = iyn + i;
01560                         wy[i] = kb.i0win_tab(nuynew - iyp);
01561                         int ixp = ixn + i;
01562                         wx[i] = kb.i0win_tab(nuxnew - ixp);
01563         }
01564         // restrict loops to non-zero elements
01565         int iymin = 0;
01566         for (int iy = kbmin; iy <= -1; iy++) {
01567                 if (wy[iy] != 0.f) {
01568                         iymin = iy;
01569                         break;
01570                 }
01571         }
01572         int iymax = 0;
01573         for (int iy = kbmax; iy >= 1; iy--) {
01574                 if (wy[iy] != 0.f) {
01575                         iymax = iy;
01576                         break;
01577                 }
01578         }
01579         int ixmin = 0;
01580         for (int ix = kbmin; ix <= -1; ix++) {
01581                 if (wx[ix] != 0.f) {
01582                         ixmin = ix;
01583                         break;
01584                 }
01585         }
01586         int ixmax = 0;
01587         for (int ix = kbmax; ix >= 1; ix--) {
01588                 if (wx[ix] != 0.f) {
01589                         ixmax = ix;
01590                         break;
01591                 }
01592         }
01593         float wsum = 0.0f;
01594         for (int iy = iymin; iy <= iymax; iy++)
01595                 for (int ix = ixmin; ix <= ixmax; ix++)
01596                         wsum += wx[ix]*wy[iy];
01597 
01598         complex<float> result(0.f,0.f);
01599         if ((ixn >= -kbmin) && (ixn <= nhalf-1-kbmax) && (iyn >= -nhalf-kbmin) && (iyn <= nhalf-1-kbmax)) {
01600                 // (xin,yin) not within window border from the edge
01601                 for (int iy = iymin; iy <= iymax; iy++) {
01602                         int iyp = iyn + iy;
01603                         for (int ix = ixmin; ix <= ixmax; ix++) {
01604                                 int ixp = ixn + ix;
01605                                 float w = wx[ix]*wy[iy];
01606                                 complex<float> val = fimage->cmplx(ixp,iyp);
01607                                 result += val*w;
01608                         }
01609                 }
01610         } else {
01611                 // points that "stick out"
01612                 for (int iy = iymin; iy <= iymax; iy++) {
01613                         int iyp = iyn + iy;
01614                         for (int ix = ixmin; ix <= ixmax; ix++) {
01615                                 int ixp = ixn + ix;
01616                                 bool mirror = false;
01617                                 int ixt= ixp, iyt= iyp;
01618                                 if (ixt < 0) {
01619                                         ixt = -ixt;
01620                                         iyt = -iyt;
01621                                         mirror = !mirror;
01622                                 }
01623                                 if (ixt > nhalf) {
01624                                         ixt = nxreal - ixt;
01625                                         iyt = -iyt;
01626                                         mirror = !mirror;
01627                                 }
01628                                 if (iyt > nhalf-1)  iyt -= nxreal;
01629                                 if (iyt < -nhalf)   iyt += nxreal;
01630                                 float w = wx[ix]*wy[iy];
01631                                 complex<float> val = fimage->cmplx(ixt,iyt);
01632                                 if (mirror)  result += conj(val)*w;
01633                                 else         result += val*w;
01634                         }
01635                 }
01636         }
01637         if (flip)  result = conj(result)/wsum;
01638         else result /= wsum;
01639         delete [] wx0;
01640         delete [] wy0;
01641         return result;
01642 }*/
01643 
01644 /*
01645 complex<float> Util::extractpoint2(int nx, int ny, float nuxnew, float nuynew, EMData *fimage, Util::KaiserBessel& kb) {
01646 
01647         int nxreal = nx - 2;
01648         if (nxreal != ny)
01649                 throw ImageDimensionException("extractpoint requires ny == nx");
01650         int nhalf = nxreal/2;
01651         bool flip = false;
01652         if (nuxnew < 0.f) {
01653                 nuxnew *= -1;
01654                 nuynew *= -1;
01655                 flip = true;
01656         }
01657         if (nuynew >= nhalf-0.5)  {
01658                 nuynew -= nxreal;
01659         } else if (nuynew < -nhalf-0.5) {
01660                 nuynew += nxreal;
01661         }
01662 
01663         // put (xnew,ynew) on a grid.  The indices will be wrong for
01664         // the Fourier elements in the image, but the grid sizing will
01665         // be correct.
01666         int ixn = int(Util::round(nuxnew));
01667         int iyn = int(Util::round(nuynew));
01668 
01669         // set up some temporary weighting arrays
01670         static float wy[7];
01671         static float wx[7];
01672 
01673         float iynn = nuynew - iyn;
01674         wy[0] = kb.i0win_tab(iynn+3);
01675         wy[1] = kb.i0win_tab(iynn+2);
01676         wy[2] = kb.i0win_tab(iynn+1);
01677         wy[3] = kb.i0win_tab(iynn);
01678         wy[4] = kb.i0win_tab(iynn-1);
01679         wy[5] = kb.i0win_tab(iynn-2);
01680         wy[6] = kb.i0win_tab(iynn-3);
01681 
01682         float ixnn = nuxnew - ixn;
01683         wx[0] = kb.i0win_tab(ixnn+3);
01684         wx[1] = kb.i0win_tab(ixnn+2);
01685         wx[2] = kb.i0win_tab(ixnn+1);
01686         wx[3] = kb.i0win_tab(ixnn);
01687         wx[4] = kb.i0win_tab(ixnn-1);
01688         wx[5] = kb.i0win_tab(ixnn-2);
01689         wx[6] = kb.i0win_tab(ixnn-3);
01690 
01691         float wsum = (wx[0]+wx[1]+wx[2]+wx[3]+wx[4]+wx[5]+wx[6])*(wy[0]+wy[1]+wy[2]+wy[3]+wy[4]+wy[5]+wy[6]);
01692 
01693         complex<float> result(0.f,0.f);
01694         for (int iy = 0; iy < 7; iy++) {
01695                 int iyp = iyn + iy - 3 ;
01696                 for (int ix = 0; ix < 7; ix++) {
01697                         int ixp = ixn + ix - 3;
01698                         float w = wx[ix]*wy[iy];
01699                         complex<float> val = fimage->cmplx(ixp,iyp);
01700                         result += val*w;
01701                 }
01702         }
01703 
01704         if (flip)  result = conj(result)/wsum;
01705         else result /= wsum;
01706 
01707         return result;
01708 }*/
01709 
01710 
01711 complex<float> Util::extractpoint2(int nx, int ny, float nuxnew, float nuynew, EMData *fimage, Util::KaiserBessel& kb) {
01712 
01713         int nxreal = nx - 2;
01714         if (nxreal != ny)
01715                 throw ImageDimensionException("extractpoint requires ny == nx");
01716         int nhalf = nxreal/2;
01717         bool flip = (nuxnew < 0.f);
01718         if (flip) {
01719                 nuxnew *= -1;
01720                 nuynew *= -1;
01721         }
01722         if (nuynew >= nhalf-0.5)  {
01723                 nuynew -= nxreal;
01724         } else if (nuynew < -nhalf-0.5) {
01725                 nuynew += nxreal;
01726         }
01727 
01728         // put (xnew,ynew) on a grid.  The indices will be wrong for
01729         // the Fourier elements in the image, but the grid sizing will
01730         // be correct.
01731         int ixn = int(Util::round(nuxnew));
01732         int iyn = int(Util::round(nuynew));
01733 
01734         // set up some temporary weighting arrays
01735         static float wy[7];
01736         static float wx[7];
01737 
01738         float iynn = nuynew - iyn;
01739         wy[0] = kb.i0win_tab(iynn+3);
01740         wy[1] = kb.i0win_tab(iynn+2);
01741         wy[2] = kb.i0win_tab(iynn+1);
01742         wy[3] = kb.i0win_tab(iynn);
01743         wy[4] = kb.i0win_tab(iynn-1);
01744         wy[5] = kb.i0win_tab(iynn-2);
01745         wy[6] = kb.i0win_tab(iynn-3);
01746 
01747         float ixnn = nuxnew - ixn;
01748         wx[0] = kb.i0win_tab(ixnn+3);
01749         wx[1] = kb.i0win_tab(ixnn+2);
01750         wx[2] = kb.i0win_tab(ixnn+1);
01751         wx[3] = kb.i0win_tab(ixnn);
01752         wx[4] = kb.i0win_tab(ixnn-1);
01753         wx[5] = kb.i0win_tab(ixnn-2);
01754         wx[6] = kb.i0win_tab(ixnn-3);
01755 
01756         float wsum = (wx[0]+wx[1]+wx[2]+wx[3]+wx[4]+wx[5]+wx[6])*(wy[0]+wy[1]+wy[2]+wy[3]+wy[4]+wy[5]+wy[6]);
01757 
01758         complex<float> result(0.f,0.f);
01759         if ((ixn >= 3) && (ixn <= nhalf-3) && (iyn >= -nhalf+3) && (iyn <= nhalf-4)) {
01760                 // (xin,yin) not within window border from the edge
01761                 for (int iy = 0; iy < 7; iy++) {
01762                         int iyp = iyn + iy - 3 ;
01763                         for (int ix = 0; ix < 7; ix++) {
01764                                 int ixp = ixn + ix - 3;
01765                                 float w = wx[ix]*wy[iy];
01766                                 complex<float> val = fimage->cmplx(ixp,iyp);
01767                                 result += val*w;
01768                         }
01769                 }
01770         } else {
01771                 // points that "stick out"
01772                 for (int iy = 0; iy < 7; iy++) {
01773                         int iyp = iyn + iy - 3;
01774                         for (int ix = 0; ix < 7; ix++) {
01775                                 int ixp = ixn + ix - 3;
01776                                 bool mirror = false;
01777                                 int ixt = ixp, iyt = iyp;
01778                                 if (ixt < 0) {
01779                                         ixt = -ixt;
01780                                         iyt = -iyt;
01781                                         mirror = !mirror;
01782                                 }
01783                                 if (ixt > nhalf) {
01784                                         ixt = nxreal - ixt;
01785                                         iyt = -iyt;
01786                                         mirror = !mirror;
01787                                 }
01788                                 if (iyt > nhalf-1)  iyt -= nxreal;
01789                                 if (iyt < -nhalf)   iyt += nxreal;
01790                                 float w = wx[ix]*wy[iy];
01791                                 complex<float> val = fimage->cmplx(ixt,iyt);
01792                                 if (mirror)  result += conj(val)*w;
01793                                 else         result += val*w;
01794                         }
01795                 }
01796         }
01797         if (flip)  result = conj(result)/wsum;
01798         else result /= wsum;
01799         return result;
01800 }
01801 
01802 /*
01803 complex<float> Util::extractpoint2(int nx, int ny, float nuxnew, float nuynew, EMData *fimage, Util::KaiserBessel& kb) {
01804 
01805         int nxreal = nx - 2;
01806         if (nxreal != ny)
01807                 throw ImageDimensionException("extractpoint requires ny == nx");
01808         int nhalf = nxreal/2;
01809         bool flip = (nuxnew < 0.f);
01810         if (flip) {
01811                 nuxnew *= -1;
01812                 nuynew *= -1;
01813         }
01814         // put (xnew,ynew) on a grid.  The indices will be wrong for
01815         // the Fourier elements in the image, but the grid sizing will
01816         // be correct.
01817         int ixn = int(Util::round(nuxnew));
01818         int iyn = int(Util::round(nuynew));
01819         // set up some temporary weighting arrays
01820         static float wy[7];
01821         static float wx[7];
01822 
01823         float iynn = nuynew - iyn;
01824         wy[0] = kb.i0win_tab(iynn+3);
01825         wy[1] = kb.i0win_tab(iynn+2);
01826         wy[2] = kb.i0win_tab(iynn+1);
01827         wy[3] = kb.i0win_tab(iynn);
01828         wy[4] = kb.i0win_tab(iynn-1);
01829         wy[5] = kb.i0win_tab(iynn-2);
01830         wy[6] = kb.i0win_tab(iynn-3);
01831 
01832         float ixnn = nuxnew - ixn;
01833         wx[0] = kb.i0win_tab(ixnn+3);
01834         wx[1] = kb.i0win_tab(ixnn+2);
01835         wx[2] = kb.i0win_tab(ixnn+1);
01836         wx[3] = kb.i0win_tab(ixnn);
01837         wx[4] = kb.i0win_tab(ixnn-1);
01838         wx[5] = kb.i0win_tab(ixnn-2);
01839         wx[6] = kb.i0win_tab(ixnn-3);
01840 
01841         float wsum = (wx[0]+wx[1]+wx[2]+wx[3]+wx[4]+wx[5]+wx[6])*(wy[0]+wy[1]+wy[2]+wy[3]+wy[4]+wy[5]+wy[6]);
01842 
01843         complex<float> result(0.f,0.f);
01844 
01845         if ((ixn >= 3) && (ixn <= nhalf-3) && (iyn >= -nhalf+3) && (iyn <= nhalf-4)) {
01846                 // (xin,yin) not within window border from the edge
01847                 result = ( fimage->cmplx(ixn-3,iyn-3)*wx[0] +
01848                            fimage->cmplx(ixn-2,iyn-3)*wx[1] +
01849                            fimage->cmplx(ixn-1,iyn-3)*wx[2] +
01850                            fimage->cmplx(ixn+0,iyn-3)*wx[3] +
01851                            fimage->cmplx(ixn+1,iyn-3)*wx[4] +
01852                            fimage->cmplx(ixn+2,iyn-3)*wx[5] +
01853                            fimage->cmplx(ixn+3,iyn-3)*wx[6] )*wy[0] +
01854                            ( fimage->cmplx(ixn-3,iyn-2)*wx[0] +
01855                            fimage->cmplx(ixn-2,iyn-2)*wx[1] +
01856                            fimage->cmplx(ixn-1,iyn-2)*wx[2] +
01857                            fimage->cmplx(ixn+0,iyn-2)*wx[3] +
01858                            fimage->cmplx(ixn+1,iyn-2)*wx[4] +
01859                            fimage->cmplx(ixn+2,iyn-2)*wx[5] +
01860                            fimage->cmplx(ixn+3,iyn-2)*wx[6] )*wy[1] +
01861                            ( fimage->cmplx(ixn-3,iyn-1)*wx[0] +
01862                            fimage->cmplx(ixn-2,iyn-1)*wx[1] +
01863                            fimage->cmplx(ixn-1,iyn-1)*wx[2] +
01864                            fimage->cmplx(ixn+0,iyn-1)*wx[3] +
01865                            fimage->cmplx(ixn+1,iyn-1)*wx[4] +
01866                            fimage->cmplx(ixn+2,iyn-1)*wx[5] +
01867                            fimage->cmplx(ixn+3,iyn-1)*wx[6] )*wy[2] +
01868                            ( fimage->cmplx(ixn-3,iyn+0)*wx[0] +
01869                            fimage->cmplx(ixn-2,iyn+0)*wx[1] +
01870                            fimage->cmplx(ixn-1,iyn+0)*wx[2] +
01871                            fimage->cmplx(ixn+0,iyn+0)*wx[3] +
01872                            fimage->cmplx(ixn+1,iyn+0)*wx[4] +
01873                            fimage->cmplx(ixn+2,iyn+0)*wx[5] +
01874                            fimage->cmplx(ixn+3,iyn+0)*wx[6] )*wy[3] +
01875                            ( fimage->cmplx(ixn-3,iyn+1)*wx[0] +
01876                            fimage->cmplx(ixn-2,iyn+1)*wx[1] +
01877                            fimage->cmplx(ixn-1,iyn+1)*wx[2] +
01878                            fimage->cmplx(ixn+0,iyn+1)*wx[3] +
01879                            fimage->cmplx(ixn+1,iyn+1)*wx[4] +
01880                            fimage->cmplx(ixn+2,iyn+1)*wx[5] +
01881                            fimage->cmplx(ixn+3,iyn+1)*wx[6] )*wy[4] +
01882                            ( fimage->cmplx(ixn-3,iyn+2)*wx[0] +
01883                            fimage->cmplx(ixn-2,iyn+2)*wx[1] +
01884                            fimage->cmplx(ixn-1,iyn+2)*wx[2] +
01885                            fimage->cmplx(ixn+0,iyn+2)*wx[3] +
01886                            fimage->cmplx(ixn+1,iyn+2)*wx[4] +
01887                            fimage->cmplx(ixn+2,iyn+2)*wx[5] +
01888                            fimage->cmplx(ixn+3,iyn+2)*wx[6] )*wy[5] +
01889                            ( fimage->cmplx(ixn-3,iyn+3)*wx[0] +
01890                            fimage->cmplx(ixn-2,iyn+3)*wx[1] +
01891                            fimage->cmplx(ixn-1,iyn+3)*wx[2] +
01892                            fimage->cmplx(ixn+0,iyn+3)*wx[3] +
01893                            fimage->cmplx(ixn+1,iyn+3)*wx[4] +
01894                            fimage->cmplx(ixn+2,iyn+3)*wx[5] +
01895                            fimage->cmplx(ixn+3,iyn+3)*wx[6] )*wy[6];
01896 
01897         } else {
01898                 // points that "stick out"
01899                 for (int iy = 0; iy < 7; iy++) {
01900                         int iyp = iyn + iy - 3;
01901                         for (int ix = 0; ix < 7; ix++) {
01902                                 int ixp = ixn + ix - 3;
01903                                 bool mirror = false;
01904                                 int ixt= ixp, iyt= iyp;
01905                                 if (ixt < 0) {
01906                                         ixt = -ixt;
01907                                         iyt = -iyt;
01908                                         mirror = !mirror;
01909                                 }
01910                                 if (ixt > nhalf) {
01911                                         ixt = nxreal - ixt;
01912                                         iyt = -iyt;
01913                                         mirror = !mirror;
01914                                 }
01915                                 if (iyt > nhalf-1)  iyt -= nxreal;
01916                                 if (iyt < -nhalf)   iyt += nxreal;
01917                                 float w = wx[ix]*wy[iy];
01918                                 complex<float> val = fimage->cmplx(ixt,iyt);
01919                                 if (mirror)  result += conj(val)*w;
01920                                 else         result += val*w;
01921                         }
01922                 }
01923         }
01924         if (flip)  result = conj(result)/wsum;
01925         else result /= wsum;
01926         return result;
01927 }*/
01928 
01929 
01930 float Util::triquad(float R, float S, float T, float* fdata)
01931 {
01932 
01933     const float C2 = 0.5f;    //1.0 / 2.0;
01934     const float C4 = 0.25f;   //1.0 / 4.0;
01935     const float C8 = 0.125f;  //1.0 / 8.0;
01936 
01937     float  RS   = R * S;
01938     float  ST   = S * T;
01939     float  RT   = R * T;
01940     float  RST  = R * ST;
01941 
01942     float  RSQ  = 1-R*R;
01943     float  SSQ  = 1-S*S;
01944     float  TSQ  = 1-T*T;
01945 
01946     float  RM1  = (1-R);
01947     float  SM1  = (1-S);
01948     float  TM1  = (1-T);
01949 
01950     float  RP1  = (1+R);
01951     float  SP1  = (1+S);
01952     float  TP1  = (1+T);
01953 
01954     float triquad =
01955     (-C8) * RST * RM1  * SM1  * TM1 * fdata[0] +
01956         ( C4) * ST  * RSQ  * SM1  * TM1 * fdata[1] +
01957         ( C8) * RST * RP1  * SM1  * TM1 * fdata[2] +
01958         ( C4) * RT  * RM1  * SSQ  * TM1 * fdata[3] +
01959         (-C2) * T   * RSQ  * SSQ  * TM1 * fdata[4] +
01960         (-C4) * RT  * RP1  * SSQ  * TM1 * fdata[5] +
01961         ( C8) * RST * RM1  * SP1  * TM1 * fdata[6] +
01962         (-C4) * ST  * RSQ  * SP1  * TM1 * fdata[7] +
01963         (-C8) * RST * RP1  * SP1  * TM1 * fdata[8] +
01964 //
01965         ( C4) * RS  * RM1  * SM1  * TSQ * fdata[9]  +
01966         (-C2) * S   * RSQ  * SM1  * TSQ * fdata[10] +
01967         (-C4) * RS  * RP1  * SM1  * TSQ * fdata[11] +
01968         (-C2) * R   * RM1  * SSQ  * TSQ * fdata[12] +
01969                       RSQ  * SSQ  * TSQ * fdata[13] +
01970         ( C2) * R   * RP1  * SSQ  * TSQ * fdata[14] +
01971         (-C4) * RS  * RM1  * SP1  * TSQ * fdata[15] +
01972         ( C2) * S   * RSQ  * SP1  * TSQ * fdata[16] +
01973         ( C4) * RS  * RP1  * SP1  * TSQ * fdata[17] +
01974  //
01975         ( C8) * RST * RM1  * SM1  * TP1 * fdata[18] +
01976         (-C4) * ST  * RSQ  * SM1  * TP1 * fdata[19] +
01977         (-C8) * RST * RP1  * SM1  * TP1 * fdata[20] +
01978         (-C4) * RT  * RM1  * SSQ  * TP1 * fdata[21] +
01979         ( C2) * T   * RSQ  * SSQ  * TP1 * fdata[22] +
01980         ( C4) * RT  * RP1  * SSQ  * TP1 * fdata[23] +
01981         (-C8) * RST * RM1  * SP1  * TP1 * fdata[24] +
01982         ( C4) * ST  * RSQ  * SP1  * TP1 * fdata[25] +
01983         ( C8) * RST * RP1  * SP1  * TP1 * fdata[26]   ;
01984      return triquad;
01985 }
01986 
01987 Util::sincBlackman::sincBlackman(int M_, float fc_, int ntable_)
01988                 : M(M_), fc(fc_), ntable(ntable_) {
01989         // Sinc-Blackman kernel
01990         build_sBtable();
01991 }
01992 
01993 void Util::sincBlackman::build_sBtable() {
01994         sBtable.resize(ntable+1);
01995         int ltab = int(round(float(ntable)/1.25f));
01996         int M2 = M/2;
01997         fltb = float(ltab)/M2;
01998         for (int i=ltab+1; i <= ntable; i++) sBtable[i] = 0.0f;
01999         float x = 1.0e-7f;
02000         sBtable[0] = (float)(sin(twopi*fc*x)/x*(0.52-0.5*cos(twopi*(x-M2)/M)+0.08*cos(2*twopi*(x-M2)/M)));
02001         for (int i=1; i <= ltab; i++) {
02002                 x = float(i)/fltb;
02003                 sBtable[i] = (float)(sin(twopi*fc*x)/x*(0.52-0.5*cos(twopi*(x-M2)/M)+0.08*cos(2*twopi*(x-M2)/M)));
02004                 //cout << "  "<<x<<"  "<<sBtable[i] <<endl;
02005         }
02006 }
02007 
02008 Util::KaiserBessel::KaiserBessel(float alpha_, int K_, float r_, float v_,
02009                                          int N_, float vtable_, int ntable_)
02010                 : alpha(alpha_), v(v_), r(r_), N(N_), K(K_), vtable(vtable_),
02011                   ntable(ntable_) {
02012         // Default values are alpha=1.25, K=6, r=0.5, v = K/2
02013         if (0.f == v) v = float(K)/2;
02014         if (0.f == vtable) vtable = v;
02015         alphar = alpha*r;
02016         fac = static_cast<float>(twopi)*alphar*v;
02017         vadjust = 1.0f*v;
02018         facadj = static_cast<float>(twopi)*alphar*vadjust;
02019         build_I0table();
02020 }
02021 
02022 float Util::KaiserBessel::i0win(float x) const {
02023         float val0 = float(gsl_sf_bessel_I0(facadj));
02024         float absx = fabs(x);
02025         if (absx > vadjust) return 0.f;
02026         float rt = sqrt(1.f - pow(absx/vadjust, 2));
02027         float res = static_cast<float>(gsl_sf_bessel_I0(facadj*rt))/val0;
02028         return res;
02029 }
02030 
02031 void Util::KaiserBessel::build_I0table() {
02032         i0table.resize(ntable+1); // i0table[0:ntable]
02033         int ltab = int(round(float(ntable)/1.25f));
02034         fltb = float(ltab)/(K/2);
02035         float val0 = static_cast<float>(gsl_sf_bessel_I0(facadj));
02036         for (int i=ltab+1; i <= ntable; i++) i0table[i] = 0.f;
02037         for (int i=0; i <= ltab; i++) {
02038                 float s = float(i)/fltb/N;
02039                 if (s < vadjust) {
02040                         float rt = sqrt(1.f - pow(s/vadjust, 2));
02041                         i0table[i] = static_cast<float>(gsl_sf_bessel_I0(facadj*rt))/val0;
02042                 } else {
02043                         i0table[i] = 0.f;
02044                 }
02045 //              cout << "  "<<s*N<<"  "<<i0table[i] <<endl;
02046         }
02047 }
02048 
02049 float Util::KaiserBessel::I0table_maxerror() {
02050         float maxdiff = 0.f;
02051         for (int i = 1; i <= ntable; i++) {
02052                 float diff = fabs(i0table[i] - i0table[i-1]);
02053                 if (diff > maxdiff) maxdiff = diff;
02054         }
02055         return maxdiff;
02056 }
02057 
02058 float Util::KaiserBessel::sinhwin(float x) const {
02059         float val0 = sinh(fac)/fac;
02060         float absx = fabs(x);
02061         if (0.0 == x) {
02062                 float res = 1.0f;
02063                 return res;
02064         } else if (absx == alphar) {
02065                 return 1.0f/val0;
02066         } else if (absx < alphar) {
02067                 float rt = sqrt(1.0f - pow((x/alphar), 2));
02068                 float facrt = fac*rt;
02069                 float res = (sinh(facrt)/facrt)/val0;
02070                 return res;
02071         } else {
02072                 float rt = sqrt(pow((x/alphar),2) - 1.f);
02073                 float facrt = fac*rt;
02074                 float res = (sin(facrt)/facrt)/val0;
02075                 return res;
02076         }
02077 }
02078 
02079 float Util::FakeKaiserBessel::i0win(float x) const {
02080         float val0 = sqrt(facadj)*float(gsl_sf_bessel_I1(facadj));
02081         float absx = fabs(x);
02082         if (absx > vadjust) return 0.f;
02083         float rt = sqrt(1.f - pow(absx/vadjust, 2));
02084         float res = sqrt(facadj*rt)*float(gsl_sf_bessel_I1(facadj*rt))/val0;
02085         return res;
02086 }
02087 
02088 void Util::FakeKaiserBessel::build_I0table() {
02089         i0table.resize(ntable+1); // i0table[0:ntable]
02090         int ltab = int(round(float(ntable)/1.1f));
02091         fltb = float(ltab)/(K/2);
02092         float val0 = sqrt(facadj)*static_cast<float>(gsl_sf_bessel_I1(facadj));
02093         for (int i=ltab+1; i <= ntable; i++) i0table[i] = 0.f;
02094         for (int i=0; i <= ltab; i++) {
02095                 float s = float(i)/fltb/N;
02096                 if (s < vadjust) {
02097                         float rt = sqrt(1.f - pow(s/vadjust, 2));
02098                         i0table[i] = sqrt(facadj*rt)*static_cast<float>(gsl_sf_bessel_I1(facadj*rt))/val0;
02099                 } else {
02100                         i0table[i] = 0.f;
02101                 }
02102         }
02103 }
02104 
02105 float Util::FakeKaiserBessel::sinhwin(float x) const {
02106         float val0 = sinh(fac)/fac;
02107         float absx = fabs(x);
02108         if (0.0 == x) {
02109                 float res = 1.0f;
02110                 return res;
02111         } else if (absx == alphar) {
02112                 return 1.0f/val0;
02113         } else if (absx < alphar) {
02114                 float rt = sqrt(1.0f - pow((x/alphar), 2));
02115                 float facrt = fac*rt;
02116                 float res = (sinh(facrt)/facrt)/val0;
02117                 return res;
02118         } else {
02119                 float rt = sqrt(pow((x/alphar),2) - 1.f);
02120                 float facrt = fac*rt;
02121                 float res = (sin(facrt)/facrt)/val0;
02122                 return res;
02123         }
02124 }
02125 
02126 #if 0 // 1-st order KB window
02127 float Util::FakeKaiserBessel::sinhwin(float x) const {
02128         //float val0 = sinh(fac)/fac;
02129         float prefix = 2*facadj*vadjust/float(gsl_sf_bessel_I1(facadj));
02130         float val0 = prefix*(cosh(facadj) - sinh(facadj)/facadj);
02131         float absx = fabs(x);
02132         if (0.0 == x) {
02133                 //float res = 1.0f;
02134                 float res = val0;
02135                 return res;
02136         } else if (absx == alphar) {
02137                 //return 1.0f/val0;
02138                 return prefix;
02139         } else if (absx < alphar) {
02140                 float rt = sqrt(1.0f - pow((x/alphar), 2));
02141                 //float facrt = fac*rt;
02142                 float facrt = facadj*rt;
02143                 //float res = (sinh(facrt)/facrt)/val0;
02144                 float res = prefix*(cosh(facrt) - sinh(facrt)/facrt);
02145                 return res;
02146         } else {
02147                 float rt = sqrt(pow((x/alphar),2) - 1.f);
02148                 //float facrt = fac*rt;
02149                 float facrt = facadj*rt;
02150                 //float res = (sin(facrt)/facrt)/val0;
02151                 float res = prefix*(sin(facrt)/facrt - cos(facrt));
02152                 return res;
02153         }
02154 }
02155 #endif // 0
02156 
02157 
02158 
02159 #define  circ(i)         circ[i-1]
02160 #define  numr(i,j)       numr[(j-1)*3 + i-1]
02161 #define  xim(i,j)        xim[(j-1)*nsam + i-1]
02162 
02163 EMData* Util::Polar2D(EMData* image, vector<int> numr, string cmode){
02164         int nsam = image->get_xsize();
02165         int nrow = image->get_ysize();
02166         int nring = numr.size()/3;
02167         int lcirc = numr[3*nring-2]+numr[3*nring-1]-1;
02168         EMData* out = new EMData();
02169         out->set_size(lcirc,1,1);
02170         char mode = (cmode == "F" || cmode == "f") ? 'f' : 'h';
02171         float *xim  = image->get_data();
02172         float *circ = out->get_data();
02173 /*   alrq(image->get_data(), nsam, nrow, &numr[0], out->get_data(), lcirc, nring, cmode);
02174    return out;
02175 }
02176 void Util::alrq(float *xim,  int nsam , int nrow , int *numr,
02177           float *circ, int lcirc, int nring, char mode)
02178 {*/
02179 /*
02180 c
02181 c  purpose:
02182 c
02183 c  resmaple to polar coordinates
02184 c
02185 */
02186         //  dimension         xim(nsam,nrow),circ(lcirc)
02187         //  integer           numr(3,nring)
02188 
02189         double dfi, dpi;
02190         int    ns2, nr2, i, inr, l, nsim, kcirc, lt, j;
02191         float  yq, xold, yold, fi, x, y;
02192 
02193         ns2 = nsam/2+1;
02194         nr2 = nrow/2+1;
02195         dpi = 2.0*atan(1.0);
02196 
02197         for (i=1;i<=nring;i++) {
02198                 // radius of the ring
02199                 inr = numr(1,i);
02200                 yq  = static_cast<float>(inr);
02201                 l   = numr(3,i);
02202                 if (mode == 'h' || mode == 'H')  lt = l/2;
02203                 else                             lt = l/4;
02204 
02205                 nsim           = lt-1;
02206                 dfi            = dpi/(nsim+1);
02207                 kcirc          = numr(2,i);
02208                 xold           = 0.0f;
02209                 yold           = static_cast<float>(inr);
02210                 circ(kcirc)    = quadri(xold+(float)ns2,yold+(float)nr2,nsam,nrow,xim);
02211                 xold           = static_cast<float>(inr);
02212                 yold           = 0.0f;
02213                 circ(lt+kcirc) = quadri(xold+ns2,yold+nr2,nsam,nrow,xim);
02214 
02215                 if (mode == 'f' || mode == 'F') {
02216                         xold              = 0.0f;
02217                         yold              = static_cast<float>(-inr);
02218                         circ(lt+lt+kcirc) = quadri(xold+ns2,yold+nr2,nsam,nrow,xim);
02219                         xold              = static_cast<float>(-inr);
02220                         yold              = 0.0f;
02221                         circ(lt+lt+lt+kcirc) = quadri(xold+ns2,yold+nr2,nsam,nrow,xim);
02222                 }
02223 
02224                 for (j=1;j<=nsim;j++) {
02225                         fi               = static_cast<float>(dfi*j);
02226                         x                = sin(fi)*yq;
02227                         y                = cos(fi)*yq;
02228                         xold             = x;
02229                         yold             = y;
02230                         circ(j+kcirc)    = quadri(xold+ns2,yold+nr2,nsam,nrow,xim);
02231                         xold             =  y;
02232                         yold             = -x;
02233                         circ(j+lt+kcirc) = quadri(xold+ns2,yold+nr2,nsam,nrow,xim);
02234 
02235                         if (mode == 'f' || mode == 'F')  {
02236                                 xold                = -x;
02237                                 yold                = -y;
02238                                 circ(j+lt+lt+kcirc) = quadri(xold+ns2,yold+nr2,nsam,nrow,xim);
02239                                 xold                = -y;
02240                                 yold                =  x;
02241                                 circ(j+lt+lt+lt+kcirc) = quadri(xold+ns2,yold+nr2,nsam,nrow,xim);
02242                         }
02243                 }
02244         }
02245         return  out;
02246 }
02247 
02248 EMData* Util::Polar2Dm(EMData* image, float cns2, float cnr2, vector<int> numr, string cmode){
02249         int nsam = image->get_xsize();
02250         int nrow = image->get_ysize();
02251         int nring = numr.size()/3;
02252         int lcirc = numr[3*nring-2]+numr[3*nring-1]-1;
02253         EMData* out = new EMData();
02254         out->set_size(lcirc,1,1);
02255         char mode = (cmode == "F" || cmode == "f") ? 'f' : 'h';
02256         float *xim  = image->get_data();
02257         float *circ = out->get_data();
02258         double dpi, dfi;
02259         int    it, jt, inr, l, nsim, kcirc, lt;
02260         float  xold, yold, fi, x, y;
02261 
02262         //     cns2 and cnr2 are predefined centers
02263         //     no need to set to zero, all elements are defined
02264         dpi = 2*atan(1.0);
02265         for (it=1; it<=nring; it++) {
02266                 // radius of the ring
02267                 inr = numr(1,it);
02268 
02269                 // "F" means a full circle interpolation
02270                 // "H" means a half circle interpolation
02271 
02272                 l = numr(3,it);
02273                 if ( mode == 'h' || mode == 'H' ) lt = l / 2;
02274                 else                              lt = l / 4;
02275 
02276                 nsim  = lt - 1;
02277                 dfi   = dpi / (nsim+1);
02278                 kcirc = numr(2,it);
02279                 xold  = 0.0f+cns2;
02280                 yold  = inr+cnr2;
02281 
02282                 Assert( kcirc <= lcirc );
02283                 circ(kcirc) = quadri(xold,yold,nsam,nrow,xim);    // Sampling on 90 degree
02284 
02285                 xold  = inr+cns2;
02286                 yold  = 0.0f+cnr2;
02287                 Assert( lt+kcirc <= lcirc );
02288                 circ(lt+kcirc) = quadri(xold,yold,nsam,nrow,xim);  // Sampling on 0 degree
02289 
02290                 if ( mode == 'f' || mode == 'F' ) {
02291                         xold = 0.0f+cns2;
02292                         yold = -inr+cnr2;
02293                         Assert( lt+lt+kcirc <= lcirc );
02294                         circ(lt+lt+kcirc) = quadri(xold,yold,nsam,nrow,xim);  // Sampling on 270 degree
02295 
02296                         xold = -inr+cns2;
02297                         yold = 0.0f+cnr2;
02298                         Assert(lt+lt+lt+kcirc <= lcirc );
02299                         circ(lt+lt+lt+kcirc) = quadri(xold,yold,nsam,nrow,xim); // Sampling on 180 degree
02300                 }
02301 
02302                 for (jt=1; jt<=nsim; jt++) {
02303                         fi   = static_cast<float>(dfi * jt);
02304                         x    = sin(fi) * inr;
02305                         y    = cos(fi) * inr;
02306 
02307                         xold = x+cns2;
02308                         yold = y+cnr2;
02309 
02310                         Assert( jt+kcirc <= lcirc );
02311                         circ(jt+kcirc) = quadri(xold,yold,nsam,nrow,xim);      // Sampling on the first quadrant
02312 
02313                         xold = y+cns2;
02314                         yold = -x+cnr2;
02315 
02316                         Assert( jt+lt+kcirc <= lcirc );
02317                         circ(jt+lt+kcirc) = quadri(xold,yold,nsam,nrow,xim);    // Sampling on the fourth quadrant
02318 
02319                         if ( mode == 'f' || mode == 'F' ) {
02320                                 xold = -x+cns2;
02321                                 yold = -y+cnr2;
02322 
02323                                 Assert( jt+lt+lt+kcirc <= lcirc );
02324                                 circ(jt+lt+lt+kcirc) = quadri(xold,yold,nsam,nrow,xim); // Sampling on the third quadrant
02325 
02326                                 xold = -y+cns2;
02327                                 yold = x+cnr2;
02328 
02329                                 Assert( jt+lt+lt+lt+kcirc <= lcirc );
02330                                 circ(jt+lt+lt+lt+kcirc) = quadri(xold,yold,nsam,nrow,xim);  // Sampling on the second quadrant
02331                         }
02332                 } // end for jt
02333         } //end for it
02334         return out;
02335 }
02336 
02337 float Util::bilinear(float xold, float yold, int nsam, int nrow, float* xim)
02338 {
02339 /*
02340 c  purpose: linear interpolation
02341   Optimized for speed, circular closer removed, checking of ranges removed
02342 */
02343     float bilinear;
02344     int   ixold, iyold;
02345 
02346 /*
02347         float xdif, ydif, xrem, yrem;
02348         ixold   = (int) floor(xold);
02349         iyold   = (int) floor(yold);
02350         ydif = yold - iyold;
02351         yrem = 1.0f - ydif;
02352 
02353         //  May want to insert if?
02354 //              IF ((IYOLD .GE. 1 .AND. IYOLD .LE. NROW-1) .AND.
02355 //     &            (IXOLD .GE. 1 .AND. IXOLD .LE. NSAM-1)) THEN
02356 //c                INSIDE BOUNDARIES OF OUTPUT IMAGE
02357         xdif = xold - ixold;
02358         xrem = 1.0f- xdif;
02359 //                 RBUF(K) = YDIF*(BUF(NADDR+NSAM)*XREM
02360 //     &                    +BUF(NADDR+NSAM+1)*XDIF)
02361 //     &                    +YREM*(BUF(NADDR)*XREM + BUF(NADDR+1)*XDIF)
02362         bilinear = ydif*(xim(ixold,iyold+1)*xrem + xim(ixold+1,iyold+1)*xdif) +
02363                                         yrem*(xim(ixold,iyold)*xrem+xim(ixold+1,iyold)*xdif);
02364 
02365     return bilinear;
02366 }
02367 */
02368         float xdif, ydif;
02369 
02370         ixold   = (int) xold;
02371         iyold   = (int) yold;
02372         ydif = yold - iyold;
02373 
02374         //  May want to insert it?
02375 //              IF ((IYOLD .GE. 1 .AND. IYOLD .LE. NROW-1) .AND.
02376 //     &            (IXOLD .GE. 1 .AND. IXOLD .LE. NSAM-1)) THEN
02377 //c                INSIDE BOUNDARIES OF OUTPUT IMAGE
02378         xdif = xold - ixold;
02379         bilinear = xim(ixold, iyold) + ydif* (xim(ixold, iyold+1) - xim(ixold, iyold)) +
02380                    xdif* (xim(ixold+1, iyold) - xim(ixold, iyold) +
02381                            ydif* (xim(ixold+1, iyold+1) - xim(ixold+1, iyold) - xim(ixold, iyold+1) + xim(ixold, iyold)) );
02382 
02383         return bilinear;
02384 }
02385 
02386 void Util::alrl_ms(float *xim, int    nsam, int  nrow, float cns2, float cnr2,
02387              int  *numr, float *circ, int , int  nring, char  mode) {
02388         double dpi, dfi;
02389         int    it, jt, inr, l, nsim, kcirc, lt;
02390         float   xold, yold, fi, x, y;
02391 
02392         //     cns2 and cnr2 are predefined centers
02393         //     no need to set to zero, all elements are defined
02394 
02395         dpi = 2*atan(1.0);
02396         for (it=1; it<=nring; it++) {
02397                 // radius of the ring
02398                 inr = numr(1,it);
02399 
02400                 l = numr(3,it);
02401                 if ( mode == 'h' || mode == 'H' ) lt = l / 2;
02402                 else                              lt = l / 4;
02403 
02404                 nsim  = lt - 1;
02405                 dfi   = dpi / (nsim+1);
02406                 kcirc = numr(2,it);
02407 
02408 
02409                 xold  = 0.0f+cns2;
02410                 yold  = inr+cnr2;
02411 
02412                 circ(kcirc) = quadri(xold,yold,nsam,nrow,xim);
02413 
02414                 xold  = inr+cns2;
02415                 yold  = 0.0f+cnr2;
02416                 circ(lt+kcirc) = quadri(xold,yold,nsam,nrow,xim);
02417 
02418                 if ( mode == 'f' || mode == 'F' ) {
02419                         xold = 0.0f+cns2;
02420                         yold = -inr+cnr2;
02421                         circ(lt+lt+kcirc) = quadri(xold,yold,nsam,nrow,xim);
02422 
02423                         xold = -inr+cns2;
02424                         yold = 0.0f+cnr2;
02425                         circ(lt+lt+lt+kcirc) = quadri(xold,yold,nsam,nrow,xim);
02426                 }
02427 
02428                 for (jt=1; jt<=nsim; jt++) {
02429                         fi   = static_cast<float>(dfi * jt);
02430                         x    = sin(fi) * inr;
02431                         y    = cos(fi) * inr;
02432 
02433                         xold = x+cns2;
02434                         yold = y+cnr2;
02435                         circ(jt+kcirc) = quadri(xold,yold,nsam,nrow,xim);
02436 
02437                         xold = y+cns2;
02438                         yold = -x+cnr2;
02439                         circ(jt+lt+kcirc) = quadri(xold,yold,nsam,nrow,xim);
02440 
02441                         if ( mode == 'f' || mode == 'F' ) {
02442                                 xold = -x+cns2;
02443                                 yold = -y+cnr2;
02444                                 circ(jt+lt+lt+kcirc) = quadri(xold,yold,nsam,nrow,xim);
02445 
02446                                 xold = -y+cns2;
02447                                 yold = x+cnr2;
02448                                 circ(jt+lt+lt+lt+kcirc) = quadri(xold,yold,nsam,nrow,xim);
02449                         }
02450                 } // end for jt
02451         } //end for it
02452 }
02453 /*
02454 void Util::alrl_ms(float *xim, int    nsam, int  nrow, float cns2, float cnr2,
02455              int  *numr, float *circ, int lcirc, int  nring, char  mode)
02456 {
02457    double dpi, dfi;
02458    int    it, jt, inr, l, nsim, kcirc, lt, xold, yold;
02459    float  yq, fi, x, y;
02460 
02461    //     cns2 and cnr2 are predefined centers
02462    //     no need to set to zero, all elements are defined
02463 
02464    dpi = 2*atan(1.0);
02465    for (it=1; it<=nring; it++) {
02466       // radius of the ring
02467       inr = numr(1,it);
02468       yq  = inr;
02469 
02470       l = numr(3,it);
02471       if ( mode == 'h' || mode == 'H' ) {
02472          lt = l / 2;
02473       }
02474       else { // if ( mode == 'f' || mode == 'F' )
02475          lt = l / 4;
02476       }
02477 
02478       nsim  = lt - 1;
02479       dfi   = dpi / (nsim+1);
02480       kcirc = numr(2,it);
02481 
02482 
02483         xold = (int) (0.0+cns2);
02484         yold = (int) (inr+cnr2);
02485 
02486         circ(kcirc) = xim(xold, yold);
02487 
02488       xold = (int) (inr+cns2);
02489       yold = (int) (0.0+cnr2);
02490       circ(lt+kcirc) = xim(xold, yold);
02491 
02492       if ( mode == 'f' || mode == 'F' ) {
02493          xold  = (int) (0.0+cns2);
02494          yold = (int) (-inr+cnr2);
02495          circ(lt+lt+kcirc) = xim(xold, yold);
02496 
02497          xold  = (int) (-inr+cns2);
02498          yold = (int) (0.0+cnr2);
02499          circ(lt+lt+lt+kcirc) = xim(xold, yold);
02500       }
02501 
02502       for (jt=1; jt<=nsim; jt++) {
02503          fi   = dfi * jt;
02504          x    = sin(fi) * yq;
02505          y    = cos(fi) * yq;
02506 
02507          xold  = (int) (x+cns2);
02508          yold = (int) (y+cnr2);
02509          circ(jt+kcirc) = xim(xold, yold);
02510 
02511          xold  = (int) (y+cns2);
02512          yold = (int) (-x+cnr2);
02513          circ(jt+lt+kcirc) = xim(xold, yold);
02514 
02515          if ( mode == 'f' || mode == 'F' ) {
02516             xold  = (int) (-x+cns2);
02517             yold = (int) (-y+cnr2);
02518             circ(jt+lt+lt+kcirc) = xim(xold, yold);
02519 
02520             xold  = (int) (-y+cns2);
02521             yold = (int) (x+cnr2);
02522             circ(jt+lt+lt+lt+kcirc) = xim(xold, yold);
02523          }
02524       } // end for jt
02525    } //end for it
02526 }
02527 */
02528 //xim((int) floor(xold), (int) floor(yold))
02529 #undef  xim
02530 
02531 EMData* Util::Polar2Dmi(EMData* image, float cns2, float cnr2, vector<int> numr, string cmode, Util::KaiserBessel& kb){
02532 // input image is twice the size of the original image
02533         int nring = numr.size()/3;
02534         int lcirc = numr[3*nring-2]+numr[3*nring-1]-1;
02535         EMData* out = new EMData();
02536         out->set_size(lcirc,1,1);
02537         char mode = (cmode == "F" || cmode == "f") ? 'f' : 'h';
02538         float *circ = out->get_data();
02539         float *fimage = image->get_data();
02540         int nx = image->get_xsize();
02541         int ny = image->get_ysize();
02542         int nz = image->get_zsize();
02543         double dpi, dfi;
02544         int    it, jt, inr, l, nsim, kcirc, lt;
02545         float  yq, xold, yold, fi, x, y;
02546 
02547         //     cns2 and cnr2 are predefined centers
02548         //     no need to set to zero, all elements are defined
02549 
02550         dpi = 2*atan(1.0);
02551         for (it=1;it<=nring;it++) {
02552                 // radius of the ring
02553                 inr = numr(1,it);
02554                 yq  = static_cast<float>(inr);
02555 
02556                 l = numr(3,it);
02557                 if ( mode == 'h' || mode == 'H' )  lt = l / 2;
02558                 else                               lt = l / 4;
02559 
02560                 nsim  = lt - 1;
02561                 dfi   = dpi / (nsim+1);
02562                 kcirc = numr(2,it);
02563                 xold  = 0.0f;
02564                 yold  = static_cast<float>(inr);
02565                 circ(kcirc) = get_pixel_conv_new(nx,ny,nz,2*(xold+cns2-1.0f),2*(yold+cnr2-1.0f),0,fimage,kb);
02566 //      circ(kcirc) = image->get_pixel_conv(2*(xold+cns2-1.0f),2*(yold+cnr2-1.0f),0,kb);
02567 
02568                 xold  = static_cast<float>(inr);
02569                 yold  = 0.0f;
02570                 circ(lt+kcirc) = get_pixel_conv_new(nx,ny,nz,2*(xold+cns2-1.0f),2*(yold+cnr2-1.0f),0,fimage,kb);
02571 //      circ(lt+kcirc) = image->get_pixel_conv(2*(xold+cns2-1.0f),2*(yold+cnr2-1.0f),0,kb);
02572 
02573         if ( mode == 'f' || mode == 'F' ) {
02574                 xold = 0.0f;
02575                 yold = static_cast<float>(-inr);
02576                 circ(lt+lt+kcirc) = get_pixel_conv_new(nx,ny,nz,2*(xold+cns2-1.0f),2*(yold+cnr2-1.0f),0,fimage,kb);
02577 //         circ(lt+lt+kcirc) = image->get_pixel_conv(2*(xold+cns2-1.0f),2*(yold+cnr2-1.0f),0,kb);
02578 
02579                 xold = static_cast<float>(-inr);
02580                 yold = 0.0f;
02581                 circ(lt+lt+lt+kcirc) = get_pixel_conv_new(nx,ny,nz,2*(xold+cns2-1.0f),2*(yold+cnr2-1.0f),0,fimage,kb);
02582 //         circ(lt+lt+lt+kcirc) = image->get_pixel_conv(2*(xold+cns2-1.0f),2*(yold+cnr2-1.0f),0,kb);
02583         }
02584 
02585         for (jt=1;jt<=nsim;jt++) {
02586                 fi   = static_cast<float>(dfi * jt);
02587                 x    = sin(fi) * yq;
02588                 y    = cos(fi) * yq;
02589 
02590                 xold = x;
02591                 yold = y;
02592                 circ(jt+kcirc) = get_pixel_conv_new(nx,ny,nz,2*(xold+cns2-1.0f),2*(yold+cnr2-1.0f),0,fimage,kb);
02593 //         circ(jt+kcirc) = image->get_pixel_conv(2*(xold+cns2-1.0f),2*(yold+cnr2-1.0f),0,kb);
02594 
02595                 xold = y;
02596                 yold = -x;
02597                 circ(jt+lt+kcirc) = get_pixel_conv_new(nx,ny,nz,2*(xold+cns2-1.0f),2*(yold+cnr2-1.0f),0,fimage,kb);
02598 //         circ(jt+lt+kcirc) = image->get_pixel_conv(2*(xold+cns2-1.0f),2*(yold+cnr2-1.0f),0,kb);
02599 
02600         if ( mode == 'f' || mode == 'F' ) {
02601                 xold = -x;
02602                 yold = -y;
02603                 circ(jt+lt+lt+kcirc) = get_pixel_conv_new(nx,ny,nz,2*(xold+cns2-1.0f),2*(yold+cnr2-1.0f),0,fimage,kb);
02604 //            circ(jt+lt+lt+kcirc) = image->get_pixel_conv(2*(xold+cns2-1.0f),2*(yold+cnr2-1.0f),0,kb);
02605 
02606                 xold = -y;
02607                 yold = x;
02608                 circ(jt+lt+lt+lt+kcirc) = get_pixel_conv_new(nx,ny,nz,2*(xold+cns2-1.0f),2*(yold+cnr2-1.0f),0,fimage,kb);
02609 //            circ(jt+lt+lt+lt+kcirc) = image->get_pixel_conv(2*(xold+cns2-1.0f),2*(yold+cnr2-1.0f),0,kb);
02610         }
02611         } // end for jt
02612         } //end for it
02613         return  out;
02614 }
02615 
02616 /*
02617 
02618         A set of 1-D power-of-two FFTs
02619         Pawel & Chao 01/20/06
02620 
02621 fftr_q(xcmplx,nv)
02622   single precision
02623 
02624  dimension xcmplx(2,iabs(nv)/2);
02625  xcmplx(1,1) --- R(0), xcmplx(2,1) --- R(NV/2)
02626  xcmplx(1,i) --- real, xcmplx(2,i) --- imaginary
02627 
02628 
02629 fftr_d(xcmplx,nv)
02630   double precision
02631 
02632  dimension xcmplx(2,iabs(nv)/2);
02633  xcmplx(1,1) --- R(0), xcmplx(2,1) --- R(NV/2)
02634  xcmplx(1,i) --- real, xcmplx(2,i) --- imaginary
02635 
02636 
02637 
02638 */
02639 #define  tab1(i)      tab1[i-1]
02640 #define  xcmplx(i,j)  xcmplx [(j-1)*2 + i-1]
02641 #define  br(i)        br[i-1]
02642 #define  bi(i)        bi[i-1]
02643 //-----------------------------------------
02644 void Util::fftc_d(double *br, double *bi, int ln, int ks)
02645 {
02646         double rni,sgn,tr1,tr2,ti1,ti2;
02647         double cc,c,ss,s,t,x2,x3,x4,x5;
02648         int    b3,b4,b5,b6,b7,b56;
02649         int    n, k, l, j, i, ix0, ix1, status=0;
02650 
02651         const double tab1[] = {
02652                 9.58737990959775e-5,
02653                 1.91747597310703e-4,
02654                 3.83495187571395e-4,
02655                 7.66990318742704e-4,
02656                 1.53398018628476e-3,
02657                 3.06795676296598e-3,
02658                 6.13588464915449e-3,
02659                 1.22715382857199e-2,
02660                 2.45412285229123e-2,
02661                 4.90676743274181e-2,
02662                 9.80171403295604e-2,
02663                 1.95090322016128e-1,
02664                 3.82683432365090e-1,
02665                 7.07106781186546e-1,
02666                 1.00000000000000,
02667         };
02668 
02669         n=(int)pow(2.0f,ln);
02670 
02671         k=abs(ks);
02672         l=16-ln;
02673         b3=n*k;
02674         b6=b3;
02675         b7=k;
02676         if (ks > 0) {
02677                 sgn=1.0f;
02678         } else {
02679                 sgn=-1.0f;
02680                 rni=1.0f/(float)(n);
02681                 j=1;
02682                 for (i=1; i<=n; i++) {
02683                         br(j)=br(j)*rni;
02684                         bi(j)=bi(j)*rni;
02685                         j=j+k;
02686                 }
02687         }
02688 
02689 L12:
02690    b6=b6/2;
02691    b5=b6;
02692    b4=2*b6;
02693    b56=b5-b6;
02694 
02695 L14:
02696    tr1=br(b5+1);
02697    ti1=bi(b5+1);
02698    tr2=br(b56+1);
02699    ti2=bi(b56+1);
02700 
02701    br(b5+1)=tr2-tr1;
02702    bi(b5+1)=ti2-ti1;
02703    br(b56+1)=tr1+tr2;
02704    bi(b56+1)=ti1+ti2;
02705 
02706    b5=b5+b4;
02707    b56=b5-b6;
02708    if ( b5 <= b3 )  goto  L14;
02709    if ( b6 == b7 )  goto  L20;
02710 
02711    b4=b7;
02712    cc=2.0f*pow(tab1(l),2);
02713    c=1.0f-cc;
02714    l++;
02715    ss=sgn*tab1(l);
02716    s=ss;
02717 
02718 L16:
02719    b5=b6+b4;
02720    b4=2*b6;
02721    b56=b5-b6;
02722 
02723 L18:
02724    tr1=br(b5+1);
02725    ti1=bi(b5+1);
02726    tr2=br(b56+1);
02727    ti2=bi(b56+1);
02728    br(b5+1)=c*(tr2-tr1)-s*(ti2-ti1);
02729    bi(b5+1)=s*(tr2-tr1)+c*(ti2-ti1);
02730    br(b56+1)=tr1+tr2;
02731    bi(b56+1)=ti1+ti2;
02732 
02733    b5=b5+b4;
02734    b56=b5-b6;
02735    if ( b5 <= b3 )  goto  L18;
02736    b4=b5-b6;
02737    b5=b4-b3;
02738    c=-c;
02739    b4=b6-b5;
02740    if ( b5 < b4 )  goto  L16;
02741    b4=b4+b7;
02742    if ( b4 >= b5 ) goto  L12;
02743 
02744    t=c-cc*c-ss*s;
02745    s=s+ss*c-cc*s;
02746    c=t;
02747    goto  L16;
02748 
02749 L20:
02750    ix0=b3/2;
02751    b3=b3-b7;
02752    b4=0;
02753    b5=0;
02754    b6=ix0;
02755    ix1=0;
02756    if (b6 == b7) goto EXIT;
02757 
02758 L22:
02759    b4=b3-b4;
02760    b5=b3-b5;
02761    x2=br(b4+1);
02762    x3=br(b5+1);
02763    x4=bi(b4+1);
02764    x5=bi(b5+1);
02765    br(b4+1)=x3;
02766    br(b5+1)=x2;
02767    bi(b4+1)=x5;
02768    bi(b5+1)=x4;
02769    if(b6 < b4)  goto  L22;
02770 
02771 L24:
02772    b4=b4+b7;
02773    b5=b6+b5;
02774    x2=br(b4+1);
02775    x3=br(b5+1);
02776    x4=bi(b4+1);
02777    x5=bi(b5+1);
02778    br(b4+1)=x3;
02779    br(b5+1)=x2;
02780    bi(b4+1)=x5;
02781    bi(b5+1)=x4;
02782    ix0=b6;
02783 
02784 L26:
02785    ix0=ix0/2;
02786    ix1=ix1-ix0;
02787    if( ix1 >= 0)  goto L26;
02788 
02789    ix0=2*ix0;
02790    b4=b4+b7;
02791    ix1=ix1+ix0;
02792    b5=ix1;
02793    if ( b5 >= b4)  goto  L22;
02794    if ( b4 < b6)   goto  L24;
02795 
02796 EXIT:
02797    status = 0;
02798 }
02799 
02800 // -----------------------------------------------------------------
02801 void Util::fftc_q(float *br, float *bi, int ln, int ks)
02802 {
02803         //  dimension  br(1),bi(1)
02804 
02805         int b3,b4,b5,b6,b7,b56;
02806         int n, k, l, j, i, ix0, ix1;
02807         float rni, tr1, ti1, tr2, ti2, cc, c, ss, s, t, x2, x3, x4, x5, sgn;
02808         int status=0;
02809 
02810         const float tab1[] = {
02811                 9.58737990959775e-5f,
02812                 1.91747597310703e-4f,
02813                 3.83495187571395e-4f,
02814                 7.66990318742704e-4f,
02815                 1.53398018628476e-3f,
02816                 3.06795676296598e-3f,
02817                 6.13588464915449e-3f,
02818                 1.22715382857199e-2f,
02819                 2.45412285229123e-2f,
02820                 4.90676743274181e-2f,
02821                 9.80171403295604e-2f,
02822                 1.95090322016128e-1f,
02823                 3.82683432365090e-1f,
02824                 7.07106781186546e-1f,
02825                 1.00000000000000f,
02826         };
02827 
02828         n=(int)pow(2.0f,ln);
02829 
02830         k=abs(ks);
02831         l=16-ln;
02832         b3=n*k;
02833         b6=b3;
02834         b7=k;
02835         if( ks > 0 ) {
02836                 sgn=1.0f;
02837         } else {
02838                 sgn=-1.0f;
02839                 rni=1.0f/(float)n;
02840                 j=1;
02841                 for (i=1; i<=n; i++) {
02842                         br(j)=br(j)*rni;
02843                         bi(j)=bi(j)*rni;
02844                         j=j+k;
02845                 }
02846         }
02847 L12:
02848    b6=b6/2;
02849    b5=b6;
02850    b4=2*b6;
02851    b56=b5-b6;
02852 L14:
02853    tr1=br(b5+1);
02854    ti1=bi(b5+1);
02855 
02856    tr2=br(b56+1);
02857    ti2=bi(b56+1);
02858 
02859    br(b5+1)=tr2-tr1;
02860    bi(b5+1)=ti2-ti1;
02861    br(b56+1)=tr1+tr2;
02862    bi(b56+1)=ti1+ti2;
02863 
02864    b5=b5+b4;
02865    b56=b5-b6;
02866    if ( b5 <= b3 )  goto  L14;
02867    if ( b6 == b7 )  goto  L20;
02868 
02869    b4=b7;
02870    cc=2.0f*pow(tab1(l),2);
02871    c=1.0f-cc;
02872    l++;
02873    ss=sgn*tab1(l);
02874    s=ss;
02875 L16:
02876    b5=b6+b4;
02877    b4=2*b6;
02878    b56=b5-b6;
02879 L18:
02880    tr1=br(b5+1);
02881    ti1=bi(b5+1);
02882    tr2=br(b56+1);
02883    ti2=bi(b56+1);
02884    br(b5+1)=c*(tr2-tr1)-s*(ti2-ti1);
02885    bi(b5+1)=s*(tr2-tr1)+c*(ti2-ti1);
02886    br(b56+1)=tr1+tr2;
02887    bi(b56+1)=ti1+ti2;
02888 
02889    b5=b5+b4;
02890    b56=b5-b6;
02891    if(b5 <= b3)  goto L18;
02892    b4=b5-b6;
02893    b5=b4-b3;
02894    c=-c;
02895    b4=b6-b5;
02896    if(b5 < b4)  goto  L16;
02897    b4=b4+b7;
02898    if(b4 >= b5) goto  L12;
02899 
02900    t=c-cc*c-ss*s;
02901    s=s+ss*c-cc*s;
02902    c=t;
02903    goto  L16;
02904 L20:
02905    ix0=b3/2;
02906    b3=b3-b7;
02907    b4=0;
02908    b5=0;
02909    b6=ix0;
02910    ix1=0;
02911    if ( b6 == b7) goto EXIT;
02912 L22:
02913    b4=b3-b4;
02914    b5=b3-b5;
02915    x2=br(b4+1);
02916    x3=br(b5+1);
02917    x4=bi(b4+1);
02918    x5=bi(b5+1);
02919    br(b4+1)=x3;
02920    br(b5+1)=x2;
02921    bi(b4+1)=x5;
02922    bi(b5+1)=x4;
02923    if (b6 < b4) goto  L22;
02924 L24:
02925    b4=b4+b7;
02926    b5=b6+b5;
02927    x2=br(b4+1);
02928    x3=br(b5+1);
02929    x4=bi(b4+1);
02930    x5=bi(b5+1);
02931    br(b4+1)=x3;
02932    br(b5+1)=x2;
02933    bi(b4+1)=x5;
02934    bi(b5+1)=x4;
02935    ix0=b6;
02936 L26:
02937    ix0=ix0/2;
02938    ix1=ix1-ix0;
02939    if(ix1 >= 0)  goto  L26;
02940 
02941    ix0=2*ix0;
02942    b4=b4+b7;
02943    ix1=ix1+ix0;
02944    b5=ix1;
02945    if (b5 >= b4)  goto  L22;
02946    if (b4 < b6)   goto  L24;
02947 EXIT:
02948    status = 0;
02949 }
02950 
02951 void  Util::fftr_q(float *xcmplx, int nv)
02952 {
02953    // dimension xcmplx(2,1); xcmplx(1,i) --- real, xcmplx(2,i) --- imaginary
02954 
02955         int nu, inv, nu1, n, isub, n2, i1, i2, i;
02956         float ss, cc, c, s, tr, ti, tr1, tr2, ti1, ti2, t;
02957 
02958         const float tab1[] = {
02959                 9.58737990959775e-5f,
02960                 1.91747597310703e-4f,
02961                 3.83495187571395e-4f,
02962                 7.66990318742704e-4f,
02963                 1.53398018628476e-3f,
02964                 3.06795676296598e-3f,
02965                 6.13588464915449e-3f,
02966                 1.22715382857199e-2f,
02967                 2.45412285229123e-2f,
02968                 4.90676743274181e-2f,
02969                 9.80171403295604e-2f,
02970                 1.95090322016128e-1f,
02971                 3.82683432365090e-1f,
02972                 7.07106781186546e-1f,
02973                 1.00000000000000f,
02974         };
02975 
02976         nu=abs(nv);
02977         inv=nv/nu;
02978         nu1=nu-1;
02979         n=(int)pow(2.f,nu1);
02980         isub=16-nu1;
02981 
02982         ss=-tab1(isub);
02983         cc=-2.0f*pow(tab1(isub-1),2.f);
02984         c=1.0f;
02985         s=0.0f;
02986         n2=n/2;
02987         if ( inv > 0) {
02988                 fftc_q(&xcmplx(1,1),&xcmplx(2,1),nu1,2);
02989                 tr=xcmplx(1,1);
02990                 ti=xcmplx(2,1);
02991                 xcmplx(1,1)=tr+ti;
02992                 xcmplx(2,1)=tr-ti;
02993                 for (i=1;i<=n2;i++) {
02994                         i1=i+1;
02995                         i2=n-i+1;
02996                         tr1=xcmplx(1,i1);
02997                         tr2=xcmplx(1,i2);
02998                         ti1=xcmplx(2,i1);
02999                         ti2=xcmplx(2,i2);
03000                         t=(cc*c-ss*s)+c;
03001                         s=(cc*s+ss*c)+s;
03002                         c=t;
03003                         xcmplx(1,i1)=0.5f*((tr1+tr2)+(ti1+ti2)*c-(tr1-tr2)*s);
03004                         xcmplx(1,i2)=0.5f*((tr1+tr2)-(ti1+ti2)*c+(tr1-tr2)*s);
03005                         xcmplx(2,i1)=0.5f*((ti1-ti2)-(ti1+ti2)*s-(tr1-tr2)*c);
03006                         xcmplx(2,i2)=0.5f*(-(ti1-ti2)-(ti1+ti2)*s-(tr1-tr2)*c);
03007                 }
03008         } else {
03009                 tr=xcmplx(1,1);
03010                 ti=xcmplx(2,1);
03011                 xcmplx(1,1)=0.5f*(tr+ti);
03012                 xcmplx(2,1)=0.5f*(tr-ti);
03013                 for (i=1; i<=n2; i++) {
03014                         i1=i+1;
03015                         i2=n-i+1;
03016                         tr1=xcmplx(1,i1);
03017                         tr2=xcmplx(1,i2);
03018                         ti1=xcmplx(2,i1);
03019                         ti2=xcmplx(2,i2);
03020                         t=(cc*c-ss*s)+c;
03021                         s=(cc*s+ss*c)+s;
03022                         c=t;
03023                         xcmplx(1,i1)=0.5f*((tr1+tr2)-(tr1-tr2)*s-(ti1+ti2)*c);
03024                         xcmplx(1,i2)=0.5f*((tr1+tr2)+(tr1-tr2)*s+(ti1+ti2)*c);
03025                         xcmplx(2,i1)=0.5f*((ti1-ti2)+(tr1-tr2)*c-(ti1+ti2)*s);
03026                         xcmplx(2,i2)=0.5f*(-(ti1-ti2)+(tr1-tr2)*c-(ti1+ti2)*s);
03027                 }
03028                 fftc_q(&xcmplx(1,1),&xcmplx(2,1),nu1,-2);
03029         }
03030 }
03031 
03032 // -------------------------------------------
03033 void  Util::fftr_d(double *xcmplx, int nv)
03034 {
03035         // double precision  x(2,1)
03036         int    i1, i2,  nu, inv, nu1, n, isub, n2, i;
03037         double tr1,tr2,ti1,ti2,tr,ti;
03038         double cc,c,ss,s,t;
03039         const double tab1[] = {
03040                 9.58737990959775e-5,
03041                 1.91747597310703e-4,
03042                 3.83495187571395e-4,
03043                 7.66990318742704e-4,
03044                 1.53398018628476e-3,
03045                 3.06795676296598e-3,
03046                 6.13588464915449e-3,
03047                 1.22715382857199e-2,
03048                 2.45412285229123e-2,
03049                 4.90676743274181e-2,
03050                 9.80171403295604e-2,
03051                 1.95090322016128e-1,
03052                 3.82683432365090e-1,
03053                 7.07106781186546e-1,
03054                 1.00000000000000,
03055         };
03056 
03057         nu=abs(nv);
03058         inv=nv/nu;
03059         nu1=nu-1;
03060         n=(int)pow(2.0f,nu1);
03061         isub=16-nu1;
03062         ss=-tab1(isub);
03063         cc=-2.0*pow(tab1(isub-1),2);
03064         c=1.0f;
03065         s=0.0f;
03066         n2=n/2;
03067 
03068         if ( inv > 0 ) {
03069                 fftc_d(&xcmplx(1,1),&xcmplx(2,1),nu1,2);
03070                 tr=xcmplx(1,1);
03071                 ti=xcmplx(2,1);
03072                 xcmplx(1,1)=tr+ti;
03073                 xcmplx(2,1)=tr-ti;
03074                 for (i=1;i<=n2;i++) {
03075                         i1=i+1;
03076                         i2=n-i+1;
03077                         tr1=xcmplx(1,i1);
03078                         tr2=xcmplx(1,i2);
03079                         ti1=xcmplx(2,i1);
03080                         ti2=xcmplx(2,i2);
03081                         t=(cc*c-ss*s)+c;
03082                         s=(cc*s+ss*c)+s;
03083                         c=t;
03084                         xcmplx(1,i1)=0.5*((tr1+tr2)+(ti1+ti2)*c-(tr1-tr2)*s);
03085                         xcmplx(1,i2)=0.5*((tr1+tr2)-(ti1+ti2)*c+(tr1-tr2)*s);
03086                         xcmplx(2,i1)=0.5*((ti1-ti2)-(ti1+ti2)*s-(tr1-tr2)*c);
03087                         xcmplx(2,i2)=0.5*(-(ti1-ti2)-(ti1+ti2)*s-(tr1-tr2)*c);
03088                 }
03089         } else {
03090                 tr=xcmplx(1,1);
03091                 ti=xcmplx(2,1);
03092                 xcmplx(1,1)=0.5*(tr+ti);
03093                 xcmplx(2,1)=0.5*(tr-ti);
03094                 for (i=1; i<=n2; i++) {
03095                         i1=i+1;
03096                         i2=n-i+1;
03097                         tr1=xcmplx(1,i1);
03098                         tr2=xcmplx(1,i2);
03099                         ti1=xcmplx(2,i1);
03100                         ti2=xcmplx(2,i2);
03101                         t=(cc*c-ss*s)+c;
03102                         s=(cc*s+ss*c)+s;
03103                         c=t;
03104                         xcmplx(1,i1)=0.5*((tr1+tr2)-(tr1-tr2)*s-(ti1+ti2)*c);
03105                         xcmplx(1,i2)=0.5*((tr1+tr2)+(tr1-tr2)*s+(ti1+ti2)*c);
03106                         xcmplx(2,i1)=0.5*((ti1-ti2)+(tr1-tr2)*c-(ti1+ti2)*s);
03107                         xcmplx(2,i2)=0.5*(-(ti1-ti2)+(tr1-tr2)*c-(ti1+ti2)*s);
03108                 }
03109                 fftc_d(&xcmplx(1,1),&xcmplx(2,1),nu1,-2);
03110         }
03111 }
03112 #undef  tab1
03113 #undef  xcmplx
03114 #undef  br
03115 #undef  bi
03116 
03117 // This function conducts the Single Precision Fourier Transform for a set of rings
03118 void Util::Frngs(EMData* circp, vector<int> numr){
03119         int nring = numr.size()/3;
03120         float *circ = circp->get_data();
03121         int i, l;
03122         for (i=1; i<=nring;i++) {
03123 
03124 #ifdef _WIN32
03125                 l = (int)( log((float)numr(3,i))/log(2.0f) );
03126 #else
03127                 l=(int)(log2(numr(3,i)));
03128 #endif  //_WIN32
03129 
03130                 fftr_q(&circ(numr(2,i)),l);
03131         }
03132 }
03133 // This function conducts the Single Precision Inverse Fourier Transform for a set of rings
03134 void Util::Frngs_inv(EMData* circp, vector<int> numr){
03135         int nring = numr.size()/3;
03136         float *circ = circp->get_data();
03137         int i, l;
03138         for (i=1; i<=nring;i++) {
03139 
03140 #ifdef _WIN32
03141                 l = (int)( log((float)numr(3,i))/log(2.0f) );
03142 #else
03143                 l=(int)(log2(numr(3,i)));
03144 #endif  //_WIN32
03145 
03146                 fftr_q(&circ(numr(2,i)),-l);
03147         }
03148 }
03149 #undef  circ
03150 
03151 #define  b(i)            b[i-1]
03152 void Util::prb1d(double *b, int npoint, float *pos) {
03153         double  c2,c3;
03154         int     nhalf;
03155 
03156         nhalf = npoint/2 + 1;
03157         *pos  = 0.0;
03158 
03159         if (npoint == 7) {
03160                 c2 = 49.*b(1) + 6.*b(2) - 21.*b(3) - 32.*b(4) - 27.*b(5)
03161                      - 6.*b(6) + 31.*b(7);
03162                 c3 = 5.*b(1) - 3.*b(3) - 4.*b(4) - 3.*b(5) + 5.*b(7);
03163         }
03164         else if (npoint == 5) {
03165                 c2 = (74.*b(1) - 23.*b(2) - 60.*b(3) - 37.*b(4)
03166                    + 46.*b(5) ) / (-70.);
03167                 c3 = (2.*b(1) - b(2) - 2.*b(3) - b(4) + 2.*b(5) ) / 14.0;
03168         }
03169         else if (npoint == 3) {
03170                 c2 = (5.*b(1) - 8.*b(2) + 3.*b(3) ) / (-2.0);
03171                 c3 = (b(1) - 2.*b(2) + b(3) ) / 2.0;
03172         }
03173         //else if (npoint == 9) {
03174         else  { // at least one has to be true!!
03175                 c2 = (1708.*b(1) + 581.*b(2) - 246.*b(3) - 773.*b(4)
03176                      - 1000.*b(5) - 927.*b(6) - 554.*b(7) + 119.*b(8)
03177                      + 1092.*b(9) ) / (-4620.);
03178                 c3 = (28.*b(1) + 7.*b(2) - 8.*b(3) - 17.*b(4) - 20.*b(5)
03179                      - 17.*b(6) - 8.*b(7) + 7.*b(8) + 28.*b(9) ) / 924.0;
03180         }
03181         if (c3 != 0.0)  *pos = static_cast<float>(c2/(2.0*c3) - nhalf);
03182 }
03183 #undef  b
03184 
03185 #define  circ1(i)        circ1[i-1]
03186 #define  circ2(i)        circ2[i-1]
03187 #define  t(i)            t[i-1]
03188 #define  q(i)            q[i-1]
03189 #define  b(i)            b[i-1]
03190 #define  t7(i)           t7[i-1]
03191 Dict Util::Crosrng_e(EMData*  circ1p, EMData* circ2p, vector<int> numr, int neg) {
03192         //  neg = 0 straight,  neg = 1 mirrored
03193         int nring = numr.size()/3;
03194         //int lcirc = numr[3*nring-2]+numr[3*nring-1]-1;
03195         int maxrin = numr[numr.size()-1];
03196         double qn;   float  tot;
03197         float *circ1 = circ1p->get_data();
03198         float *circ2 = circ2p->get_data();
03199 /*
03200 c checks single position, neg is flag for checking mirrored position
03201 c
03202 c  input - fourier transforms of rings!
03203 c  first set is conjugated (mirrored) if neg
03204 c  circ1 already multiplied by weights!
03205 c       automatic arrays
03206         dimension         t(maxrin)  removed +2 as it is only needed for other ffts
03207         double precision  q(maxrin)
03208         double precision  t7(-3:3)
03209 */
03210         float *t;
03211         double t7[7], *q;
03212         int    i, j, k, ip, jc, numr3i, numr2i, jtot = 0;
03213         float  pos;
03214 
03215 #ifdef _WIN32
03216         ip = -(int)(log((float)maxrin)/log(2.0f));
03217 #else
03218         ip = -(int) (log2(maxrin));
03219 #endif  //_WIN32
03220 
03221         q = (double*)calloc(maxrin, sizeof(double));
03222         t = (float*)calloc(maxrin, sizeof(float));
03223 
03224 //   cout << *qn <<"  " <<*tot<<"  "<<ip<<endl;
03225         for (i=1; i<=nring; i++) {
03226                 numr3i = numr(3,i);
03227                 numr2i = numr(2,i);
03228 
03229                 t(1) = (circ1(numr2i)) * circ2(numr2i);
03230 
03231                 if (numr3i != maxrin) {
03232                          // test .ne. first for speed on some compilers
03233                         t(numr3i+1) = circ1(numr2i+1) * circ2(numr2i+1);
03234                         t(2)            = 0.0;
03235 
03236                         if (neg) {
03237                                 // first set is conjugated (mirrored)
03238                                 for (j=3;j<=numr3i;j=j+2) {
03239                                         jc = j+numr2i-1;
03240                                         t(j) =(circ1(jc))*circ2(jc)-(circ1(jc+1))*circ2(jc+1);
03241                                         t(j+1) = -(circ1(jc))*circ2(jc+1)-(circ1(jc+1))*circ2(jc);
03242                                 }
03243                         } else {
03244                                 for (j=3;j<=numr3i;j=j+2) {
03245                                         jc = j+numr2i-1;
03246                                         t(j) = (circ1(jc))*circ2(jc) + (circ1(jc+1))*circ2(jc+1);
03247                                         t(j+1) = -(circ1(jc))*circ2(jc+1) + (circ1(jc+1))*circ2(jc);
03248                                 }
03249                         }
03250                         for (j=1;j<=numr3i+1;j++) q(j) = q(j) + t(j);
03251                 } else {
03252                         t(2) = circ1(numr2i+1) * circ2(numr2i+1);
03253                         if (neg) {
03254                                 // first set is conjugated (mirrored)
03255                                 for (j=3;j<=maxrin;j=j+2) {
03256                                         jc = j+numr2i-1;
03257                                         t(j) = (circ1(jc))*circ2(jc) - (circ1(jc+1))*circ2(jc+1);
03258                                         t(j+1) = -(circ1(jc))*circ2(jc+1) - (circ1(jc+1))*circ2(jc);
03259                                 }
03260                         } else {
03261                                 for (j=3;j<=maxrin;j=j+2) {
03262                                         jc = j+numr2i-1;
03263                                         t(j) = (circ1(jc))*circ2(jc) + (circ1(jc+1))*circ2(jc+1);
03264                                         t(j+1) = -(circ1(jc))*circ2(jc+1) + (circ1(jc+1))*circ2(jc);
03265                                 }
03266                         }
03267                         for (j = 1; j <= maxrin; j++) q(j) += t(j);
03268                 }
03269         }
03270 
03271         fftr_d(q,ip);
03272 
03273         qn = -1.0e20;
03274         for (j=1;j<=maxrin;j++) {
03275            if (q(j) >= qn) {
03276                   qn = q(j); jtot = j;
03277            }
03278         }
03279 
03280         for (k=-3; k<=3; k++) {
03281                 j = (jtot+k+maxrin-1)%maxrin + 1;
03282                 t7(k+4) = q(j);
03283         }
03284 
03285         prb1d(t7,7,&pos);
03286 
03287         tot = (float)jtot + pos;
03288 
03289         if (q) free(q);
03290         if (t) free(t);
03291 
03292         Dict retvals;
03293         retvals["qn"] = qn;
03294         retvals["tot"] = tot;
03295         return  retvals;
03296 }
03297 
03298 Dict Util::Crosrng_ew(EMData*  circ1p, EMData* circ2p, vector<int> numr, vector<float> w, int neg) {
03299    //  neg = 0 straight,  neg = 1 mirrored
03300         int nring = numr.size()/3;
03301         //int lcirc = numr[3*nring-2]+numr[3*nring-1]-1;
03302         int maxrin = numr[numr.size()-1];
03303         double qn;   float  tot;
03304         float *circ1 = circ1p->get_data();
03305         float *circ2 = circ2p->get_data();
03306 /*
03307 c checks single position, neg is flag for checking mirrored position
03308 c
03309 c  input - fourier transforms of rings!
03310 c  first set is conjugated (mirrored) if neg
03311 c  multiplication by weights!
03312 c       automatic arrays
03313         dimension         t(maxrin)  removed +2 as it is only needed for other ffts
03314         double precision  q(maxrin)
03315         double precision  t7(-3:3)
03316 */
03317         float *t;
03318         double t7[7], *q;
03319         int    i, j, k, ip, jc, numr3i, numr2i, jtot = 0;
03320         float  pos;
03321 
03322 #ifdef _WIN32
03323         ip = -(int)(log((float)maxrin)/log(2.0f));
03324 #else
03325         ip = -(int) (log2(maxrin));
03326 #endif  //_WIN32
03327 
03328         q = (double*)calloc(maxrin, sizeof(double));
03329         t = (float*)calloc(maxrin, sizeof(float));
03330 
03331 //   cout << *qn <<"  " <<*tot<<"  "<<ip<<endl;
03332         for (i=1;i<=nring;i++) {
03333                 numr3i = numr(3,i);
03334                 numr2i = numr(2,i);
03335 
03336                 t(1) = circ1(numr2i) * circ2(numr2i);
03337 
03338                 if (numr3i != maxrin) {
03339                         // test .ne. first for speed on some compilers
03340                         t(numr3i+1) = circ1(numr2i+1) * circ2(numr2i+1);
03341                         t(2)      = 0.0;
03342 
03343                         if (neg) {
03344                                 // first set is conjugated (mirrored)
03345                                 for (j=3; j<=numr3i; j=j+2) {
03346                                         jc = j+numr2i-1;
03347                                         t(j)   =  (circ1(jc))*circ2(jc)-(circ1(jc+1))*circ2(jc+1);
03348                                         t(j+1) = -(circ1(jc))*circ2(jc+1)-(circ1(jc+1))*circ2(jc);
03349                                 }
03350                         } else {
03351                                 for (j=3; j<=numr3i; j=j+2) {
03352                                         jc = j+numr2i-1;
03353                                         t(j) = (circ1(jc))*circ2(jc) + (circ1(jc+1))*circ2(jc+1);
03354                                         t(j+1) = -(circ1(jc))*circ2(jc+1) + (circ1(jc+1))*circ2(jc);
03355                                 }
03356                         }
03357                         for (j=1;j<=numr3i+1;j++) q(j) += t(j)*w[i-1];
03358                 } else {
03359                         t(2) = circ1(numr2i+1) * circ2(numr2i+1);
03360                         if (neg) {
03361                                 // first set is conjugated (mirrored)
03362                                 for (j=3; j<=maxrin; j=j+2) {
03363                                         jc = j+numr2i-1;
03364                                         t(j) = (circ1(jc))*circ2(jc) - (circ1(jc+1))*circ2(jc+1);
03365                                         t(j+1) = -(circ1(jc))*circ2(jc+1) - (circ1(jc+1))*circ2(jc);
03366                                 }
03367                         } else {
03368                                 for (j=3; j<=maxrin; j=j+2) {
03369                                 jc = j+numr2i-1;
03370                                 t(j) = (circ1(jc))*circ2(jc) + (circ1(jc+1))*circ2(jc+1);
03371                                 t(j+1) = -(circ1(jc))*circ2(jc+1) + (circ1(jc+1))*circ2(jc);
03372                                 }
03373                         }
03374                         for (j = 1; j <= maxrin; j++) q(j) += t(j)*w[i-1];
03375                 }
03376         }
03377 
03378         fftr_d(q,ip);
03379 
03380         qn = -1.0e20;
03381         for (j=1;j<=maxrin;j++) {
03382                 //cout << j << "  " << q(j) << endl;
03383                 if (q(j) >= qn) {
03384                         qn = q(j);
03385                         jtot = j;
03386                 }
03387         }
03388 
03389         for (k=-3; k<=3; k++) {
03390                 j = (jtot+k+maxrin-1)%maxrin + 1;
03391                 t7(k+4) = q(j);
03392         }
03393 
03394         prb1d(t7,7,&pos);
03395 
03396         tot = (float)jtot + pos;
03397 
03398         //if (q) free(q);
03399         if (t) free(t);
03400 
03401         Dict retvals;
03402         //tot = 1;
03403         //qn = q(1);
03404         retvals["qn"] = qn;
03405         retvals["tot"] = tot;
03406 
03407         if (q) free(q);
03408 
03409         return  retvals;
03410 }
03411 
03412 Dict Util::Crosrng_ms(EMData* circ1p, EMData* circ2p, vector<int> numr) {
03413         int nring = numr.size()/3;
03414         //int lcirc = numr[3*nring-2]+numr[3*nring-1]-1;
03415         int maxrin = numr[numr.size()-1];
03416         double qn; float tot; double qm; float tmt;
03417         float *circ1 = circ1p->get_data();
03418         float *circ2 = circ2p->get_data();
03419 /*
03420 c
03421 c  checks both straight & mirrored positions
03422 c
03423 c  input - fourier transforms of rings!!
03424 c  circ1 already multiplied by weights!
03425 c
03426 */
03427 
03428         // dimension             circ1(lcirc),circ2(lcirc)
03429 
03430         // t(maxrin), q(maxrin), t7(-3:3)  //maxrin+2 removed
03431         double *t, *q, t7[7];
03432 
03433         int   ip, jc, numr3i, numr2i, i, j, k, jtot = 0;
03434         float t1, t2, t3, t4, c1, c2, d1, d2, pos;
03435 
03436         qn  = 0.0f;
03437         qm  = 0.0f;
03438         tot = 0.0f;
03439         tmt = 0.0f;
03440 #ifdef _WIN32
03441         ip = -(int)(log((float)maxrin)/log(2.0f));
03442 #else
03443         ip = -(int)(log2(maxrin));
03444 #endif  //_WIN32
03445   //for (j=1; j<=maxrin;j++) cout <<"  "<<j<<"   "<<circ1(j)<<"   "<<circ2(j) <<endl;
03446 
03447         //  c - straight  = circ1 * conjg(circ2)
03448         //  zero q array
03449 
03450         q = (double*)calloc(maxrin,sizeof(double));
03451 
03452         //   t - mirrored  = conjg(circ1) * conjg(circ2)
03453         //   zero t array
03454         t = (double*)calloc(maxrin,sizeof(double));
03455 
03456    //   premultiply  arrays ie( circ12 = circ1 * circ2) much slower
03457         for (i=1; i<=nring; i++) {
03458 
03459                 numr3i = numr(3,i);   // Number of samples of this ring
03460                 numr2i = numr(2,i);   // The beginning point of this ring
03461 
03462                 t1   = circ1(numr2i) * circ2(numr2i);
03463                 q(1) += t1;
03464                 t(1) += t1;
03465 
03466                 t1   = circ1(numr2i+1) * circ2(numr2i+1);
03467                 if (numr3i == maxrin)  {
03468                         q(2) += t1;
03469                         t(2) += t1;
03470                 } else {
03471                         q(numr3i+1) += t1;
03472                         t(numr3i+1) += t1;
03473                 }
03474 
03475                 for (j=3; j<=numr3i; j += 2) {
03476                         jc     = j+numr2i-1;
03477 
03478 // Here, (c1+c2i)*conj(d1+d2i) = (c1*d1+c2*d2)+(-c1*d2+c2*d1)i
03479 //                                ----- -----    ----- -----
03480 //                                 t1     t2      t3    t4
03481 // Here, conj(c1+c2i)*conj(d1+d2i) = (c1*d1-c2*d2)+(-c1*d2-c2*d1)i
03482 //                                    ----- -----    ----- -----
03483 //                                     t1    t2       t3    t4
03484 
03485                         c1     = circ1(jc);
03486                         c2     = circ1(jc+1);
03487                         d1     = circ2(jc);
03488                         d2     = circ2(jc+1);
03489 
03490                         t1     = c1 * d1;
03491                         t2     = c2 * d2;
03492                         t3     = c1 * d2;
03493                         t4     = c2 * d1;
03494 
03495                         q(j)   += t1 + t2;
03496                         q(j+1) += -t3 + t4;
03497                         t(j)   += t1 - t2;
03498                         t(j+1) += -t3 - t4;
03499                 }
03500         }
03501         //for (j=1; j<=maxrin; j++) cout <<"  "<<j<<"   "<<q(j) <<"   "<<t(j) <<endl;
03502         fftr_d(q,ip);
03503 
03504         qn  = -1.0e20;
03505         for (j=1; j<=maxrin; j++) {//cout <<"  "<<j<<"   "<<q(j) <<endl;
03506                 if (q(j) >= qn) {
03507                         qn  = q(j);
03508                         jtot = j;
03509                 }
03510         }
03511 
03512         for (k=-3; k<=3; k++) {
03513                 j = ((jtot+k+maxrin-1)%maxrin)+1;
03514                 t7(k+4) = q(j);
03515         }
03516 
03517         // interpolate
03518         prb1d(t7,7,&pos);
03519         tot = (float)(jtot)+pos;
03520         // Do not interpolate
03521         //tot = (float)(jtot);
03522 
03523         // mirrored
03524         fftr_d(t,ip);
03525 
03526         // find angle
03527         qm = -1.0e20;
03528         for (j=1; j<=maxrin;j++) {//cout <<"  "<<j<<"   "<<t(j) <<endl;
03529                 if ( t(j) >= qm ) {
03530                         qm   = t(j);
03531                         jtot = j;
03532                 }
03533         }
03534 
03535         for (k=-3; k<=3; k++)  {
03536                 j = ((jtot+k+maxrin-1)%maxrin) + 1;
03537                 t7(k+4) = t(j);
03538         }
03539 
03540         // interpolate
03541 
03542         prb1d(t7,7,&pos);
03543         tmt = float(jtot) + pos;
03544         // Do not interpolate
03545         //tmt = float(jtot);
03546 
03547         free(t);
03548         free(q);
03549 
03550         Dict retvals;
03551         retvals["qn"] = qn;
03552         retvals["tot"] = tot;
03553         retvals["qm"] = qm;
03554         retvals["tmt"] = tmt;
03555         return retvals;
03556 }
03557 
03558 
03559 Dict Util::Crosrng_sm_psi(EMData* circ1p, EMData* circ2p, vector<int> numr, float psi, int flag) {
03560 // flag 0 - straignt, 1 - mirror
03561 
03562         int nring = numr.size()/3;
03563         int maxrin = numr[numr.size()-1];
03564         double qn; float tot; double qm; float tmt;
03565         float *circ1 = circ1p->get_data();
03566         float *circ2 = circ2p->get_data();
03567 /*
03568 c
03569 c  checks both straight & mirrored positions
03570 c
03571 c  input - fourier transforms of rings!!
03572 c  circ1 already multiplied by weights!
03573 c
03574 */
03575 
03576         double *q, t7[7];
03577 
03578         int   ip, jc, numr3i, numr2i, i, j, k, jtot = 0;
03579         float t1, t2, t3, t4, c1, c2, d1, d2, pos;
03580 
03581         qn  = 0.0f;
03582         qm  = 0.0f;
03583         tot = 0.0f;
03584         tmt = 0.0f;
03585 #ifdef _WIN32
03586         ip = -(int)(log((float)maxrin)/log(2.0f));
03587 #else
03588         ip = -(int)(log2(maxrin));
03589 #endif  //_WIN32
03590 
03591         //  c - straight  = circ1 * conjg(circ2)
03592         //  zero q array
03593 
03594         q = (double*)calloc(maxrin,sizeof(double));
03595 
03596    //   premultiply  arrays ie( circ12 = circ1 * circ2) much slower
03597         if (flag==0) {
03598                 for (i=1; i<=nring; i++) {
03599 
03600                         numr3i = numr(3,i);   // Number of samples of this ring
03601                         numr2i = numr(2,i);   // The beginning point of this ring
03602 
03603                         t1   = circ1(numr2i) * circ2(numr2i);
03604                         q(1) += t1;
03605 
03606                         t1   = circ1(numr2i+1) * circ2(numr2i+1);
03607                         if (numr3i == maxrin)  {
03608                                 q(2) += t1;
03609                         } else {
03610                                 q(numr3i+1) += t1;
03611                         }
03612 
03613                         for (j=3; j<=numr3i; j += 2) {
03614                                 jc     = j+numr2i-1;
03615 
03616         // Here, (c1+c2i)*conj(d1+d2i) = (c1*d1+c2*d2)+(-c1*d2+c2*d1)i
03617         //                                ----- -----    ----- -----
03618         //                                 t1     t2      t3    t4
03619 
03620                                 c1     = circ1(jc);
03621                                 c2     = circ1(jc+1);
03622                                 d1     = circ2(jc);
03623                                 d2     = circ2(jc+1);
03624 
03625                                 t1     = c1 * d1;
03626                                 t3     = c1 * d2;
03627                                 t2     = c2 * d2;
03628                                 t4     = c2 * d1;
03629 
03630                                 q(j)   += t1 + t2;
03631                                 q(j+1) += -t3 + t4;
03632                         }
03633                 }
03634         } else {
03635                 for (i=1; i<=nring; i++) {
03636 
03637                         numr3i = numr(3,i);   // Number of samples of this ring
03638                         numr2i = numr(2,i);   // The beginning point of this ring
03639 
03640                         t1   = circ1(numr2i) * circ2(numr2i);
03641                         q(1) += t1;
03642 
03643                         t1   = circ1(numr2i+1) * circ2(numr2i+1);
03644                         if (numr3i == maxrin)  {
03645                                 q(2) += t1;
03646                         } else {
03647                                 q(numr3i+1) += t1;
03648                         }
03649 
03650                         for (j=3; j<=numr3i; j += 2) {
03651                                 jc     = j+numr2i-1;
03652 
03653         // Here, (c1+c2i)*conj(d1+d2i) = (c1*d1+c2*d2)+(-c1*d2+c2*d1)i
03654         //                                ----- -----    ----- -----
03655         //                                 t1     t2      t3    t4
03656 
03657                                 c1     = circ1(jc);
03658                                 c2     = circ1(jc+1);
03659                                 d1     = circ2(jc);
03660                                 d2     = circ2(jc+1);
03661 
03662                                 t1     = c1 * d1;
03663                                 t3     = c1 * d2;
03664                                 t2     = c2 * d2;
03665                                 t4     = c2 * d1;
03666 
03667                                 q(j)   += t1 - t2;
03668                                 q(j+1) += -t3 - t4;
03669                         }
03670                 }
03671         }
03672         fftr_d(q,ip);
03673 
03674         qn  = -1.0e20;
03675         int psi_pos = int(psi/360.0*maxrin+0.5);
03676 
03677         for (k=-5; k<=5; k++) {
03678                 j = (psi_pos+maxrin-1)%maxrin+1;
03679                 if (q(j) >= qn) {
03680                         qn  = q(j);
03681                         jtot = j;
03682                 }
03683         }
03684 
03685         for (k=-3; k<=3; k++) {
03686                 j = ((jtot+k+maxrin-1)%maxrin)+1;
03687                 t7(k+4) = q(j);
03688         }
03689 
03690         // interpolate
03691         prb1d(t7,7,&pos);
03692         tot = (float)(jtot)+pos;
03693         free(q);
03694 
03695         Dict retvals;
03696         retvals["qn"] = qn;
03697         retvals["tot"] = tot;
03698         return retvals;
03699 }
03700 
03701 
03702 Dict Util::Crosrng_ns(EMData* circ1p, EMData* circ2p, vector<int> numr) {
03703         int nring = numr.size()/3;
03704         //int lcirc = numr[3*nring-2]+numr[3*nring-1]-1;
03705         int maxrin = numr[numr.size()-1];
03706         double qn; float tot;
03707         float *circ1 = circ1p->get_data();
03708         float *circ2 = circ2p->get_data();
03709 /*
03710 c
03711 c  checks only straight position
03712 c
03713 c  input - fourier transforms of rings!!
03714 c  circ1 already multiplied by weights!
03715 c
03716 */
03717 
03718         // dimension             circ1(lcirc),circ2(lcirc)
03719 
03720         // q(maxrin), t7(-3:3)  //maxrin+2 removed
03721         double *q, t7[7];
03722 
03723         int   ip, jc, numr3i, numr2i, i, j, k, jtot = 0;
03724         float c1, c2, d1, d2, pos;
03725 
03726         qn  = 0.0;
03727         tot = 0.0;
03728 #ifdef _WIN32
03729         ip = -(int)(log((float)maxrin)/log(2.0f));
03730 #else
03731    ip = -(int)(log2(maxrin));
03732 #endif  //_WIN32
03733         //for (j=1; j<=maxrin;j++) cout <<"  "<<j<<"   "<<circ1(j)<<"   "<<circ2(j) <<endl;
03734 
03735         //  c - straight  = circ1 * conjg(circ2)
03736         //  zero q array
03737 
03738         q = (double*)calloc(maxrin,sizeof(double));
03739 
03740                         //   premultiply  arrays ie( circ12 = circ1 * circ2) much slower
03741         for (i=1; i<=nring; i++) {
03742 
03743                 numr3i = numr(3,i);   // Number of samples of this ring
03744                 numr2i = numr(2,i);   // The beginning point of this ring
03745 
03746                 q(1) += circ1(numr2i) * circ2(numr2i);
03747 
03748                 if (numr3i == maxrin)   q(2) += circ1(numr2i+1) * circ2(numr2i+1);
03749                 else  q(numr3i+1) += circ1(numr2i+1) * circ2(numr2i+1);
03750 
03751                 for (j=3; j<=numr3i; j += 2) {
03752                         jc     = j+numr2i-1;
03753 
03754 // Here, (c1+c2i)*conj(d1+d2i) = (c1*d1+c2*d2)+(-c1*d2+c2*d1)i
03755 //                                ----- -----    ----- -----
03756 //                                 t1     t2      t3    t4
03757 
03758                         c1     = circ1(jc);
03759                         c2     = circ1(jc+1);
03760                         d1     = circ2(jc);
03761                         d2     = circ2(jc+1);
03762 
03763                         q(j)   += c1 * d1 + c2 * d2;
03764                         q(j+1) += -c1 * d2 + c2 * d1;
03765                 }
03766         }
03767 //for (j=1; j<=maxrin; j++) cout <<"  "<<j<<"   "<<q(j) <<endl;
03768         fftr_d(q,ip);
03769 
03770         qn  = -1.0e20;
03771         for (j=1; j<=maxrin; j++) {//cout <<"  "<<j<<"   "<<q(j) <<endl;
03772                 if (q(j) >= qn) {
03773                         qn  = q(j);
03774                         jtot = j;
03775                 }
03776         }
03777 
03778         for (k=-3; k<=3; k++)  {
03779                 j = ((jtot+k+maxrin-1)%maxrin)+1;
03780                 t7(k+4) = q(j);
03781         }
03782 
03783         // interpolate
03784         prb1d(t7,7,&pos);
03785         tot = (float)(jtot)+pos;
03786         // Do not interpolate
03787         //*tot = (float)(jtot);
03788 
03789         free(q);
03790 
03791         Dict retvals;
03792         retvals["qn"] = qn;
03793         retvals["tot"] = tot;
03794         return retvals;
03795 }
03796 
03797 #define  dout(i,j)        dout[i+maxrin*j]
03798 #define  circ1b(i)        circ1b[i-1]
03799 #define  circ2b(i)        circ2b[i-1]
03800 
03801 EMData* Util::Crosrng_msg(EMData* circ1, EMData* circ2, vector<int> numr) {
03802 /*
03803 c
03804 c  checks both straight & mirrored positions
03805 c
03806 c  input - fourier transforms of rings!!
03807 c  circ1 already multiplied by weights!
03808 c
03809   returns EM object with 1D ccf
03810 
03811 */
03812 
03813    // dimension         circ1(lcirc),circ2(lcirc)
03814 
03815         int   ip, jc, numr3i, numr2i, i, j;
03816         float t1, t2, t3, t4, c1, c2, d1, d2;
03817 
03818         int nring = numr.size()/3;
03819         //int lcirc = numr[3*nring-2]+numr[3*nring-1]-1;
03820         int maxrin = numr[numr.size()-1];
03821 
03822         float* circ1b = circ1->get_data();
03823         float* circ2b = circ2->get_data();
03824 
03825         // t(maxrin), q(maxrin)  // removed +2
03826         double *t, *q;
03827 
03828         q = (double*)calloc(maxrin,sizeof(double));
03829         t = (double*)calloc(maxrin,sizeof(double));
03830 
03831 #ifdef _WIN32
03832         ip = -(int)(log((float)maxrin)/log(2.0f));
03833 #else
03834         ip = -(int)(log2(maxrin));
03835 #endif  //_WIN32
03836 
03837         //  q - straight  = circ1 * conjg(circ2)
03838 
03839         //   t - mirrored  = conjg(circ1) * conjg(circ2)
03840 
03841         //   premultiply  arrays ie( circ12 = circ1 * circ2) much slower
03842 
03843         for (i=1; i<=nring; i++) {
03844 
03845                 numr3i = numr(3,i);
03846                 numr2i = numr(2,i);
03847 
03848                 t1   = circ1b(numr2i) * circ2b(numr2i);
03849                 q(1) = q(1)+t1;
03850                 t(1) = t(1)+t1;
03851 
03852                 t1   = circ1b(numr2i+1) * circ2b(numr2i+1);
03853                 if (numr3i == maxrin)  {
03854                         q(2) += t1;
03855                         t(2) += t1;
03856                 } else {
03857                         q(numr3i+1) += t1;
03858                         t(numr3i+1) += t1;
03859                 }
03860 
03861                 for (j=3; j<=numr3i; j=j+2) {
03862                         jc     = j+numr2i-1;
03863 
03864                         c1     = circ1b(jc);
03865                         c2     = circ1b(jc+1);
03866                         d1     = circ2b(jc);
03867                         d2     = circ2b(jc+1);
03868 
03869                         t1     = c1 * d1;
03870                         t3     = c1 * d2;
03871                         t2     = c2 * d2;
03872                         t4     = c2 * d1;
03873 
03874                         q(j)   += t1 + t2;
03875                         q(j+1) += - t3 + t4;
03876                         t(j)   += t1 - t2;
03877                         t(j+1) += - t3 - t4;
03878                 }
03879         }
03880 
03881         // straight
03882         fftr_d(q,ip);
03883 
03884         // mirrored
03885         fftr_d(t,ip);
03886 
03887         EMData* out = new EMData();
03888         out->set_size(maxrin,2,1);
03889         float *dout = out->get_data();
03890         for (int i=0; i<maxrin; i++) {dout(i,0)=static_cast<float>(q[i]); dout(i,1)=static_cast<float>(t[i]);}
03891         //out->set_size(maxrin,1,1);
03892         //float *dout = out->get_data();
03893         //for (int i=0; i<maxrin; i++) {dout(i,0)=q[i];}
03894         free(t);
03895         free(q);
03896         return out;
03897 }
03898 
03899 
03900 vector<float> Util::Crosrng_msg_vec_p(EMData* circ1, EMData* circ2, vector<int> numr ) {
03901 
03902         int maxrin = numr[numr.size()-1];
03903 
03904         vector<float> r(2*maxrin);
03905 
03906         Crosrng_msg_vec( circ1, circ2, numr, &r[0], &r[maxrin] );
03907 
03908         return r;
03909 }
03910 
03911 #define  dout(i,j)        dout[i+maxrin*j]
03912 #define  circ1b(i)        circ1b[i-1]
03913 #define  circ2b(i)        circ2b[i-1]
03914 
03915 void Util::Crosrng_msg_vec(EMData* circ1, EMData* circ2, vector<int> numr, float *q, float *t) {
03916 /*
03917 c
03918 c  checks both straight & mirrored positions
03919 c
03920 c  input - fourier transforms of rings!!
03921 c  circ1 already multiplied by weights!
03922 c
03923   returns EM object with 1D ccf
03924 
03925 */
03926 
03927    // dimension         circ1(lcirc),circ2(lcirc)
03928 
03929         int   ip, jc, numr3i, numr2i, i, j;
03930         float t1, t2, t3, t4, c1, c2, d1, d2;
03931 
03932         int nring = numr.size()/3;
03933         //int lcirc = numr[3*nring-2]+numr[3*nring-1]-1;
03934         int maxrin = numr[numr.size()-1];
03935 
03936         float* circ1b = circ1->get_data();
03937         float* circ2b = circ2->get_data();
03938 
03939 #ifdef _WIN32
03940         ip = -(int)(log((float)maxrin)/log(2.0f));
03941 #else
03942         ip = -(int)(log2(maxrin));
03943 #endif  //_WIN32
03944         for (int i=1; i<=maxrin; i++)  {q(i) = 0.0f; t(i) = 0.0f;}
03945 
03946         //  q - straight  = circ1 * conjg(circ2)
03947 
03948         //   t - mirrored  = conjg(circ1) * conjg(circ2)
03949 
03950         for (i=1; i<=nring; i++) {
03951 
03952                 numr3i = numr(3,i);
03953                 numr2i = numr(2,i);
03954 
03955                 t1   = circ1b(numr2i) * circ2b(numr2i);
03956                 q(1) += t1;
03957                 t(1) += t1;
03958 
03959                 t1   = circ1b(numr2i+1) * circ2b(numr2i+1);
03960                 if (numr3i == maxrin)  {
03961                         q(2) += t1;
03962                         t(2) += t1;
03963                 } else {
03964                         q(numr3i+1) += t1;
03965                         t(numr3i+1) += t1;
03966                 }
03967 
03968                 for (j=3; j<=numr3i; j=j+2) {
03969                         jc     = j+numr2i-1;
03970 
03971                         c1     = circ1b(jc);
03972                         c2     = circ1b(jc+1);
03973                         d1     = circ2b(jc);
03974                         d2     = circ2b(jc+1);
03975 
03976                         t1     = c1 * d1;
03977                         t3     = c1 * d2;
03978                         t2     = c2 * d2;
03979                         t4     = c2 * d1;
03980 
03981                         q(j)   += t1 + t2;
03982                         q(j+1) += -t3 + t4;
03983                         t(j)   += t1 - t2;
03984                         t(j+1) += -t3 - t4;
03985                 }
03986         }
03987         // straight
03988         fftr_q(q,ip);
03989         //for (int i=0; i<maxrin; i++) cout<<i<<"  B    "<<q[i]<<"       "<<t[i]<<endl;
03990 
03991         // mirrored
03992         fftr_q(t,ip);
03993 }
03994 
03995 
03996 
03997 EMData* Util::Crosrng_msg_s(EMData* circ1, EMData* circ2, vector<int> numr)
03998 {
03999 /*
04000   This program is half of the Crosrng_msg. It only checks straight position.
04001 
04002   input - fourier transforms of rings!!
04003   circ1 already multiplied by weights!
04004   returns EM object with 1D ccf
04005 
04006 */
04007 
04008         int   ip, jc, numr3i, numr2i, i, j;
04009         float t1, t2, t3, t4, c1, c2, d1, d2;
04010 
04011         int nring = numr.size()/3;
04012         int maxrin = numr[numr.size()-1];
04013 
04014         float* circ1b = circ1->get_data();
04015         float* circ2b = circ2->get_data();
04016 
04017         double *q;
04018 
04019         q = (double*)calloc(maxrin,sizeof(double));
04020 
04021 #ifdef _WIN32
04022         ip = -(int)(log((float)maxrin)/log(2.0f));
04023 #else
04024         ip = -(int)(log2(maxrin));
04025 #endif  //_WIN32
04026 
04027          //  q - straight  = circ1 * conjg(circ2)
04028 
04029         for (i=1;i<=nring;i++) {
04030 
04031                 numr3i = numr(3,i);
04032                 numr2i = numr(2,i);
04033 
04034                 t1   = circ1b(numr2i) * circ2b(numr2i);
04035                 q(1) = q(1)+t1;
04036 
04037                 if (numr3i == maxrin)  {
04038                         t1   = circ1b(numr2i+1) * circ2b(numr2i+1);
04039                         q(2) = q(2)+t1;
04040                 } else {
04041                         t1              = circ1b(numr2i+1) * circ2b(numr2i+1);
04042                         q(numr3i+1) = q(numr3i+1)+t1;
04043                 }
04044 
04045                 for (j=3;j<=numr3i;j=j+2) {
04046                         jc     = j+numr2i-1;
04047 
04048                         c1     = circ1b(jc);
04049                         c2     = circ1b(jc+1);
04050                         d1     = circ2b(jc);
04051                         d2     = circ2b(jc+1);
04052 
04053                         t1     = c1 * d1;
04054                         t3     = c1 * d2;
04055                         t2     = c2 * d2;
04056                         t4     = c2 * d1;
04057 
04058                         q(j)   = q(j)   + t1 + t2;
04059                         q(j+1) = q(j+1) - t3 + t4;
04060                 }
04061         }
04062 
04063         // straight
04064         fftr_d(q,ip);
04065 
04066         EMData* out = new EMData();
04067         out->set_size(maxrin,1,1);
04068         float *dout = out->get_data();
04069         for (int i=0; i<maxrin; i++) dout[i]=static_cast<float>(q[i]);
04070         free(q);
04071         return out;
04072 
04073 }
04074 
04075 
04076 EMData* Util::Crosrng_msg_m(EMData* circ1, EMData* circ2, vector<int> numr)
04077 {
04078 /*
04079 
04080   This program is half of the Crosrng_msg. It only checks mirrored position.
04081 
04082   input - fourier transforms of rings!!
04083   circ1 already multiplied by weights!
04084   returns EM object with 1D ccf
04085 
04086 */
04087 
04088         int   ip, jc, numr3i, numr2i, i, j;
04089         float t1, t2, t3, t4, c1, c2, d1, d2;
04090 
04091         int nring = numr.size()/3;
04092         int maxrin = numr[numr.size()-1];
04093 
04094         float* circ1b = circ1->get_data();
04095         float* circ2b = circ2->get_data();
04096 
04097         double *t;
04098 
04099         t = (double*)calloc(maxrin,sizeof(double));
04100 
04101 #ifdef _WIN32
04102         ip = -(int)(log((float)maxrin)/log(2.0f));
04103 #else
04104         ip = -(int)(log2(maxrin));
04105 #endif  //_WIN32
04106 
04107          //   t - mirrored  = conjg(circ1) * conjg(circ2)
04108 
04109         for (i=1;i<=nring;i++) {
04110 
04111                 numr3i = numr(3,i);
04112                 numr2i = numr(2,i);
04113 
04114                 t1   = circ1b(numr2i) * circ2b(numr2i);
04115                 t(1) = t(1)+t1;
04116 
04117                 if (numr3i == maxrin)  {
04118                         t1   = circ1b(numr2i+1) * circ2b(numr2i+1);
04119                         t(2) = t(2)+t1;
04120                 }
04121 
04122                 for (j=3;j<=numr3i;j=j+2) {
04123                         jc     = j+numr2i-1;
04124 
04125                         c1     = circ1b(jc);
04126                         c2     = circ1b(jc+1);
04127                         d1     = circ2b(jc);
04128                         d2     = circ2b(jc+1);
04129 
04130                         t1     = c1 * d1;
04131                         t3     = c1 * d2;
04132                         t2     = c2 * d2;
04133                         t4     = c2 * d1;
04134 
04135                         t(j)   = t(j)   + t1 - t2;
04136                         t(j+1) = t(j+1) - t3 - t4;
04137                 }
04138         }
04139 
04140         // mirrored
04141         fftr_d(t,ip);
04142 
04143         EMData* out = new EMData();
04144         out->set_size(maxrin,1,1);
04145         float *dout = out->get_data();
04146         for (int i=0; i<maxrin; i++) dout[i]=static_cast<float>(t[i]);
04147         free(t);
04148         return out;
04149 
04150 }
04151 
04152 #undef circ1b
04153 #undef circ2b
04154 #undef dout
04155 
04156 #undef  circ1
04157 #undef  circ2
04158 #undef  t
04159 #undef  q
04160 #undef  b
04161 #undef  t7
04162 
04163 
04164 #define    QUADPI                   3.141592653589793238462643383279502884197
04165 #define    PI2                      2*QUADPI
04166 
04167 // helper functions for ali2d_ra
04168 
04169 float Util::ener(EMData* ave, vector<int> numr) {
04170         ENTERFUNC;
04171         long double ener,en;
04172 
04173         int nring = numr.size()/3;
04174         float *aveptr = ave->get_data();
04175 
04176         ener = 0.0;
04177         for (int i=1; i<=nring; i++) {
04178                 int numr3i = numr(3,i);
04179                 int np     = numr(2,i)-1;
04180                 float tq = static_cast<float>(PI2*numr(1,i)/numr3i);
04181                 en = tq*(aveptr[np]*aveptr[np]+aveptr[np+1]*aveptr[np+1])*0.5;
04182                 for (int j=np+2; j<np+numr3i-1; j++) en += tq*aveptr[j]*aveptr[j];
04183                 ener += en/numr3i;
04184         }
04185         EXITFUNC;
04186         return static_cast<float>(ener);
04187 }
04188 
04189 float Util::ener_tot(const vector<EMData*>& data, vector<int> numr, vector<float> tot) {
04190         ENTERFUNC;
04191         long double ener, en;
04192         float arg, cs, si;
04193 
04194         int nima = data.size();
04195         int nring = numr.size()/3;
04196         int maxrin = numr(3,nring);
04197 
04198         ener = 0.0;
04199         for (int i=1; i<=nring; i++) {
04200                 int numr3i = numr(3,i);
04201                 int np     = numr(2,i)-1;
04202                 float tq = static_cast<float>(PI2*numr(1,i)/numr3i);
04203                 float temp1 = 0.0, temp2 = 0.0;
04204                 for (int kk=0; kk<nima; kk++) {
04205                         float *ptr = data[kk]->get_data();
04206                         temp1 += ptr[np];
04207                         temp2 += static_cast<float>(ptr[np+1]*cos(PI2*(tot[kk]-1.0f)/2.0f*numr3i/maxrin));
04208                 }
04209                 en = tq*(temp1*temp1+temp2*temp2)*0.5;
04210                 for (int j=2; j<numr3i; j+=2) {
04211                         float tempr = 0.0, tempi = 0.0;
04212                         for (int kk=0; kk<nima; kk++) {
04213                                 float *ptr = data[kk]->get_data();
04214                                 arg = static_cast<float>( PI2*(tot[kk]-1.0)*(j/2)/maxrin );
04215                                 cs = cos(arg);
04216                                 si = sin(arg);
04217                                 tempr += ptr[np + j]*cs - ptr[np + j +1]*si;
04218                                 tempi += ptr[np + j]*si + ptr[np + j +1]*cs;
04219                         }
04220                         en += tq*(tempr*tempr+tempi*tempi);
04221                 }
04222                 ener += en/numr3i;
04223         }
04224         EXITFUNC;
04225         return static_cast<float>(ener);
04226 }
04227 
04228 void Util::update_fav (EMData* avep, EMData* datp, float tot, int mirror, vector<int> numr) {
04229         int nring = numr.size()/3;
04230         float *ave = avep->get_data();
04231         float *dat = datp->get_data();
04232         int i, j, numr3i, np;
04233         float  arg, cs, si;
04234         int maxrin = numr(3,nring);
04235         if(mirror == 1) { //for mirrored data has to be conjugated
04236                 for (i=1; i<=nring; i++) {
04237                         numr3i = numr(3,i);
04238                         np     = numr(2,i)-1;
04239                         ave[np]   += dat[np];
04240                         ave[np+1] += static_cast<float>( dat[np+1]*cos(PI2*(tot-1.0f)/2.0f*numr3i/maxrin) );
04241                         for (j=2; j<numr3i; j=j+2) {
04242                                 arg = static_cast<float>( PI2*(tot-1.)*(j/2)/maxrin );
04243                                 cs = cos(arg);
04244                                 si = sin(arg);
04245                                 //complex(data[np + j],data[np + j +1])*complex(cos(arg),sin(arg))
04246                                 ave[np + j]    += dat[np + j]*cs - dat[np + j +1]*si;
04247                                 ave[np + j +1] -= dat[np + j]*si + dat[np + j +1]*cs;
04248                         }
04249                 }
04250         } else {
04251                 for (i=1; i<=nring; i++) {
04252                         numr3i = numr(3,i);
04253                         np     = numr(2,i)-1;
04254                         ave[np]   += dat[np];
04255                         ave[np+1] += static_cast<float>( dat[np+1]*cos(PI2*(tot-1.0f)/2.0f*numr3i/maxrin) );
04256                         for (j=2; j<numr3i; j=j+2) {
04257                                 arg = static_cast<float>( PI2*(tot-1.)*(j/2)/maxrin );
04258                                 cs = cos(arg);
04259                                 si = sin(arg);
04260                                 //complex(data[np + j],data[np + j +1])*complex(cos(arg),sin(arg))
04261                                 ave[np + j]    += dat[np + j]*cs - dat[np + j +1]*si;
04262                                 ave[np + j +1] += dat[np + j]*si + dat[np + j +1]*cs;
04263                         }
04264                 }
04265         }
04266         avep->update();
04267         EXITFUNC;
04268 }
04269 
04270 void Util::sub_fav(EMData* avep, EMData* datp, float tot, int mirror, vector<int> numr) {
04271         int nring = numr.size()/3;
04272         float *ave = avep->get_data();
04273         float *dat = datp->get_data();
04274         int i, j, numr3i, np;
04275         float  arg, cs, si;
04276         int maxrin = numr(3,nring);
04277         if(mirror == 1) { //for mirrored data has to be conjugated
04278                 for (i=1; i<=nring; i++) {
04279                         numr3i = numr(3,i);
04280                         np     = numr(2,i)-1;
04281                         ave[np]   -= dat[np];
04282                         ave[np+1] -= static_cast<float>( dat[np+1]*cos(PI2*(tot-1.0f)/2.0f*numr3i/maxrin) );
04283                         for (j=2; j<numr3i; j=j+2) {
04284                                 arg = static_cast<float>( PI2*(tot-1.)*(j/2)/maxrin );
04285                                 cs = cos(arg);
04286                                 si = sin(arg);
04287                                 //complex(data[np + j],data[np + j +1])*complex(cos(arg),sin(arg))
04288                                 ave[np + j]    -= dat[np + j]*cs - dat[np + j +1]*si;
04289                                 ave[np + j +1] += dat[np + j]*si + dat[np + j +1]*cs;
04290                         }
04291                 }
04292         } else {
04293                 for (i=1; i<=nring; i++) {
04294                         numr3i = numr(3,i);
04295                         np     = numr(2,i)-1;
04296                         ave[np]   -= dat[np];
04297                         ave[np+1] -= static_cast<float>( dat[np+1]*cos(PI2*(tot-1.0f)/2.0f*numr3i/maxrin) );
04298                         for (j=2; j<numr3i; j=j+2) {
04299                                 arg = static_cast<float>( PI2*(tot-1.)*(j/2)/maxrin );
04300                                 cs = cos(arg);
04301                                 si = sin(arg);
04302                                 //complex(data[np + j],data[np + j +1])*complex(cos(arg),sin(arg))
04303                                 ave[np + j]    -= dat[np + j]*cs - dat[np + j +1]*si;
04304                                 ave[np + j +1] -= dat[np + j]*si + dat[np + j +1]*cs;
04305                         }
04306                 }
04307         }
04308         avep->update();
04309         EXITFUNC;
04310 }
04311 
04312 
04313 #undef    QUADPI
04314 #undef    PI2
04315 
04316 #undef  numr
04317 #undef  circ
04318 
04319 
04320 #define QUADPI   3.141592653589793238462643383279502884197
04321 #define PI2      QUADPI*2
04322 #define deg_rad  QUADPI/180.0
04323 #define rad_deg  180.0/QUADPI
04324 
04325 struct ori_t
04326 {
04327     int iphi;
04328     int itht;
04329     int id;
04330 };
04331 
04332 
04333 struct cmpang
04334 {
04335     bool operator()( const ori_t& a, const ori_t& b )
04336     {
04337         if( a.itht != b.itht )
04338         {
04339             return a.itht < b.itht;
04340         }
04341 
04342         return a.iphi < b.iphi;
04343     }
04344 };
04345 
04346 //helper function for the weights calculation by Voronoi to Cml
04347 vector<double> Util::cml_weights(const vector<float>& cml){
04348         static const int NBIN = 100;
04349         int nline=cml.size()/2;
04350         vector<double> weights(nline);
04351 
04352         vector<ori_t> angs(nline);
04353         for( int i=0; i < nline; ++i ) {
04354                 angs[i].iphi = int( NBIN*cml[2*i] );
04355                 angs[i].itht = int( NBIN*cml[2*i+1] );
04356                 if( angs[i].itht == 180*NBIN ) angs[i].itht = 0;
04357                 angs[i].id = i;
04358         }
04359 
04360         //std::cout << "# of angs: " << angs.size() << std::endl;
04361 
04362         std::sort( angs.begin(), angs.end(), cmpang() );
04363 
04364         vector<float> newphi;
04365         vector<float> newtht;
04366         vector< vector<int> > indices;
04367 
04368         int curt_iphi = -1;
04369         int curt_itht = -1;
04370         for(unsigned int i=0 ;i < angs.size(); ++i ) {
04371                 if( angs[i].iphi==curt_iphi && angs[i].itht==curt_itht ) {
04372                         Assert( indices.size() > 0 );
04373                         indices.back().push_back(angs[i].id);
04374                 } else {
04375                         curt_iphi = angs[i].iphi;
04376                         curt_itht = angs[i].itht;
04377 
04378                         newphi.push_back( float(curt_iphi)/NBIN );
04379                         newtht.push_back( float(curt_itht)/NBIN );
04380                         indices.push_back( vector<int>(1,angs[i].id) );
04381                 }
04382         }
04383 
04384         //std::cout << "# of indpendent ang: " << newphi.size() << std::endl;
04385 
04386 
04387         int num_agl = newphi.size();
04388 
04389         if(num_agl>2) {
04390                 vector<double> w=Util::vrdg(newphi, newtht);
04391 
04392                 Assert( w.size()==newphi.size() );
04393                 Assert( indices.size()==newphi.size() );
04394 
04395                 for(unsigned int i=0; i < newphi.size(); ++i ) {
04396                     /*
04397                     std::cout << "phi,tht,w,n: ";
04398                     std::cout << boost::format( "%10.3f" ) % newphi[i] << " ";
04399                     std::cout << boost::format( "%10.3f" ) % newtht[i] << " ";
04400                     std::cout << boost::format( "%8.6f"  ) % w[i] << " ";
04401                     std::cout << indices[i].size() << "(";
04402                     */
04403 
04404                     for(unsigned int j=0; j < indices[i].size(); ++j ) {
04405                             int id = indices[i][j];
04406                             weights[id] = w[i]/indices[i].size();
04407                             //std::cout << id << " ";
04408                     }
04409 
04410                     //std::cout << ")" << std::endl;
04411 
04412                 }
04413         } else {
04414                 cout<<"warning in Util.cml_weights"<<endl;
04415                 double val = PI2/float(nline);
04416                 for(int i=0; i<nline; i++)  weights[i]=val;
04417         }
04418 
04419         return weights;
04420 
04421 }
04422 
04423 /****************************************************
04424  * New code for common-lines
04425  ****************************************************/
04426 
04427 /*  This function drop a line (line) to an 2D image (img).
04428  *  The position of the line to the image is defined by (postline).
04429  *  The part of the line paste is defined by (offset), the begin position
04430  *  and (length) the size.
04431  */
04432 void Util::set_line(