spasim.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  * Gxsm Plugin Name: spasim.C
00006  * ========================================
00007  * 
00008  * Copyright (C) 1999 The Free Software Foundation
00009  *
00010  * Authors: Percy Zahl <zahl@fkp.uni-hannover.de>
00011  * additional features: Andreas Klust <klust@fkp.uni-hannover.de>
00012  *
00013  * This program is free software; you can redistribute it and/or modify
00014  * it under the terms of the GNU General Public License as published by
00015  * the Free Software Foundation; either version 2 of the License, or
00016  * (at your option) any later version.
00017  *
00018  * This program is distributed in the hope that it will be useful,
00019  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00020  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00021  * GNU General Public License for more details.
00022  *
00023  * You should have received a copy of the GNU General Public License
00024  * along with this program; if not, write to the Free Software
00025  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
00026  */
00027 
00028 /* Please do not change the Begin/End lines of this comment section!
00029  * this is a LaTeX style section used for auto generation of the PlugIn Manual 
00030  * Chapter. Add a complete PlugIn documentation inbetween the Begin/End marks!
00031  * All "% PlugInXXX" commentary tags are mandatory
00032  * All "% OptPlugInXXX" tags are optional
00033  * --------------------------------------------------------------------------------
00034 % BeginPlugInDocuSection
00035 % PlugInDocuCaption: SPA--LEED simulation
00036 % PlugInName: spasim
00037 % PlugInAuthor: Percy Zahl
00038 % PlugInAuthorEmail: zahl@users.sf.net
00039 % PlugInMenuPath: Math/Statistik/SPALEED Sim.
00040 
00041 % PlugInDescription
00042  This Plugin simulates a SPA-LEED measurement (asks for the electron
00043  wave lenght $\lambda$ as input) using the following transformation:
00044 
00045 \begin{enumerate}
00046 \item phase transformation, using 
00047   \[e^\frac{2\pi i Z(x,y)}{\lambda}\]
00048 \item 2 dim. fourier transformation of the phase transformed image
00049 \item the resulting intensity is stored: $|FT(\text{phase trans. image})|^2$
00050 \end{enumerate}
00051 
00052 The resulting scan is scaled to have a size of $\pm100$ (full width is
00053 one. To automatically calculate realspace dimensions $\Gamma$ from
00054 inverse of spot separation (e.g. from center (0,0) to some spot or
00055 lenght of the line object) enable \GxsmEmph{InvAng} with the PlugIn configurator!
00056 By default coordinates in pixels  are used (center is (0,0)).
00057 
00058 \GxsmNote{Remember: One pixel distance (e.g. in X) corresponds to the
00059 full width of the original picture!}
00060 
00061 % PlugInUsage
00062 Call from \GxsmMenu{Math/Statistics/SPALEED Sim.} and input $\lambda$
00063 in Angstroems.
00064 
00065 % OptPlugInSources
00066 The active channel is used as data source.
00067 
00068 %% OptPlugInObjects
00069 %A optional rectangle is used for data extraction...
00070 
00071 % OptPlugInDest
00072 The computation result is placed into an existing math channel, else into a new created math channel.
00073 
00074 % OptPlugInConfig
00075 Using the Plug-In configurator you can preset the wave lenght $\lambda$.
00076 
00077 %% OptPlugInFiles
00078 %Does it uses, needs, creates any files? Put info here!
00079 
00080 % OptPlugInKnownBugs
00081 The show-line object did not work with the \GxsmEmph{InvAng} setting
00082 -- sorry, but you can still save the data, but it will not show any
00083 profile.
00084 
00085 %% OptPlugInNotes
00086 
00087 % OptPlugInHints
00088 You may want to carefully background correct you image before! Check
00089 also for correct step heights, if applicable.
00090 
00091 
00092 % EndPlugInDocuSection
00093  * -------------------------------------------------------------------------------- 
00094  */
00095 
00096 #include <gtk/gtk.h>
00097 #include "config.h"
00098 #include "gxsm/plugin.h"
00099 
00100 static void spasim_init( void );
00101 static void spasim_about( void );
00102 static void spasim_configure( void );
00103 static void spasim_cleanup( void );
00104 static gboolean spasim_run( Scan *Src, Scan *Dest );
00105 
00106 GxsmPlugin spasim_pi = {
00107         NULL,
00108         NULL,
00109         0,
00110         NULL,
00111         "Spasim-M1S-F1D",
00112         NULL, //"-SPALEED -ELSLEED",
00113         NULL,
00114         "Percy Zahl",
00115         N_("_Math/_Statistics/"),
00116         N_("SPALEED Sim."),
00117         N_("Simulate SPALEED!"),
00118         "no more info",
00119         NULL,
00120         NULL,
00121         spasim_init,
00122         NULL,
00123         spasim_about,
00124         spasim_configure,
00125         NULL,
00126         spasim_cleanup
00127 };
00128 
00129 GxsmMathOneSrcPlugin spasim_m1s_pi = {
00130         spasim_run
00131 };
00132 
00133 static const char *about_text = N_("Gxsm Spasim Plugin\n\n"
00134                                    "This Plugin simulates a SPA-LEED measurement (WaveLenght as input)\n"
00135                                    "on the Src-Channel's Scan:\n"
00136                                    "1.) Phase Transformation, using e^(2pi i Z(x,y)/WaveLength)\n"
00137                                    "2.) 2D FT( Phase Transformed Image)\n"
00138                                    "3.) Result = |FT(\")|^2");
00139 
00140 double WaveLengthDefault=0.0;
00141 int EnableInvAng=0;
00142 double WaveLengthLast=3.141;
00143 
00144 GxsmPlugin *get_gxsm_plugin_info ( void ){ 
00145         spasim_pi.description = g_strdup_printf(N_("Gxsm MathOneArg spasim plugin %s"), VERSION);
00146         return &spasim_pi; 
00147 }
00148 
00149 GxsmMathOneSrcPlugin *get_gxsm_math_one_src_plugin_info( void ) { 
00150         return &spasim_m1s_pi; 
00151 }
00152 
00153 static void spasim_init(void)
00154 {
00155         PI_DEBUG (DBG_L2, "Spasim Plugin Init");
00156 }
00157 
00158 static void spasim_about(void)
00159 {
00160         const gchar *authors[] = { spasim_pi.authors, NULL};
00161         gtk_widget_show(gnome_about_new ( spasim_pi.name,
00162                                           VERSION,
00163                                     N_("(C) 2000 the Free Software Foundation"),
00164                                     about_text,
00165                                     authors,
00166                                     NULL, NULL, NULL
00167                                     ));
00168 }
00169 
00170 static void spasim_configure(void)
00171 {
00172         double flg;
00173         spasim_pi.app->ValueRequest("Enter Value", "WaveLength", 
00174                                     "Default WaveLength, if set to Zero I will ask later!",
00175                                     spasim_pi.app->xsm->Z_Unit, 
00176                                     0., 1000., ".3f", &WaveLengthDefault);
00177         flg = EnableInvAng;
00178         spasim_pi.app->ValueRequest("Configure", "Enable InvAng (0/1)?", 
00179                                     "Use inv Ang for lenght scale?\n"
00180                                     "(Note: sorry, but profile won't work w this!)",
00181                                     spasim_pi.app->xsm->Unity, 
00182                                     0., 1., ".0f", &flg);
00183         EnableInvAng=flg>0?1:0;
00184 }
00185 
00186 static void spasim_cleanup(void)
00187 {
00188         PI_DEBUG (DBG_L2, "Spasim Plugin Cleanup");
00189 }
00190 
00191 static gboolean spasim_run(Scan *Src, Scan *Dest)
00192 {
00193         double WaveLength = WaveLengthLast;
00194 
00195         if(fabs(WaveLengthDefault) > 1e-10)
00196                 WaveLength = WaveLengthDefault;
00197         else
00198                 spasim_pi.app->ValueRequest("Enter Value", "WaveLength", 
00199                                             "I need WaveLength for SpaSim!",
00200                                             spasim_pi.app->xsm->Z_Unit, 
00201                                             1e-3, 1e3, ".3f", &WaveLength);
00202         WaveLengthLast = WaveLength;
00203 
00204 // SPA-LEED image simulation
00205         PI_DEBUG (DBG_L2, "F2D SpaSim");
00206 
00207         // Set Dest to Float, Range: +/-100% =^= One Pixel
00208         Dest->mem2d->Resize(Dest->data.s.nx, Dest->data.s.ny, ZD_FLOAT);
00209 //      Dest->mem2d->data->MkXLookup(-100., 100.);
00210 //      Dest->mem2d->data->MkYLookup(-100., 100.);
00211         Dest->mem2d->data->MkXLookup(-Src->mem2d->GetNx()/2, Src->mem2d->GetNx()/2);
00212         Dest->mem2d->data->MkYLookup(-Src->mem2d->GetNy()/2, Src->mem2d->GetNy()/2);
00213         if (EnableInvAng){
00214                 InvUnit ux("invA","invA", "X Lenght", Src->data.s.rx);
00215                 InvUnit uy("invA","invA", "Y Lenght", Src->data.s.ry);
00216                 Dest->data.SetXUnit(&ux);
00217                 Dest->data.SetYUnit(&uy);
00218         }else{
00219                 LinUnit ux("pix","pix", "X pos");
00220                 LinUnit uy("pix","pix", "Y pos");
00221                 Dest->data.SetXUnit(&ux);
00222                 Dest->data.SetYUnit(&uy);
00223         }
00224         LinUnit lu("CPS","CPS", "Int.");
00225         Dest->data.SetZUnit(&lu);
00226 
00227         // allocate memory for the complex data and one line buffer
00228         fftw_complex *in  = new fftw_complex [Src->mem2d->GetNy() * Src->mem2d->GetNx()];
00229         fftw_complex *out = new fftw_complex [Src->mem2d->GetNy() * Src->mem2d->GetNx()];
00230         // uses row-major format:
00231         // pos = Src->mem2d->GetNy ()*col + line;
00232 
00233         // transform scan data to complex data with correct phase
00234         for (int pos=0, col=0; col < Src->mem2d->GetNx (); ++col)
00235                 for (int line=0; line < Src->mem2d->GetNy (); ++line, ++pos){
00236                         double arg = 2.*M_PI * Src->data.s.dz 
00237                                 * Src->mem2d->GetDataPkt(col, line) 
00238                                 / WaveLength;
00239                         c_re(in[pos]) = cos(arg);
00240                         c_im(in[pos]) = sin(arg);
00241                 }
00242 
00243         // do the fourier transform
00244         // create plan for fft
00245         fftw_plan plan = fftw_plan_dft_2d (Src->mem2d->GetNx (), Src->mem2d->GetNy (), in, out, FFTW_FORWARD, FFTW_ESTIMATE);
00246         // compute fft
00247         fftw_execute (plan);
00248 
00249         // take the square value of the complex data and store to Dest [double]
00250         for (int pos=0, col=0; col < Src->mem2d->GetNx (); ++col)
00251                 for (int line=0; line < Src->mem2d->GetNy (); ++line, ++pos)
00252                         Dest->mem2d->PutDataPkt (  c_re (out[pos]) * c_re (out[pos]) 
00253                                                  + c_im (out[pos]) * c_im (out[pos]),
00254                                                    QSWP (col, Src->mem2d->GetNx ()), 
00255                                                    QSWP (line, Src->mem2d->GetNy ()) );
00256 
00257         // destroy plan
00258         fftw_destroy_plan (plan);
00259 
00260         // free memory
00261         delete in;
00262         delete out;
00263 
00264         return MATH_OK;
00265 }

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