autocorrelation.C

Go to the documentation of this file.
00001 /* Gnome gxsm - Gnome X Scanning Microscopy
00002  * universal STM/AFM/SARLS/SPALEED/... controlling and
00003  * data analysis software
00004  *
00005  * plugin_helper reports your answers as
00006 author          =Erik Muller
00007 pluginname              =autocorrelation
00008 pluginmenuentry         =Auto Correlation
00009 menupath                =Math/Statistics/
00010 entryplace              =Statistics
00011 shortentryplace =ST
00012 abouttext               =Computes the Auto-Correlation of a scan.
00013 smallhelp               =Calc. Auto Correlation from Scan
00014 longhelp                =The Auto-Correlation of a scan is given by the following Z*Z=IFFT (| FT(Z) |^2).
00015  * 
00016  * Gxsm Plugin Name: autocorrelation.C
00017  * ========================================
00018  * 
00019  * Copyright (C) 1999 The Free Software Foundation
00020  *
00021  * Authors:Erik Muller
00022  *
00023  * This program is free software; you can redistribute it and/or modify
00024  * it under the terms of the GNU General Public License as published by
00025  * the Free Software Foundation; either version 2 of the License, or
00026  * (at your option) any later version.
00027  *
00028  * This program is distributed in the hope that it will be useful,
00029  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00030  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00031  * GNU General Public License for more details.
00032  *
00033  * You should have received a copy of the GNU General Public License
00034  * along with this program; if not, write to the Free Software
00035  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
00036  */
00037 
00038 /* Please do not change the Begin/End lines of this comment section!
00039  * this is a LaTeX style section used for auto generation of the PlugIn Manual 
00040  * Chapter. Add a complete PlugIn documentation inbetween the Begin/End marks!
00041  * All "% PlugInXXX" commentary tags are mandatory
00042  * All "% OptPlugInXXX" tags are optional
00043  * --------------------------------------------------------------------------------
00044 % BeginPlugInDocuSection
00045 % PlugInDocuCaption: Autocorrelation
00046 % PlugInName: autocorrelation
00047 % PlugInAuthor: Erik Muller
00048 % PlugInAuthorEmail: emmuller@users.sourceforge.net
00049 % PlugInMenuPath: Math/Statistic/Auto Correlation
00050 
00051 % PlugInDescription
00052 Computes the autocorrelation of an image.
00053 
00054 \[ Z' = |\text{IFT} (\text{FT} (Z))| \]
00055 
00056 % PlugInUsage
00057 Call \GxsmMenu{Math/Statistic/Auto Correlation} to execute.
00058 
00059 % OptPlugInSources
00060 The active channel is used as data source.
00061 
00062 % OptPlugInDest
00063 The computation result is placed into an existing math channel, else
00064 into a new created math channel.
00065 
00066 % OptPlugInNotes
00067 The quadrants of the resulting invers spectrum are aligned in a way,
00068 that the intensity of by it self correlated pixels (distance zero) is
00069 found at the image center and not at all four edges.
00070 
00071 
00072 % EndPlugInDocuSection
00073  * -------------------------------------------------------------------------------- 
00074  */
00075 #include <complex>
00076 #include <gtk/gtk.h>
00077 #include "config.h"
00078 #include "gxsm/plugin.h"
00079 #include "gxsm/xsmmath.h"
00080 
00081 // Plugin Prototypes
00082 static void autocorrelation_init( void );
00083 static void autocorrelation_about( void );
00084 static void autocorrelation_configure( void );
00085 static void autocorrelation_cleanup( void );
00086 
00087 // Define Type of math plugin here, only one line should be commented in!!
00088 #define GXSM_ONE_SRC_PLUGIN__DEF
00089 // #define GXSM_TWO_SRC_PLUGIN__DEF
00090 
00091 // Math-Run-Function, use only one of (automatically done :=)
00092 #ifdef GXSM_ONE_SRC_PLUGIN__DEF
00093 // "OneSrc" Prototype
00094  static gboolean autocorrelation_run( Scan *Src, Scan *Dest );
00095 #else
00096 // "TwoSrc" Prototype
00097  static gboolean autocorrelation_run( Scan *Src1, Scan *Src2, Scan *Dest );
00098 #endif
00099 
00100 // Fill in the GxsmPlugin Description here
00101 GxsmPlugin autocorrelation_pi = {
00102   NULL,                   // filled in and used by Gxsm, don't touch !
00103   NULL,                   // filled in and used by Gxsm, don't touch !
00104   0,                      // filled in and used by Gxsm, don't touch !
00105   NULL,                   // The Gxsm-App Class Ref.pointer (called "gapp" in Gxsm) is 
00106                           // filled in here by Gxsm on Plugin load, 
00107                           // just after init() is called !!!
00108   // ----------------------------------------------------------------------
00109   // Plugins Name, CodeStly is like: Name-M1S|M2S-BG|F1D|F2D|ST|TR|Misc
00110   "autocorrelation-"
00111 #ifdef GXSM_ONE_SRC_PLUGIN__DEF
00112   "M1S"
00113 #else
00114   "M2S"
00115 #endif
00116   "-ST",
00117   // Plugin's Category - used to autodecide on Pluginloading or ignoring
00118   // NULL: load, else
00119   // example: "+noHARD +STM +AFM"
00120   // load only, if "+noHARD: no hardware" and Instrument is STM or AFM
00121   // +/-xxxHARD und (+/-INST or ...)
00122   NULL,
00123   // Description, is shown by PluginViewer (Plugin: listplugin, Tools->Plugin Details)
00124   "Computes the Auto-Correlation of a Scan.",
00125   // Author(s)
00126   "Erik Muller",
00127   // Menupath to position where it is appendet to
00128   N_("_Math/_Statistics/"),
00129   // Menuentry
00130   N_("Auto Correlation"),
00131   // help text shown on menu
00132   N_("Do a Auto-Correlation of the scan"),
00133   // more info...
00134   "Calc. Auto Correlation of Scan",
00135   NULL,          // error msg, plugin may put error status msg here later
00136   NULL,          // Plugin Status, managed by Gxsm, plugin may manipulate it too
00137   // init-function pointer, can be "NULL", 
00138   // called if present at plugin load
00139   autocorrelation_init,  
00140   // query-function pointer, can be "NULL", 
00141   // called if present after plugin init to let plugin manage it install itself
00142   NULL, // query should be "NULL" for Gxsm-Math-Plugin !!!
00143   // about-function, can be "NULL"
00144   // can be called by "Plugin Details"
00145   autocorrelation_about,
00146   // configure-function, can be "NULL"
00147   // can be called by "Plugin Details"
00148   autocorrelation_configure,
00149   // run-function, can be "NULL", if non-Zero and no query defined, 
00150   // it is called on menupath->"plugin"
00151   NULL, // run should be "NULL" for Gxsm-Math-Plugin !!!
00152   // cleanup-function, can be "NULL"
00153   // called if present at plugin removeal
00154   autocorrelation_cleanup
00155 };
00156 
00157 // special math Plugin-Strucure, use
00158 // GxsmMathOneSrcPlugin autocorrelation_m1s_pi -> "OneSrcMath"
00159 // GxsmMathTwoSrcPlugin autocorrelation_m2s_pi -> "TwoSrcMath"
00160 #ifdef GXSM_ONE_SRC_PLUGIN__DEF
00161  GxsmMathOneSrcPlugin autocorrelation_m1s_pi
00162 #else
00163  GxsmMathTwoSrcPlugin autocorrelation_m2s_pi
00164 #endif
00165  = {
00166    // math-function to run, see prototype(s) above!!
00167    autocorrelation_run
00168  };
00169 
00170 // Text used in Aboutbox, please update!!
00171 static const char *about_text = N_("Gxsm autocorrelation Plugin\n\n"
00172                                    "Computes the Auto-Correlation of a scan:\n"
00173                                    "The Auto-Correlation of a scan is computed\n"
00174                                    "by FT the source Scan, setting the phase\n"
00175                                    "to zero and doing the IFT.");
00176 
00177 // Symbol "get_gxsm_plugin_info" is resolved by dlsym from Gxsm, used to get Plugin's info!! 
00178 // Essential Plugin Function!!
00179 GxsmPlugin *get_gxsm_plugin_info ( void ){ 
00180   autocorrelation_pi.description = g_strdup_printf(N_("Gxsm MathOneArg autocorrelation plugin %s"), VERSION);
00181   return &autocorrelation_pi; 
00182 }
00183 
00184 // Symbol "get_gxsm_math_one|two_src_plugin_info" is resolved by dlsym from Gxsm, 
00185 // used to find out which Math Type the Plugin is!! 
00186 // Essential Plugin Function!!
00187 #ifdef GXSM_ONE_SRC_PLUGIN__DEF
00188 GxsmMathOneSrcPlugin *get_gxsm_math_one_src_plugin_info( void ) {
00189   return &autocorrelation_m1s_pi; 
00190 }
00191 #else
00192 GxsmMathTwoSrcPlugin *get_gxsm_math_two_src_plugin_info( void ) { 
00193   return &autocorrelation_m2s_pi; 
00194 }
00195 #endif
00196 
00197 
00198 /* Here we go... */
00199 // init-Function
00200 static void autocorrelation_init(void)
00201 {
00202   PI_DEBUG (DBG_L2, "autocorrelation Plugin Init");
00203 }
00204 
00205 // about-Function
00206 static void autocorrelation_about(void)
00207 {
00208   const gchar *authors[] = { autocorrelation_pi.authors, NULL};
00209   gtk_widget_show(gnome_about_new ( autocorrelation_pi.name,
00210                                     VERSION,
00211                                     N_("(C) 2000 the Free Software Foundation"),
00212                                     about_text,
00213                                     authors,
00214                                     NULL, NULL, NULL
00215                                     ));
00216 }
00217 
00218 int WindowDefault=0;
00219 int WindowLast=0;
00220 
00221 int window_callback(GtkComboBox *widget, gpointer data){
00222         WindowDefault =  gtk_combo_box_get_active (widget);
00223         return 0;
00224 }
00225 
00226 // configure-Function
00227 static void autocorrelation_configure(void)
00228 {
00229 
00230 
00231 }
00232 
00233 // cleanup-Function
00234 static void autocorrelation_cleanup(void)
00235 {
00236   PI_DEBUG (DBG_L2, "autocorrelation Plugin Cleanup");
00237 }
00238 
00239 
00240 // run-Function
00241  static gboolean autocorrelation_run(Scan *Src, Scan *Dest)
00242 { 
00243 
00244 /*-------------------------------------------------*/
00245 
00246         // Selects the data in the rectangle if there is a rectangle
00247         // else, uses all the data
00248         int StartX=0,EndX=0,StartY=0,EndY=0;
00249 
00250         EndX=Src->mem2d->GetNx();
00251         EndY=Src->mem2d->GetNy();
00252 
00253         double hi, lo, z;
00254         int success = FALSE;
00255         int n_obj = Src->number_of_object ();
00256         Point2D p[2];
00257 
00258         while (n_obj--){
00259                 scan_object_data *obj_data = Src->get_object_data (n_obj);
00260                 
00261                 if (strncmp (obj_data->get_name (), "Rectangle", 9) )
00262                         continue; // only points are used!
00263                 
00264                 if (obj_data->get_num_points () != 2) 
00265                         continue; // sth. is weired!
00266                 
00267                 double x,y;
00268                 obj_data->get_xy_pixel (0, x, y);
00269                 p[0].x = (int)x; p[0].y = (int)y;
00270                 obj_data->get_xy_pixel (1, x, y);
00271                 p[1].x = (int)x; p[1].y = (int)y;
00272                 
00273                 StartX=p[0].x; EndX=p[1].x;
00274                 StartY=p[0].y; EndY=p[1].y;
00275 
00276                 success = TRUE;
00277                 break;
00278         }
00279         
00280         // If the box is outside the scan area...return an error
00281         if (StartX < 0 | StartY < 0 | EndX > Src->mem2d->GetNx() | EndY > Src->mem2d->GetNy() )
00282                 return MATH_SELECTIONERR;
00283 
00284 /* ---------------------------------------------------------------- */
00285 
00286         GtkWidget *dialog, *label, *wmenu;
00287 //      GtkWidget *image;
00288 //      image = gtk_image_new_from_file ("/home/emuller/Gxsm-2.0/plug-ins/math/statistik/test.png");
00289 
00290         dialog = gtk_dialog_new_with_buttons ("Message",
00291                                               NULL,
00292                                               //(GtkDialogFlags)(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT),
00293                                               GTK_DIALOG_MODAL,
00294                                               GTK_STOCK_OK,
00295                                               GTK_RESPONSE_NONE,                                           
00296                                               NULL);
00297         
00298         wmenu = gtk_combo_box_new_text ();
00299         
00300         gtk_combo_box_append_text (GTK_COMBO_BOX (wmenu),"No Window");
00301         gtk_combo_box_append_text (GTK_COMBO_BOX (wmenu),"Hanning");
00302         gtk_combo_box_append_text (GTK_COMBO_BOX (wmenu),"Hamming");
00303         gtk_combo_box_append_text (GTK_COMBO_BOX (wmenu),"Bartlett");
00304         gtk_combo_box_append_text (GTK_COMBO_BOX (wmenu),"Blackman");
00305         gtk_combo_box_append_text (GTK_COMBO_BOX (wmenu),"Connes");
00306 
00307         gtk_signal_connect (GTK_OBJECT(wmenu),"changed", GTK_SIGNAL_FUNC (window_callback), (gpointer) 1 );
00308 
00309         gchar *message="Please chose a window function";
00310 
00311         /* Create the widgets */
00312         label = gtk_label_new (message);
00313         
00314         /* Ensure that the dialog box is destroyed when the user responds. */
00315         g_signal_connect_swapped (dialog,
00316                                   "response",                       
00317                                   G_CALLBACK (gtk_widget_destroy),
00318                                   dialog);
00319         
00320 
00321         /* Add the label, and show everything we've added to the dialog. */
00322 
00323 //      gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
00324 //                         image);
00325         gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
00326                            label);
00327 
00328         gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
00329                            wmenu);
00330         gtk_widget_show_all (dialog);
00331         gtk_dialog_run (GTK_DIALOG (dialog));
00332         
00333 /*-------------------------------------------------*/
00334         
00335         int window = WindowDefault;
00336         int Nx, Ny;
00337         Nx=(EndX-StartX);
00338         Ny=(EndY-StartY);
00339 
00340 
00341         // Set Dest to Float, Range: +/-100% =^= One Pixel
00342         Dest->mem2d->Resize(Nx, Ny, ZD_FLOAT);
00343 
00344         // allocate memory for the complex data and one line buffer
00345         fftw_complex *in1  = new fftw_complex [Nx*Ny];
00346         fftw_complex *in2  = new fftw_complex [Nx*Ny];
00347   
00348         fftw_complex *out1 = new fftw_complex [Nx*Ny];
00349         fftw_complex *out2 = new fftw_complex [Nx*Ny];
00350 
00351 
00352 /*-------------------------------------------------*/
00353 
00354         // Applies the window function
00355         double xfactor=1,yfactor=1;
00356 
00357         // Fill array with data and apply image window to the image
00358         for (int pos=0, line=StartY; line < EndY; ++line)
00359                 for (int col=StartX; col < EndX; ++col, ++pos){           
00360                        
00361                         if(window == 0){
00362                                 xfactor=1.0;
00363                                 yfactor=1.0;
00364                         }
00365                         else if(window == 1){
00366                                 xfactor = 0.5*(1.0+cos(2.0*M_PI*((line-StartY)-Ny/2.0)/Ny));
00367                                 yfactor = 0.5*(1.0+cos(2.0*M_PI*((col-StartX)-Nx/2.0)/Nx));
00368                         }
00369                         else if(window == 2){
00370                                 xfactor = 0.54+0.46*cos(2.0*M_PI*((line-StartY)-Ny/2.0)/Ny);
00371                                 yfactor = 0.54+0.46*cos(2.0*M_PI*((col-StartX)-Nx/2.0)/Nx);
00372                         }
00373                         else if(window == 3){
00374                                 xfactor=(1.0-2.0*sqrt(((line-StartY)-Ny/2.0)*(line-StartY-Ny/2.0))/Ny);
00375                                 yfactor=(1.0-2.0*sqrt(((col-StartX)-Nx/2.0)*((col-StartX)-Nx/2.0))/Nx);
00376                         }
00377                         else if(window == 4){
00378                                 xfactor = 0.42+0.5*cos(2.0*M_PI*((line-StartY)-Ny/2.0)/Ny)+0.08*cos(4.0*M_PI*((line-StartY)-Ny/2.0)/Ny);
00379                                 yfactor = 0.42+0.5*cos(2.0*M_PI*((col-StartX)-Nx/2.0)/Nx)+0.08*cos(4.0*M_PI*((col-StartX)-Nx/2.0)/Nx);
00380                         }
00381                         else if(window == 5){
00382                                 xfactor = (1.0-4.0*((line-StartY)-Ny/2.0)*((line-StartY)-Ny/2.0)/Ny/Ny)*(1.0-4.0*((line-StartY)-Ny/2.0)*((line-StartY)-Ny/2.0)/Ny/Ny);
00383                                 yfactor = (1.0-4.0*((col-StartX)-Nx/2.0)*((col-StartX)-Nx/2.0)/Nx/Nx)*(1.0-4.0*((col-StartX)-Nx/2.0)*((col-StartX)-Nx/2.0)/Nx/Nx);
00384                         }
00385                         
00386                         c_re(in1[pos]) =(Src->mem2d->GetDataPkt(col, line))*xfactor*yfactor;
00387                         c_im(in1[pos]) = 0.;                    
00388           }
00389 
00390 
00391 /*-------------------------------------------------*/
00392 
00393         // do the fourier transform
00394         // create plan for fft
00395         fftw_plan plan1 = fftw_plan_dft_2d (Ny, Nx, in1, out1, FFTW_FORWARD, FFTW_ESTIMATE);
00396         
00397         // compute fft
00398         fftw_execute (plan1);
00399 
00400         for(int i=0; i < Ny; ++i)
00401                 for(int j=0; j < Nx; ++j){
00402                         c_re(in2[j+Nx*i])=0.0;
00403                         c_im(in2[j+Nx*i])=0.0;                        
00404                         c_re(in2[j+Nx*i])=c_re(out1[j+Nx*i])*c_re(out1[j+Nx*i])+c_im(out1[j+Nx*i])*c_im(out1[j+Nx*i]);
00405                         c_im(in2[j+Nx*i])=c_im(out1[j+Nx*i])*c_re(out1[j+Nx*i])-c_re(out1[j+Nx*i])*c_im(out1[j+Nx*i]);
00406                 }
00407 
00408 
00409         fftw_plan plan2 = fftw_plan_dft_2d (Ny, Nx, in2, out2, FFTW_BACKWARD, FFTW_ESTIMATE);
00410         // compute fft
00411         fftw_execute (plan2);
00412 
00413 
00414 
00415         //Find Normalization factor
00416         double SumNorm=0;
00417         for(int i=0; i < Nx*Ny; i++){
00418                 SumNorm += c_re(in1[i])*c_re(in1[i]);
00419             }
00420 
00421 
00422 
00423         //WRITE DATA TO DEST
00424         for (int pos=0, i=0; i < Ny; ++i)
00425                 for (int j=0; j < Nx; ++j, ++pos){
00426                         Dest->mem2d->PutDataPkt(c_re(out2[pos])/SumNorm/Nx/Ny,//j, i) ;
00427                                      QSWP (j,Nx), 
00428                                      QSWP (i, Ny));
00429                 }
00430 
00431                                              
00432         // destroy plan
00433         fftw_destroy_plan (plan1);
00434         fftw_destroy_plan (plan2);
00435 
00436         
00437         // free memory
00438         delete in1;
00439         delete in2;
00440                                      
00441         delete out1;
00442         delete out2;
00443 
00444 
00445         Dest->mem2d->data->MkXLookup(0., Src->data.s.rx*Nx/Src->mem2d->GetNx());
00446         Dest->mem2d->data->MkYLookup(0., Src->data.s.ry*Ny/Src->mem2d->GetNy());
00447         UnitObj *u;
00448 //      Dest->data.SetZUnit(u=new LinUnit(" "," ",0.02328,0));
00449         Dest->data.SetZUnit(u=new LinUnit(" "," ",1.,0));
00450         Dest->data.SetXUnit(u=new LinUnit(" "," ",1.,0));
00451         Dest->data.SetYUnit(u=new LinUnit(" "," ",1.,0));
00452 
00453 
00454         Dest->data.s.dz=1.0;
00455         Dest->data.s.dx=1.0;
00456         Dest->data.s.dy=1.0;
00457         delete u;
00458 
00459 
00460 
00461    return MATH_OK;
00462         
00463 }
00464 

Generated on Sat Apr 1 09:04:22 2006 for GXSM by  doxygen 1.4.6