slopedir.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  * Quick nine points Gxsm Plugin GUIDE by PZ:
00006  * ------------------------------------------------------------
00007  * 1.) Make a copy of this "SlopeDir.C" to "your_plugins_name.C"!
00008  * 2.) Replace all "SlopeDir" by "your_plugins_name" 
00009  *     --> please do a search and replace starting here NOW!! (Emacs doese preserve caps!)
00010  * 3.) Decide: One or Two Source Math: see line 54
00011  * 4.) Fill in GxsmPlugin Structure, see below
00012  * 5.) Replace the "about_text" below a desired
00013  * 6.) * Optional: Start your Code/Vars definition below (if needed more than the run-fkt itself!), 
00014  *       Goto Line 155 ff. please, and see comment there!!
00015  * 7.) Fill in math code in SlopeDir_run(), 
00016  *     have a look at the Data-Access methods infos at end
00017  * 8.) Add SlopeDir.C to the Makefile.am in analogy to others
00018  * 9.) Make a "make; make install"
00019  * A.) Call Gxsm->Tools->reload Plugins, be happy!
00020  * ... That's it!
00021  * 
00022  * Gxsm Plugin Name: SlopeDir.C
00023  * ========================================
00024  * 
00025  * Copyright (C) 1999 The Free Software Foundation
00026  *
00027  * Authors: Percy Zahl <zahl@fkp.uni-hannover.de>
00028  * additional features: Andreas Klust <klust@fkp.uni-hannover.de>
00029  *
00030  * This program is free software; you can redistribute it and/or modify
00031  * it under the terms of the GNU General Public License as published by
00032  * the Free Software Foundation; either version 2 of the License, or
00033  * (at your option) any later version.
00034  *
00035  * This program is distributed in the hope that it will be useful,
00036  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00037  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00038  * GNU General Public License for more details.
00039  *
00040  * You should have received a copy of the GNU General Public License
00041  * along with this program; if not, write to the Free Software
00042  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
00043  */
00044 
00045 /* Please do not change the Begin/End lines of this comment section!
00046  * this is a LaTeX style section used for auto generation of the PlugIn Manual 
00047  * Chapter. Add a complete PlugIn documentation inbetween the Begin/End marks!
00048  * --------------------------------------------------------------------------------
00049 % BeginPlugInDocuSection
00050 % PlugInDocuCaption: Calculate in plane direction of gradient
00051 
00052 % PlugInName: SlopeDir
00053 
00054 % PlugInAuthor: Percy Zahl
00055 
00056 % PlugInAuthorEmail: zahl@users.sf.net
00057 
00058 % PlugInMenuPath: Math/Statistics/Slope Dir
00059 
00060 % PlugInDescription
00061 
00062 Calculation of the direction of the local slope (gradient) using a user
00063 defined facet size at each pixel as reference area.  A plane
00064 regression is performed at each pixel to find the best matching local
00065 facet of the given size. Its normal is used to find the gradients direction in plane.
00066 
00067 % PlugInUsage
00068 Activate chanel to use and call it from Menu \emph{Math/Statistics/Slope Dir}.
00069 
00070 % OptPlugInSources
00071 The active channel is used.
00072 
00073 % OptPlugInDest
00074 Existing Math channel, else newly created Math channel.
00075 
00076 % OptPlugInConfig
00077 Can set a default facet size, if set to zero it will ask at each call.
00078 
00079 % OptPlugInKnownBugs
00080 No bugs known.
00081 
00082 % EndPlugInDocuSection
00083  * -------------------------------------------------------------------------------- 
00084  */
00085 
00086 #include <gtk/gtk.h>
00087 #include "config.h"
00088 #include "gxsm/plugin.h"
00089 
00090 // Plugin Prototypes
00091 static void SlopeDir_init( void );
00092 static void SlopeDir_about( void );
00093 static void SlopeDir_configure( void );
00094 static void SlopeDir_cleanup( void );
00095 
00096 // Define Type of math plugin here, only one line should be commented in!!
00097 #define GXSM_ONE_SRC_PLUGIN__DEF
00098 // #define GXSM_TWO_SRC_PLUGIN__DEF
00099 
00100 // Math-Run-Function, use only one of (automatically done :=)
00101 #ifdef GXSM_ONE_SRC_PLUGIN__DEF
00102 // "OneSrc" Prototype
00103  static gboolean SlopeDir_run( Scan *Src, Scan *Dest );
00104 #else
00105 // "TwoSrc" Prototype
00106  static gboolean SlopeDir_run( Scan *Src1, Scan *Src2, Scan *Dest );
00107 #endif
00108 
00109 // Fill in the GxsmPlugin Description here
00110 GxsmPlugin SlopeDir_pi = {
00111   NULL,                   // filled in and used by Gxsm, don't touch !
00112   NULL,                   // filled in and used by Gxsm, don't touch !
00113   0,                      // filled in and used by Gxsm, don't touch !
00114   NULL,                   // The Gxsm-App Class Ref.pointer (called "gapp" in Gxsm) is 
00115                           // filled in here by Gxsm on Plugin load, 
00116                           // just after init() is called !!!
00117   // ----------------------------------------------------------------------
00118   // Plugins Name, CodeStly is like: Name-M1S|M2S-BG|F1D|F2D|ST|TR|Misc
00119   "SlopeDir-"
00120 #ifdef GXSM_ONE_SRC_PLUGIN__DEF
00121   "M1S"
00122 #else
00123   "M2S"
00124 #endif
00125   "-ST",
00126   // Plugin's Category - used to autodecide on Pluginloading or ignoring
00127   // NULL: load, else
00128   // example: "+noHARD +STM +AFM"
00129   // load only, if "+noHARD: no hardware" and Instrument is STM or AFM
00130   // +/-xxxHARD und (+/-INST or ...)
00131   NULL,
00132   // Description, is shown by PluginViewer (Plugin: listplugin, Tools->Plugin Details)
00133   " Calculates local slope direction (+/-180)!",                   
00134   // Author(s)
00135   "Percy Zahl",
00136   // Menupath to position where it is appendet to
00137   N_("_Math/_Statistics/"),
00138   // Menuentry
00139   N_("Slope Dir"),
00140   // help text shown on menu
00141   N_("Sorry, no help for SlopeDir filter!"),
00142   // more info...
00143   "no more info",
00144   NULL,          // error msg, plugin may put error status msg here later
00145   NULL,          // Plugin Status, managed by Gxsm, plugin may manipulate it too
00146   // init-function pointer, can be "NULL", 
00147   // called if present at plugin load
00148   SlopeDir_init,  
00149   // query-function pointer, can be "NULL", 
00150   // called if present after plugin init to let plugin manage it install itself
00151   NULL, // query should be "NULL" for Gxsm-Math-Plugin !!!
00152   // about-function, can be "NULL"
00153   // can be called by "Plugin Details"
00154   SlopeDir_about,
00155   // configure-function, can be "NULL"
00156   // can be called by "Plugin Details"
00157   SlopeDir_configure,
00158   // run-function, can be "NULL", if non-Zero and no query defined, 
00159   // it is called on menupath->"plugin"
00160   NULL, // run should be "NULL" for Gxsm-Math-Plugin !!!
00161   // cleanup-function, can be "NULL"
00162   // called if present at plugin removeal
00163   SlopeDir_cleanup
00164 };
00165 
00166 // special math Plugin-Strucure, use
00167 // GxsmMathOneSrcPlugin SlopeDir_m1s_pi -> "OneSrcMath"
00168 // GxsmMathTwoSrcPlugin SlopeDir_m2s_pi -> "TwoSrcMath"
00169 #ifdef GXSM_ONE_SRC_PLUGIN__DEF
00170  GxsmMathOneSrcPlugin SlopeDir_m1s_pi
00171 #else
00172  GxsmMathTwoSrcPlugin SlopeDir_m2s_pi
00173 #endif
00174  = {
00175    // math-function to run, see prototype(s) above!!
00176    SlopeDir_run
00177  };
00178 
00179 // Text used in Aboutbox, please update!!
00180 static const char *about_text = N_("Gxsm SlopeDir Plugin\n\n"
00181                                    "SlopeDir calculates the\n"
00182                                    "local Direction of Slope.");
00183 
00184 int FacetRadius=2;
00185 int FacetRadiusDefault=0;
00186 
00187 // Symbol "get_gxsm_plugin_info" is resolved by dlsym from Gxsm, used to get Plugin's info!! 
00188 // Essential Plugin Function!!
00189 GxsmPlugin *get_gxsm_plugin_info ( void ){ 
00190   SlopeDir_pi.description = g_strdup_printf(N_("Gxsm MathOneArg SlopeDir plugin %s"), VERSION);
00191   return &SlopeDir_pi; 
00192 }
00193 
00194 // Symbol "get_gxsm_math_one|two_src_plugin_info" is resolved by dlsym from Gxsm, 
00195 // used to find out which Math Type the Plugin is!! 
00196 // Essential Plugin Function!!
00197 #ifdef GXSM_ONE_SRC_PLUGIN__DEF
00198 GxsmMathOneSrcPlugin *get_gxsm_math_one_src_plugin_info( void ) {
00199   return &SlopeDir_m1s_pi; 
00200 }
00201 #else
00202 GxsmMathTwoSrcPlugin *get_gxsm_math_two_src_plugin_info( void ) { 
00203   return &SlopeDir_m2s_pi; 
00204 }
00205 #endif
00206 
00207 // 5.) Start here with the plugins code, vars def., etc.... here.
00208 // ----------------------------------------------------------------------
00209 //
00210 
00211 
00212 // init-Function
00213 static void SlopeDir_init(void)
00214 {
00215   PI_DEBUG (DBG_L2, "SlopeDir Plugin Init");
00216 }
00217 
00218 // about-Function
00219 static void SlopeDir_about(void)
00220 {
00221   const gchar *authors[] = { SlopeDir_pi.authors, NULL};
00222   gtk_widget_show(gnome_about_new ( SlopeDir_pi.name,
00223                                     VERSION,
00224                                     N_("(C) 2000 the Free Software Foundation"),
00225                                     about_text,
00226                                     authors,
00227                                     NULL, NULL, NULL
00228                                     ));
00229 }
00230 
00231 // configure-Function
00232 static void SlopeDir_configure(void)
00233 {
00234   double x = (double)FacetRadiusDefault;
00235   SlopeDir_pi.app->ValueRequest("Enter Value", "FacetRadius", 
00236                                 "Default FacetRadius (Pixel), if set to Zero I will ask later!",
00237                                 SlopeDir_pi.app->xsm->Unity, 
00238                                 1., 100., ".0f", &x);
00239   FacetRadiusDefault = (int)x;
00240 }
00241 
00242 // cleanup-Function
00243 static void SlopeDir_cleanup(void)
00244 {
00245   PI_DEBUG (DBG_L2, "SlopeDir Plugin Cleanup");
00246 }
00247 
00248 typedef struct {
00249   double b,ax,ay;
00250 }APlane;
00251 
00252 typedef struct {
00253   int Cline, Crow, Crx, Cry;
00254 }Facet;
00255 
00256 // Do E Regress
00257 void FacetERegress(Scan *Src, Facet *fac, APlane *ap){
00258   double sumi, sumiy, sumyq, sumiq, sumy, val;
00259   double ysumi, ysumiy, ysumyq, ysumiq, ysumy;
00260   double a, b, nx, ny, imean, ymean,ax,bx,ay,by;
00261   int line, i;
00262 
00263   sumi = sumiq = sumy = sumyq = sumiy = ax = ay = bx = by = 0.0;
00264   ysumi = ysumiq = ysumy = ysumyq = ysumiy = 0.0;
00265   nx = ny = 0.;
00266   
00267   for (i = -fac->Crx; i <= fac->Crx; ++i){
00268     sumiq += (double)(i)*(double)(i);
00269     sumi  += (double)i;
00270     nx += 1.;
00271   }
00272   imean = sumi / nx;
00273   for (line = -fac->Cry; line <= fac->Cry; line++) {
00274     sumy = sumyq = sumiy = 0.0;
00275     for (i = -fac->Crx; i <= fac->Crx; i++) {
00276       val = Src->mem2d->GetDataPkt(i+fac->Crow, line+fac->Cline);
00277       sumy   += val;
00278       sumyq  += val*val;
00279       sumiy  += val*i;
00280     }
00281     ymean = sumy / nx;
00282     a = (sumiy - nx * imean * ymean ) / (sumiq - nx * imean * imean);
00283     b =  ymean -  a * imean;
00284     ax += a;
00285     bx += b;
00286     /* Werte fuer y-linregress */
00287     ysumy  += b;
00288     ysumyq += b*b;
00289     ysumiy += b * line;
00290     ysumiq += (double)(line)*(double)(line);
00291     ysumi  += (double)line;
00292     ny     += 1.;
00293   }
00294   ax = ax/ny;
00295   bx = bx/ny;
00296   imean = ysumi / ny;
00297   ymean = ysumy / ny;
00298   ay = (ysumiy - ny * imean * ymean ) / (ysumiq - ny * imean * imean);
00299   by =  ymean - ay * imean;
00300 
00301   // E-Facet: Y = by + xi*ax + yi*ay
00302 
00303   ap->b  = by;
00304   ap->ax = ax;
00305   ap->ay = ay;
00306 }
00307 
00308 double Phi(double dx, double dy){
00309     double q23=0.;
00310     if(dx<0.){
00311         q23=180.;
00312         if(dy<0. )
00313           q23=-180;
00314     }
00315 
00316     if(fabs(dx)>1e-5)
00317       return q23+180.*atan(dy/dx)/M_PI;
00318     else return dy>0.?90.:-90.;
00319 }
00320 
00321 // run-Function
00322 #ifdef GXSM_ONE_SRC_PLUGIN__DEF
00323  static gboolean SlopeDir_run(Scan *Src, Scan *Dest)
00324 #else
00325  static gboolean SlopeDir_run(Scan *Src1, Scan *Src2, Scan *Dest)
00326 #endif
00327 {
00328   // put plugins math code here...
00329 
00330   if(FacetRadiusDefault)
00331     FacetRadius=FacetRadiusDefault;
00332   else{
00333       double x=(double)FacetRadius;
00334       SlopeDir_pi.app->ValueRequest("Enter Value", "FacetRadius", 
00335                                     "need FacetRadius (in Pixel)!",
00336                                     SlopeDir_pi.app->xsm->Unity, 
00337                                     1., 100., ".0f", &x);
00338       FacetRadius = (int)x;
00339   }
00340 
00341   if(   Src->mem2d->GetNx() <= 2*FacetRadius 
00342      || Src->mem2d->GetNy() <= 2*FacetRadius)
00343     return MATH_SIZEERR;
00344 
00345   Dest->mem2d->Resize(Dest->data.s.nx, Dest->data.s.ny, ZD_FLOAT);
00346   Dest->mem2d->data->MkXLookup(-Src->data.s.rx/2.,
00347                                +Src->data.s.rx/2.);
00348   Dest->mem2d->data->MkYLookup(0., Src->data.s.ry);
00349   UnitObj *u;
00350   Dest->data.SetZUnit(u=new UnitObj("°","°")); delete u;
00351   Dest->data.s.dz  = 1.;
00352   Dest->data.s.rz  = 90.;
00353  
00354   APlane ap;
00355   Facet  facet;
00356   facet.Crx   = FacetRadius;
00357   facet.Cry   = FacetRadius;
00358   for(int line=FacetRadius; line<Src->mem2d->GetNy()-FacetRadius; ++line){
00359     gchar *mld = g_strdup_printf("Calculating SlopeDir: %d/%d", 
00360                                  line, Dest->data.s.ny);
00361     gapp->SetStatus(mld); 
00362     g_free(mld);
00363     SET_PROGRESS((double)line/(double)Dest->data.s.ny);
00364     for(int row=FacetRadius; row<Src->mem2d->GetNx()-FacetRadius; ++row){
00365       facet.Crow  = row;
00366       facet.Cline = line;
00367       FacetERegress(Src, &facet, &ap);
00368       Dest->mem2d->PutDataPkt(Phi(ap.ax, ap.ay), row, line);
00369     }
00370   }
00371   SET_PROGRESS(0.);
00372 
00373   return MATH_OK;
00374 }

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