fourierfilter.cpp

Go to the documentation of this file.
00001 /*
00002  * Author: Pawel A.Penczek, 09/09/2006 (Pawel.A.Penczek@uth.tmc.edu)
00003  * Copyright (c) 2000-2006 The University of Texas - Houston Medical School
00004  *
00005  * This software is issued under a joint BSD/GNU license. You may use the
00006  * source code in this file under either license. However, note that the
00007  * complete EMAN2 and SPARX software packages have some GPL dependencies,
00008  * so you are responsible for compliance with the licenses of these packages
00009  * if you opt to use BSD licensing. The warranty disclaimer below holds
00010  * in either instance.
00011  *
00012  * This complete copyright notice must be included in any revised version of the
00013  * source code. Additional authorship citations may be added, but existing
00014  * author citations must be preserved.
00015  *
00016  * This program is free software; you can redistribute it and/or modify
00017  * it under the terms of the GNU General Public License as published by
00018  * the Free Software Foundation; either version 2 of the License, or
00019  * (at your option) any later version.
00020  *
00021  * This program is distributed in the hope that it will be useful,
00022  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00023  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00024  * GNU General Public License for more details.
00025  *
00026  * You should have received a copy of the GNU General Public License
00027  * along with this program; if not, write to the Free Software
00028  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00029  *
00030  */
00031 
00032 #include "emdata.h"
00033 #include "processor.h"
00034 #include <algorithm>
00035 #include <cstdlib>
00036 
00037 using namespace EMAN;
00038 using namespace std;
00039 
00040 /*
00041  ******************************************************
00042  *DISCLAIMER
00043  * 03/29/05 P.A.Penczek
00044  * The University of Texas
00045  * Pawel.A.Penczek@uth.tmc.edu
00046  * Please do not modify the content of this document
00047  * without a written permission of the author.
00048  ******************************************************/
00049 /*
00050    Fourier filter
00051 Purpose: Apply selected Fourier space filters to 1-2-3D image.
00052 Method: Calculate FFT (if needed), apply the filter, if the input was real, do the iFFT, otherwise exit. .
00053 Real input -> padded workspace -> Reallocate workspace to real output.
00054 Complex input -> complex output.
00055 Input: f real or complex 1-2-3D image
00056 Output: 1-2-3D filtered image (real or complex).
00057  */
00058 EMData* Processor::EMFourierFilterFunc(EMData * fimage, Dict params, bool doInPlace)
00059 {
00060         int    nx, ny, nz, nyp2, nzp2, ix, iy, iz, jx, jy, jz;
00061         float  dx, dy, dz, omega=0, omegaL=0, omegaH=0;
00062         float  center=0, gamma=0, argx, argy, argz;
00063         float  aa, eps, ord=0, cnst=0, aL, aH, cnstL=0, cnstH=0;
00064         bool   complex_input;
00065         vector<float> table;
00066         int undoctf=0;
00067         float voltage=100.0f, ak=0.0f, cs=2.0f, ps=1.0f, b_factor=0.0f, wgh=0.1f, sign=-1.0f;
00068         if (!fimage)  return NULL;
00069         const int ndim = fimage->get_ndim();
00070         // Set amount of Fourier padding
00071         // dopad should be a bool, but EMObject Dict's can't store bools.
00072         int dopad = params["dopad"];
00073         int npad;
00074         if (0 == dopad) {
00075                 // no padding
00076                 npad = 1;
00077         } else if (1 == dopad) {
00078                 // 2x padding (hard-wired)
00079                 npad = 2;
00080         } else if (2 == dopad) {
00081                 npad = 4;
00082         } else {
00083                 // invalid entry
00084                 LOGERR("The dopad parameter must be 0 (false) or 1 (true)");
00085                 return NULL; // FIXME: replace w/ exception throw
00086         }
00087 
00088         // If the input image is already a Fourier image, then we want to
00089         // have this routine return a Fourier image
00090         complex_input = fimage->is_complex();
00091         if ( complex_input && 1 == dopad ) {
00092                 // Cannot pad Fourier input image
00093                 LOGERR("Cannot pad Fourier input image");
00094                 return NULL; // FIXME: replace w/ exception throw
00095         }
00096 
00097         Util::KaiserBessel* kbptr = 0;
00098 
00099 
00100         nx  = fimage->get_xsize();
00101         ny  = fimage->get_ysize();
00102         nz  = fimage->get_zsize();
00103                 // We manifestly assume no zero-padding here, just the
00104                 // necessary extension along x for the fft
00105         if (complex_input) nx = (nx - 2 + fimage->is_fftodd());
00106 
00107         const int nxp = npad*nx;
00108         const int nyp = (ny > 1) ? npad*ny : 1;
00109         const int nzp = (nz > 1) ? npad*nz : 1;
00110 
00111         int lsd2 = (nxp + 2 - nxp%2) / 2; // Extended x-dimension of the complex image
00112         int lsd3 = lsd2 - 1;
00113 
00114         //  Perform padding (if necessary) and fft, if the image is not already an fft image
00115         EMData* fp = NULL; // workspace image
00116         if (complex_input) {
00117                 if (doInPlace) {
00118                         // it's okay to change the original image
00119                         fp = fimage;
00120                 } else {
00121                         // fimage must remain pristine
00122                         fp = fimage->copy();
00123                 }
00124         } else {
00125                 if (doInPlace) {
00126                         if (npad>1) {
00127                                 LOGERR("Cannot pad with inplace filter");
00128                                 return NULL;    // FIXME, exception
00129                         }
00130                         fp=fimage;
00131                         fp->do_fft_inplace();
00132                 } else {
00133                         fp = fimage->norm_pad( false, npad, 1);
00134                         fp->do_fft_inplace();
00135                 }
00136         }
00137         fp->set_array_offsets(1,1,1);
00138 
00139         //  And the filter type is:
00140         int filter_type = params["filter_type"];
00141 
00142         nyp2 = nyp/2; nzp2 = nzp/2;
00143         dx = 1.0f/float(nxp);
00144 #ifdef _WIN32
00145         dy = 1.0f/_MAX(float(nyp),1.0f);
00146         dz = 1.0f/_MAX(float(nzp),1.0f);
00147 #else
00148         dy = 1.0f/std::max(float(nyp),1.0f);
00149         dz = 1.0f/std::max(float(nzp),1.0f);
00150 #endif  //_WIN32
00151         float dx2 = dx*dx, dy2 = dy*dy, dz2 = dz*dz;
00152 
00153         vector<float>::size_type tsize;
00154         float sz[3];
00155         float szmax;
00156         vector<float>::size_type maxsize;
00157         float xshift=0.0, yshift=0.0, zshift=0.0;
00158 
00159         // For the given type of filter set up any necessary parameters for the
00160         // filter calculation.  FIXME: Need parameter bounds checking!
00161         switch (filter_type) {
00162                 case TOP_HAT_LOW_PASS:
00163                 case TOP_HAT_HIGH_PASS:
00164                         omega = params["cutoff_abs"];
00165                         omega = 1.0f/omega/omega;
00166                         break;
00167                 case TOP_HAT_BAND_PASS:
00168                         omegaL = params["low_cutoff_frequency"];
00169                         omegaH = params["high_cutoff_frequency"];
00170                         omegaL = 1.0f/omegaL/omegaL;
00171                         omegaH = 1.0f/omegaH/omegaH;
00172                         break;
00173                 case TOP_HOMOMORPHIC:
00174                         omegaL = params["low_cutoff_frequency"];
00175                         omegaH = params["high_cutoff_frequency"];
00176                         gamma = params["value_at_zero_frequency"];
00177                         omegaL = 1.0f/omegaL/omegaL;
00178                         omegaH = 1.0f/omegaH/omegaH;
00179                         break;
00180                 case GAUSS_LOW_PASS:
00181                 case GAUSS_HIGH_PASS:
00182                 case GAUSS_INVERSE:
00183                         omega = params["cutoff_abs"];
00184                         omega = 0.5f/omega/omega;
00185                         break;
00186                 case GAUSS_BAND_PASS:
00187                         omega = params["cutoff_abs"];
00188                         center = params["center"];
00189                         omega = 0.5f/omega/omega;
00190                         break;
00191                 case GAUSS_HOMOMORPHIC:
00192                         omega = params["cutoff_abs"];
00193                         gamma = params["value_at_zero_frequency"];
00194                         omega = 0.5f/omega/omega;
00195                         gamma = 1.0f-gamma;
00196                         break;
00197                 case BUTTERWORTH_LOW_PASS:
00198                 case BUTTERWORTH_HIGH_PASS:
00199                         omegaL = params["low_cutoff_frequency"];
00200                         omegaH = params["high_cutoff_frequency"];
00201                         eps = 0.882f;
00202                         aa = 10.624f;
00203                         ord = 2.0f*log10(eps/sqrt(aa*aa-1.0f))/log10(omegaL/omegaH);
00204                         omegaL = omegaL/pow(eps,2.0f/ord);
00205                         break;
00206                 case BUTTERWORTH_HOMOMORPHIC:
00207                         omegaL = params["low_cutoff_frequency"];
00208                         omegaH = params["high_cutoff_frequency"];
00209                         gamma  = params["value_at_zero_frequency"];
00210                         eps = 0.882f;
00211                         aa  = 10.624f;
00212                         ord = 2.0f*log10(eps/sqrt(pow(aa,2)-1.0f))/log10(omegaL/omegaH);
00213                         omegaL = omegaL/pow(eps,2.0f/ord);
00214                         gamma = 1.0f-gamma;
00215                         break;
00216                 case SHIFT:
00217                         xshift = params["x_shift"];
00218                         yshift = params["y_shift"];
00219                         zshift = params["z_shift"];
00220                         //origin_type = params["origin_type"];
00221                         break;
00222                 case TANH_LOW_PASS:
00223                 case TANH_HIGH_PASS:
00224                         omega = params["cutoff_abs"];
00225                         aa = params["fall_off"];
00226                         cnst = float(pihalf/aa/omega);
00227                         break;
00228                 case TANH_HOMOMORPHIC:
00229                         omega = params["cutoff_abs"];
00230                         aa = params["fall_off"];
00231                         gamma = params["value_at_zero_frequency"];
00232                         cnst = float(pihalf/aa/omega);
00233                         gamma=1.0f-gamma;
00234                         break;
00235                 case TANH_BAND_PASS:
00236                         omegaL = params["low_cutoff_frequency"];
00237                         aL = params["Low_fall_off"];
00238                         omegaH = params["high_cutoff_frequency"];
00239                         aH = params["high_fall_off"];
00240                         cnstL = float(pihalf/aL/(omegaH-omegaL));
00241                         cnstH = float(pihalf/aH/(omegaH-omegaL));
00242                         break;
00243                 case CTF_:
00244                         dz       = params["defocus"];
00245                         cs       = params["Cs"];
00246                         voltage  = params["voltage"];
00247                         ps       = params["Pixel_size"];
00248                         b_factor = params["B_factor"];
00249                         wgh      = params["amp_contrast"];
00250                         sign     = params["sign"];
00251                         undoctf  = params["undo"];
00252                         break;
00253                 case KAISER_I0:
00254                 case KAISER_SINH:
00255                 case KAISER_I0_INVERSE:
00256                 case KAISER_SINH_INVERSE:
00257                         {
00258                                 float alpha = params["alpha"];
00259                                 int       K = params["K"];
00260                                 float     r = params["r"];
00261                                 float     v = params["v"];
00262                                 int       N = params["N"];
00263                                 kbptr = new Util::KaiserBessel(alpha, K, r, v, N);
00264                                 break;
00265                         }//without this bracket, compiler on water will complain about crosses initialization
00266                 case RADIAL_TABLE:
00267                         table = params["table"];
00268                         tsize = table.size();
00269                         sz[0] = static_cast<float>(lsd2);
00270                         sz[1] = static_cast<float>(nyp2);
00271                         sz[2] = static_cast<float>(nzp2);
00272                         szmax = *max_element(&sz[0],&sz[3]);
00273                         // for 2d, sqrt(2) = 1.414, relax a little bit to 1.6
00274                         // for 3d, sqrt(3) = 1.732, relax a little bit to 1.9
00275                         if (nzp > 1) {maxsize = vector<float>::size_type(1.9*szmax);} else {maxsize = vector<float>::size_type(1.6*szmax);}
00276                         for (vector<float>::size_type i = tsize+1; i < maxsize; i++) table.push_back(0.f);
00277                         break;
00278                 default:
00279                         LOGERR("Unknown Fourier Filter type");
00280                         return NULL; // FIXME: replace w/ exception throw
00281         }
00282         // Perform actual calculation
00283         //  Gaussian bandpass is the only one with center for frequencies
00284         if(filter_type == GAUSS_BAND_PASS) {
00285                 for ( iz = 1; iz <= nzp; iz++) {
00286                         jz=iz-1; if(jz>nzp2) jz=jz-nzp;
00287                         argz = (float(jz)-center)*(float(jz)-center)*dz2;
00288                         for ( iy = 1; iy <= nyp; iy++) {
00289                                 jy=iy-1; if(jy>nyp2) jy=jy-nyp;
00290                                 argy = argz + (float(jy)-center)*(float(jy)-center)*dy2;
00291                                 for ( ix = 1; ix <= lsd2; ix++) {
00292                                         jx=ix-1; argx = argy + (float(jx)-center)*(float(jx)-center)/float((nxp-1)*(nxp-1));
00293                                         // RHS of filter calculation for Gaussian bandpass
00294                                         fp->cmplx(ix,iy,iz) *= exp(-0.125f*argx*omega);
00295                                 }
00296                         }
00297                 }
00298         } else {
00299                 switch (filter_type) {
00300                         case TOP_HAT_LOW_PASS:
00301                                 for ( iz = 1; iz <= nzp; iz++) {
00302                                         jz=iz-1; if (jz>nzp2) jz=jz-nzp; argz = float(jz*jz)*dz2;
00303                                         for ( iy = 1; iy <= nyp; iy++) {
00304                                                 jy=iy-1; if (jy>nyp2) jy=jy-nyp; argy = argz + float(jy*jy)*dy2;
00305                                                 for ( ix = 1; ix <= lsd2; ix++) {
00306                                                         jx=ix-1; argx = argy + float(jx*jx)*dx2;
00307                                                         if (argx*omega>1.0f) fp->cmplx(ix,iy,iz) = 0;
00308                                                 }
00309                                         }
00310                                 }
00311                                 break;
00312                         case TOP_HAT_HIGH_PASS:
00313                                 for ( iz = 1; iz <= nzp; iz++) {
00314                                         jz=iz-1; if (jz>nzp2) jz=jz-nzp; argz = float(jz*jz)*dz2;
00315                                         for ( iy = 1; iy <= nyp; iy++) {
00316                                                 jy=iy-1; if (jy>nyp2) jy=jy-nyp; argy = argz + float(jy*jy)*dy2;
00317                                                 for ( ix = 1; ix <= lsd2; ix++) {
00318                                                         jx=ix-1; argx = argy + float(jx*jx)*dx2;
00319                                                         if (argx*omega<=1.0f) fp->cmplx(ix,iy,iz) = 0;
00320                                                 }
00321                                         }
00322                                 }                               break;
00323                         case TOP_HAT_BAND_PASS:
00324                                 for ( iz = 1; iz <= nzp; iz++) {
00325                                         jz=iz-1; if (jz>nzp2) jz=jz-nzp; argz = float(jz*jz)*dz2;
00326                                         for ( iy = 1; iy <= nyp; iy++) {
00327                                                 jy=iy-1; if (jy>nyp2) jy=jy-nyp; argy = argz + float(jy*jy)*dy2;
00328                                                 for ( ix = 1; ix <= lsd2; ix++) {
00329                                                         jx=ix-1; argx = argy + float(jx*jx)*dx2;
00330                                                         if (argx*omegaL<1.0f || argx*omegaH>=1.0f) fp->cmplx(ix,iy,iz) = 0;
00331                                                 }
00332                                         }
00333                                 }
00334                                 break;
00335                         case TOP_HOMOMORPHIC:
00336                                 for ( iz = 1; iz <= nzp; iz++) {
00337                                         jz=iz-1; if (jz>nzp2) jz=jz-nzp; argz = float(jz*jz)*dz2;
00338                                         for ( iy = 1; iy <= nyp; iy++) {
00339                                                 jy=iy-1; if (jy>nyp2) jy=jy-nyp; argy = argz + float(jy*jy)*dy2;
00340                                                 for ( ix = 1; ix <= lsd2; ix++) {
00341                                                         jx=ix-1; argx = argy + float(jx*jx)*dx2;
00342                                                         if (argx*omegaH>1.0f)      fp->cmplx(ix,iy,iz)  = 0.0f;
00343                                                         else if (argx*omegaL<=1.0f) fp->cmplx(ix,iy,iz) *= gamma;
00344                                                 }
00345                                         }
00346                                 }
00347                                 break;
00348                         case GAUSS_LOW_PASS :
00349                                 for ( iz = 1; iz <= nzp; iz++) {
00350                                         jz=iz-1; if (jz>nzp2) jz=jz-nzp; argz = float(jz*jz)*dz2;
00351                                         for ( iy = 1; iy <= nyp; iy++) {
00352                                                 jy=iy-1; if (jy>nyp2) jy=jy-nyp; argy = argz + float(jy*jy)*dy2;
00353                                                 for ( ix = 1; ix <= lsd2; ix++) {
00354                                                         jx=ix-1; argx = argy + float(jx*jx)*dx2;
00355                                                         fp->cmplx(ix,iy,iz) *= exp(-argx*omega);
00356                                                 }
00357                                         }
00358                                 }
00359                                 break;
00360                         case GAUSS_HIGH_PASS:
00361                                 for ( iz = 1; iz <= nzp; iz++) {
00362                                         jz=iz-1; if (jz>nzp2) jz=jz-nzp; argz = float(jz*jz)*dz2;
00363                                         for ( iy = 1; iy <= nyp; iy++) {
00364                                                 jy=iy-1; if (jy>nyp2) jy=jy-nyp; argy = argz + float(jy*jy)*dy2;
00365                                                 for ( ix = 1; ix <= lsd2; ix++) {
00366                                                         jx=ix-1; argx = argy + float(jx*jx)*dx2;
00367                                                         fp->cmplx(ix,iy,iz) *= 1.0f-exp(-argx*omega);
00368                                                 }
00369                                         }
00370                                 }
00371                                 break;
00372                         case GAUSS_HOMOMORPHIC:
00373                                 for ( iz = 1; iz <= nzp; iz++) {
00374                                         jz=iz-1; if (jz>nzp2) jz=jz-nzp; argz = float(jz*jz)*dz2;
00375                                         for ( iy = 1; iy <= nyp; iy++) {
00376                                                 jy=iy-1; if (jy>nyp2) jy=jy-nyp; argy = argz + float(jy*jy)*dy2;
00377                                                 for ( ix = 1; ix <= lsd2; ix++) {
00378                                                         jx=ix-1; argx = argy + float(jx*jx)*dx2;
00379                                                         fp->cmplx(ix,iy,iz) *= 1.0f-gamma*exp(-argx*omega);
00380                                                 }
00381                                         }
00382                                 }
00383                                 break;
00384                         case GAUSS_INVERSE :
00385                                 for ( iz = 1; iz <= nzp; iz++) {
00386                                         jz=iz-1; if (jz>nzp2) jz=jz-nzp; argz = float(jz*jz)*dz2;
00387                                         for ( iy = 1; iy <= nyp; iy++) {
00388                                                 jy=iy-1; if (jy>nyp2) jy=jy-nyp; argy = argz + float(jy*jy)*dy2;
00389                                                 for ( ix = 1; ix <= lsd2; ix++) {
00390                                                         jx=ix-1; argx = argy + float(jx*jx)*dx2;
00391                                                         fp->cmplx(ix,iy,iz) *= exp(argx*omega);
00392                                                 }
00393                                         }
00394                                 }
00395                                 break;
00396                         case KAISER_I0:   // K-B filter
00397                                 for ( iz = 1; iz <= nzp; iz++) {
00398                                         jz=iz-1; if (jz>nzp2) jz=jz-nzp;
00399                                         float nuz = jz*dz;
00400                                         for ( iy = 1; iy <= nyp; iy++) {
00401                                                 jy=iy-1; if (jy>nyp2) jy=jy-nyp;
00402                                                 float nuy = jy*dy;
00403                                                 for ( ix = 1; ix <= lsd2; ix++) {
00404                                                         jx=ix-1;
00405                                                         float nux = jx*dx;
00406                                                         //if (!kbptr)
00407                                                         //      throw
00408                                                         //              NullPointerException("kbptr null!");
00409                                                         switch (ndim) {
00410                                                                 case 3:
00411                                                                         fp->cmplx(ix,iy,iz) *= kbptr->i0win(nux)*kbptr->i0win(nuy)*kbptr->i0win(nuz);
00412                                                                         break;
00413                                                                 case 2:
00414                                                                         fp->cmplx(ix,iy,iz) *= kbptr->i0win(nux)*kbptr->i0win(nuy);
00415                                                                         break;
00416                                                                 case 1:
00417                                                                         fp->cmplx(ix,iy,iz)*= kbptr->i0win(nux);
00418                                                                         break;
00419                                                         }
00420                                                 }
00421                                         }
00422                                 }
00423                                 break;
00424                         case KAISER_SINH:   //  Sinh filter
00425                                 for ( iz = 1; iz <= nzp; iz++) {
00426                                         jz=iz-1; if (jz>nzp2) jz=jz-nzp;
00427                                         for ( iy = 1; iy <= nyp; iy++) {
00428                                                 jy=iy-1; if(jy>nyp2) jy=jy-nyp;
00429                                                 for ( ix = 1; ix <= lsd2; ix++) {
00430                                                         jx=ix-1;
00431                                                         //if (!kbptr)
00432                                                         //      throw
00433                                                         //              NullPointerException("kbptr null!");
00434                                                         switch (ndim) {
00435                                                                 case 3:
00436                                                                         fp->cmplx(ix,iy,iz)*= kbptr->sinhwin((float)jx)*kbptr->sinhwin((float)jy)*kbptr->sinhwin((float)jz);
00437                                                                         break;
00438                                                                 case 2:
00439                                                                         fp->cmplx(ix,iy,iz)*= kbptr->sinhwin((float)jx)*kbptr->sinhwin((float)jy);
00440                                                                         break;
00441                                                                 case 1:
00442                                                                         fp->cmplx(ix,iy,iz)*= kbptr->sinhwin((float)jx);
00443                                                                         //float argu = kbptr->sinhwin((float) jx);
00444                                                                         //cout << jx<<"  "<< nux<<"  "<<argu<<endl;
00445                                                                         break;
00446                                                         }
00447                                                 }
00448                                         }
00449                                 }
00450                                 break;
00451                         case KAISER_I0_INVERSE:   // 1./(K-B filter)
00452                                 for ( iz = 1; iz <= nzp; iz++) {
00453                                         jz=iz-1; if (jz>nzp2) jz=jz-nzp;
00454                                         float nuz = jz*dz;
00455                                         for ( iy = 1; iy <= nyp; iy++) {
00456                                                 jy=iy-1; if(jy>nyp2) jy=jy-nyp;
00457                                                 float nuy = jy*dy;
00458                                                 for ( ix = 1; ix <= lsd2; ix++) {
00459                                                         jx=ix-1;
00460                                                         float nux = jx*dx;
00461                                                 //if (!kbptr)
00462                                                 //      throw
00463                                                 //              NullPointerException("kbptr null!");
00464                                                         switch (ndim) {
00465                                                                 case 3:
00466                                                                         fp->cmplx(ix,iy,iz) /= (kbptr->i0win(nux)*kbptr->i0win(nuy)*kbptr->i0win(nuz));
00467                                                                         break;
00468                                                                 case 2:
00469                                                                         fp->cmplx(ix,iy,iz) /= (kbptr->i0win(nux)*kbptr->i0win(nuy));
00470                                                                         break;
00471                                                                 case 1:
00472                                                                         fp->cmplx(ix,iy,iz) /= kbptr->i0win(nux);
00473                                                                         break;
00474                                                         }
00475                                                 }
00476                                         }
00477                                 }
00478                                 break;
00479                         case KAISER_SINH_INVERSE:  // 1./sinh
00480                                 for ( iz = 1; iz <= nzp; iz++) {
00481                                         jz=iz-1; if (jz>nzp2) jz=jz-nzp;
00482                                         for ( iy = 1; iy <= nyp; iy++) {
00483                                                 jy=iy-1; if (jy>nyp2) jy=jy-nyp;
00484                                                 for ( ix = 1; ix <= lsd2; ix++) {
00485                                                         jx=ix-1;
00486                                                         //if (!kbptr)
00487                                                         //      throw
00488                                                         //              NullPointerException("kbptr null!");
00489                                                         switch (ndim) {
00490                                                                 case 3:
00491                                                                         fp->cmplx(ix,iy,iz) /= (kbptr->sinhwin((float)jx)*kbptr->sinhwin((float)jy)*kbptr->sinhwin((float)jz));
00492                                                                         break;
00493                                                                 case 2:
00494                                                                         fp->cmplx(ix,iy,iz) /= (kbptr->sinhwin((float)jx)*kbptr->sinhwin((float)jy));
00495                                                                         break;
00496                                                                 case 1:
00497                                                                         fp->cmplx(ix,iy,iz) /= kbptr->sinhwin((float)jx);
00498                                                                         //float argu = kbptr->sinhwin((float) jx);
00499                                                                         //cout << jx<<"  "<< nux<<"  "<<argu<<endl;
00500                                                                         break;
00501                                                         }
00502                                                 }
00503                                         }
00504                                 }
00505                                 break;
00506                         case BUTTERWORTH_LOW_PASS:
00507                                 for ( iz = 1; iz <= nzp; iz++) {
00508                                         jz=iz-1; if (jz>nzp2) jz=jz-nzp; argz = float(jz*jz)*dz2;
00509                                         for ( iy = 1; iy <= nyp; iy++) {
00510                                                 jy=iy-1; if (jy>nyp2) jy=jy-nyp; argy = argz + float(jy*jy)*dy2;
00511                                                 for ( ix = 1; ix <= lsd2; ix++) {
00512                                                         jx=ix-1; argx = argy + float(jx*jx)*dx2;
00513                                                         fp->cmplx(ix,iy,iz) *= sqrt(1.0f/(1.0f+pow(sqrt(argx)/omegaL,ord)));
00514                                                 }
00515                                         }
00516                                 }
00517                                 break;
00518                         case BUTTERWORTH_HIGH_PASS:
00519                                 for ( iz = 1; iz <= nzp; iz++) {
00520                                         jz=iz-1; if (jz>nzp2) jz=jz-nzp; argz = float(jz*jz)*dz2;
00521                                         for ( iy = 1; iy <= nyp; iy++) {
00522                                                 jy=iy-1; if (jy>nyp2) jy=jy-nyp; argy = argz + float(jy*jy)*dy2;
00523                                                 for ( ix = 1; ix <= lsd2; ix++) {
00524                                                         jx=ix-1; argx = argy + float(jx*jx)*dx2;
00525                                                         fp->cmplx(ix,iy,iz) *=  1.0f-sqrt(1.0f/(1.0f+pow(sqrt(argx)/omegaL,ord)));
00526                                                 }
00527                                         }
00528                                 }
00529                                 break;
00530                         case BUTTERWORTH_HOMOMORPHIC:
00531                                 for ( iz = 1; iz <= nzp; iz++) {
00532                                         jz=iz-1; if (jz>nzp2) jz=jz-nzp; argz = float(jz*jz)*dz2;
00533                                         for ( iy = 1; iy <= nyp; iy++) {
00534                                                 jy=iy-1; if (jy>nyp2) jy=jy-nyp; argy = argz + float(jy*jy)*dy2;
00535                                                 for ( ix = 1; ix <= lsd2; ix++) {
00536                                                         jx=ix-1; argx = argy + float(jx*jx)*dx2;
00537                                                         fp->cmplx(ix,iy,iz) *=  1.0f-gamma*sqrt(1.0f/(1.0f+pow(sqrt(argx)/omegaL,ord)));
00538                                                 }
00539                                         }
00540                                 }
00541                                 break;
00542                         case SHIFT:
00543                                 //if (origin_type) {
00544                                         for ( iz = 1; iz <= nzp; iz++) {
00545                                                 jz=iz-1; if (jz>nzp2) jz=jz-nzp;
00546                                                 for ( iy = 1; iy <= nyp; iy++) {
00547                                                         jy=iy-1; if (jy>nyp2) jy=jy-nyp;
00548                                                         for ( ix = 1; ix <= lsd2; ix++) {
00549                                                                 jx=ix-1;
00550                                                                 fp->cmplx(ix,iy,iz) *=  exp(-float(twopi)*iimag*(xshift*jx/nx + yshift*jy/ny+ zshift*jz/nz));
00551                                                         }
00552                                                 }
00553                                         }
00554                                 /*} else {
00555                                         for ( iz = 1; iz <= nzp; iz++) {
00556                                                 jz=iz-1; if (jz>nzp2) jz=jz-nzp;
00557                                                 if  (iz>nzp2) { kz=iz-nzp2; } else { kz=iz+nzp2; }
00558                                                 for ( iy = 1; iy <= nyp; iy++) {
00559                                                         jy=iy-1; if (jy>nyp2) jy=jy-nyp;
00560                                                         if  (iy>nyp2) { ky=iy-nyp2; } else { ky=iy+nyp2; }
00561                                                         for ( ix = 1; ix <= lsd2; ix++) {
00562                                                                 jx=ix-1;
00563                                                                 fp->cmplx(ix,ky,kz) *=  exp(-float(twopi)*iimag*(xshift*jx/nx + yshift*jy/ny+ zshift*jz/nz));
00564                                                         }
00565                                                 }
00566                                         }
00567                                 }*/
00568                                 break;
00569                         case TANH_LOW_PASS:
00570                                 for ( iz = 1; iz <= nzp; iz++) {
00571                                         jz=iz-1; if (jz>nzp2) jz=jz-nzp; argz = float(jz*jz)*dz2;
00572                                         for ( iy = 1; iy <= nyp; iy++) {
00573                                                 jy=iy-1; if (jy>nyp2) jy=jy-nyp; argy = argz + float(jy*jy)*dy2;
00574                                                 for ( ix = 1; ix <= lsd2; ix++) {
00575                                                         jx=ix-1; argx = argy + float(jx*jx)*dx2;
00576                                                         argx = sqrt(argx);
00577                                                         fp->cmplx(ix,iy,iz) *=  0.5f*(tanh(cnst*(argx+omega))-tanh(cnst*(argx-omega)));
00578                                                 }
00579                                         }
00580                                 }
00581                                 break;
00582                         case TANH_HIGH_PASS:
00583                                 for ( iz = 1; iz <= nzp; iz++) {
00584                                         jz=iz-1; if (jz>nzp2) jz=jz-nzp; argz = float(jz*jz)*dz2;
00585                                         for ( iy = 1; iy <= nyp; iy++) {
00586                                                 jy=iy-1; if (jy>nyp2) jy=jy-nyp; argy = argz + float(jy*jy)*dy2;
00587                                                 for ( ix = 1; ix <= lsd2; ix++) {
00588                                                         jx=ix-1; argx = argy + float(jx*jx)*dx2;
00589                                                         argx = sqrt(argx);
00590                                                         fp->cmplx(ix,iy,iz) *=  1.0f-0.5f*(tanh(cnst*(argx+omega))-tanh(cnst*(argx-omega)));
00591                                                 }
00592                                         }
00593                                 }
00594                                 break;
00595                         case TANH_HOMOMORPHIC:
00596                                 for ( iz = 1; iz <= nzp; iz++) {
00597                                         jz=iz-1; if (jz>nzp2) jz=jz-nzp; argz = float(jz*jz)*dz2;
00598                                         for ( iy = 1; iy <= nyp; iy++) {
00599                                                 jy=iy-1; if (jy>nyp2) jy=jy-nyp; argy = argz + float(jy*jy)*dy2;
00600                                                 for ( ix = 1; ix <= lsd2; ix++) {
00601                                                         jx=ix-1; argx = argy + float(jx*jx)*dx2;
00602                                                         argx = sqrt(argx);
00603                                                         fp->cmplx(ix,iy,iz) *= 1.0f-gamma*0.5f*(tanh(cnst*(argx+omega))-tanh(cnst*(argx-omega)));
00604                                                 }
00605                                         }
00606                                 }
00607                                 break;
00608                         case TANH_BAND_PASS:
00609                                 for ( iz = 1; iz <= nzp; iz++) {
00610                                         jz=iz-1; if (jz>nzp2) jz=jz-nzp; argz = float(jz*jz)*dz2;
00611                                         for ( iy = 1; iy <= nyp; iy++) {
00612                                                 jy=iy-1; if (jy>nyp2) jy=jy-nyp; argy = argz + float(jy*jy)*dy2;
00613                                                 for ( ix = 1; ix <= lsd2; ix++) {
00614                                                         jx=ix-1; argx = argy + float(jx*jx)*dx2;
00615                                                         argx = sqrt(argx);
00616                                                         fp->cmplx(ix,iy,iz) *= 0.5f*(tanh(cnstH*(argx+omegaH))-tanh(cnstH*(argx-omegaH))-tanh(cnstL*(argx+omegaL))+tanh(cnstL*(argx-omegaL)));
00617                                                 }
00618                                         }
00619                                 }
00620                                 break;
00621                         case RADIAL_TABLE:
00622                                 for ( iz = 1; iz <= nzp; iz++) {
00623                                         jz=iz-1; if (jz>nzp2) jz=jz-nzp; argz = float(jz*jz)*dz2;
00624                                         for ( iy = 1; iy <= nyp; iy++) {
00625                                                 jy=iy-1; if (jy>nyp2) jy=jy-nyp; argy = argz + float(jy*jy)*dy2;
00626                                                 for ( ix = 1; ix <= lsd2; ix++) {
00627                                                         jx=ix-1; argx = argy + float(jx*jx)*dx2;
00628                                                         float rf = sqrt( argx )*2.0f*lsd2;
00629                                                         int  ir = int(rf);
00630                                                         float df = rf - float(ir);
00631                                                         float f = table[ir] + df * (table[ir+1] - table[ir]); // (1-df)*table[ir]+df*table[ir+1];
00632                                                         fp->cmplx(ix,iy,iz) *= f;
00633                                                 }
00634                                         }
00635                                 }
00636                                 break;
00637                         case CTF_:
00638                                 for ( iz = 1; iz <= nzp; iz++) {
00639                                         jz=iz-1; if (jz>nzp2) jz=jz-nzp;
00640                                         for ( iy = 1; iy <= nyp; iy++) {
00641                                                 jy=iy-1; if (jy>nyp2) jy=jy-nyp;
00642                                                 for ( ix = 1; ix <= lsd2; ix++) {
00643                                                         jx=ix-1;
00644                                                         if(ny>1 && nz<=1 ) ak=sqrt(static_cast<float>(jx)/lsd3*static_cast<float>(jx)/lsd3 +
00645                                                                                      static_cast<float>(jy)/nyp2*static_cast<float>(jy)/nyp2)/ps/2.0f;
00646                                                         else if(ny<=1) ak=sqrt(static_cast<float>(jx)/lsd3*static_cast<float>(jx)/lsd3)/ps/2.0f;
00647                                                         else if(nz>1)  ak=sqrt(static_cast<float>(jx)/lsd3*static_cast<float>(jx)/lsd3 +
00648                                                                         static_cast<float>(jy)/nyp2*static_cast<float>(jy)/nyp2 +
00649                                                                             static_cast<float>(jz)/nzp2*static_cast<float>(jz)/nzp2)/ps/2.0f;
00650                                                                         float tf=Util::tf(dz, ak, voltage, cs, wgh, b_factor, sign);
00651                                                         if( undoctf == 1 )
00652                                                         {
00653                                                             if( tf>0 && tf <  1e-5 ) tf =  1e-5f;
00654                                                             if( tf<0 && tf > -1e-5 ) tf = -1e-5f;
00655                                                             fp->cmplx(ix,iy,iz) /= tf;
00656                                                         } else
00657                                                             fp->cmplx(ix,iy,iz) *= tf;
00658                                                 }
00659                                         }
00660                                 }
00661                                 break;
00662                 }
00663         }
00664         delete kbptr; kbptr = 0;
00665         if (!complex_input) {
00666                 fp->do_ift_inplace();
00667                 fp->depad();
00668         }
00669 
00670                 // Return a complex (Fourier) filtered image
00671                 // Note: fp and fimage are the _same_ object if doInPlace
00672                 // is true, so in that case fimage has been filtered.
00673                 // We always return an image (pointer), but if the function
00674                 // was called with doInPlace == true then the calling function
00675                 // will probably ignore the return value.
00676 
00677                 // ELSE Return a real-space filtered image
00678                 //
00679                 // On 12/15/2006 Wei Zhang comment:
00680                 // If input is reald and doInPlace == true, we might need delete fp after copy its
00681                 // data back to fimage, since fp is allocated inside this function and is ignored
00682                 // by caller if doInPlace == true. As a reminder, the caller is EMFourierFuncInPlace
00683                 //
00684         fp->set_array_offsets(0,0,0);
00685         fp->update();
00686         if (doInPlace && !complex_input) {
00687                 // copy workspace data into the original image
00688                 float* orig = fimage->get_data();
00689                 float* work = fp->get_data();
00690                 for (int i = 0; i < nx*ny*nz; i++) orig[i] = work[i];
00691                 fimage->update();
00692         }
00693         return fp;
00694         EXITFUNC;
00695 }

Generated on Sat Nov 21 02:19:15 2009 for EMAN2 by  doxygen 1.5.6