AngularAnalysis.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          =Percy Zahl
00007 email                   =zahl@users.sf.net
00008 pluginname              =AngularAnalysis
00009 pluginmenuentry         =Angular Analysis
00010 menupath                =Math/Statistics/
00011 entryplace              =Statistics
00012 shortentryplace =ST
00013 abouttext               =Calculate all gradients and present slope, direction as polar histogramm
00014 smallhelp               =Angular Analysis in polar representation
00015 longhelp                =Calculate all gradients and present slope, direction as polar histogramm
00016  * 
00017  * Gxsm Plugin Name: AngularAnalysis.C
00018  * ========================================
00019  * 
00020  * Copyright (C) 1999 The Free Software Foundation
00021  *
00022  * Authors: Percy Zahl <zahl@fkp.uni-hannover.de>
00023  * additional features: Andreas Klust <klust@fkp.uni-hannover.de>
00024  *
00025  * This program is free software; you can redistribute it and/or modify
00026  * it under the terms of the GNU General Public License as published by
00027  * the Free Software Foundation; either version 2 of the License, or
00028  * (at your option) any later version.
00029  *
00030  * This program is distributed in the hope that it will be useful,
00031  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00032  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00033  * GNU General Public License for more details.
00034  *
00035  * You should have received a copy of the GNU General Public License
00036  * along with this program; if not, write to the Free Software
00037  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
00038  */
00039 
00040 
00041 /* Please do not change the Begin/End lines of this comment section!
00042  * this is a LaTeX style section used for auto generation of the PlugIn Manual 
00043  * Chapter. Add a complete PlugIn documentation inbetween the Begin/End marks!
00044  * All "% PlugInXXX" commentary tags are mandatory
00045  * All "% OptPlugInXXX" tags are optional and can be removed or commented in
00046  * --------------------------------------------------------------------------------
00047 % BeginPlugInDocuSection
00048 % PlugInDocuCaption: Angular Analysis
00049 % PlugInName: AngularAnalysis
00050 % PlugInAuthor: Percy Zahl
00051 % PlugInAuthorEmail: zahl@users.sf.net
00052 % PlugInMenuPath: Math/Statistics/Angular Analysis
00053 
00054 % PlugInDescription
00055 Calculate all local gradients and presents those in a polar histogram
00056 of slope as radius and direction as polar angle.
00057 
00058 % PlugInUsage
00059 Call \GxsmMenu{Math/Statistics/Angular Analysis}.
00060 
00061 %% OptPlugInSection: replace this by the section caption
00062 %all following lines until next tag are going into this section
00063 %...
00064 
00065 %% OptPlugInSubSection: replace this line by the subsection caption
00066 %all following lines until next tag are going into this subsection
00067 %...
00068 
00069 %% you can repeat OptPlugIn(Sub)Sections multiple times!
00070 
00071 %% OptPlugInSources
00072 %The active channel is used as data source.
00073 
00074 %% OptPlugInObjects
00075 %A optional rectangle is used for data extraction...
00076 
00077 %% OptPlugInDest
00078 %The computation result is placed into an existing math channel, else into a new created math channel.
00079 
00080 %% OptPlugInConfig
00081 %describe the configuration options of your plug in here!
00082 
00083 %% OptPlugInFiles
00084 %Does it uses, needs, creates any files? Put info here!
00085 
00086 %% OptPlugInRefs
00087 %Any references?
00088 
00089 %% OptPlugInKnownBugs
00090 %Are there known bugs? List! How to work around if not fixed?
00091 
00092 %% OptPlugInNotes
00093 %If you have any additional notes
00094 
00095 %% OptPlugInHints
00096 %Any tips and tricks?
00097 
00098 % EndPlugInDocuSection
00099  * -------------------------------------------------------------------------------- 
00100  */
00101 
00102 #include <gtk/gtk.h>
00103 #include "config.h"
00104 #include "gxsm/plugin.h"
00105 
00106 // Plugin Prototypes
00107 static void AngularAnalysis_init( void );
00108 static void AngularAnalysis_about( void );
00109 static void AngularAnalysis_configure( void );
00110 static void AngularAnalysis_cleanup( void );
00111 
00112 // Define Type of math plugin here, only one line should be commented in!!
00113 #define GXSM_ONE_SRC_PLUGIN__DEF
00114 // #define GXSM_TWO_SRC_PLUGIN__DEF
00115 
00116 // Math-Run-Function, use only one of (automatically done :=)
00117 #ifdef GXSM_ONE_SRC_PLUGIN__DEF
00118 // "OneSrc" Prototype
00119  static gboolean AngularAnalysis_run( Scan *Src, Scan *Dest );
00120 #else
00121 // "TwoSrc" Prototype
00122  static gboolean AngularAnalysis_run( Scan *Src1, Scan *Src2, Scan *Dest );
00123 #endif
00124 
00125 // Fill in the GxsmPlugin Description here
00126 GxsmPlugin AngularAnalysis_pi = {
00127   NULL,                   // filled in and used by Gxsm, don't touch !
00128   NULL,                   // filled in and used by Gxsm, don't touch !
00129   0,                      // filled in and used by Gxsm, don't touch !
00130   NULL,                   // The Gxsm-App Class Ref.pointer (called "gapp" in Gxsm) is 
00131                           // filled in here by Gxsm on Plugin load, 
00132                           // just after init() is called !!!
00133   // ----------------------------------------------------------------------
00134   // Plugins Name, CodeStly is like: Name-M1S|M2S-BG|F1D|F2D|ST|TR|Misc
00135   "AngularAnalysis-"
00136 #ifdef GXSM_ONE_SRC_PLUGIN__DEF
00137   "M1S"
00138 #else
00139   "M2S"
00140 #endif
00141   "-ST",
00142   // Plugin's Category - used to autodecide on Pluginloading or ignoring
00143   // NULL: load, else
00144   // example: "+noHARD +STM +AFM"
00145   // load only, if "+noHARD: no hardware" and Instrument is STM or AFM
00146   // +/-xxxHARD und (+/-INST or ...)
00147   NULL,
00148   // Description, is shown by PluginViewer (Plugin: listplugin, Tools->Plugin Details)
00149   "Calculate all gradients and present slope, direction as polar histogramm",                   
00150   // Author(s)
00151   "Percy Zahl",
00152   // Menupath to position where it is appendet to
00153   N_("_Math/_Statistics/"),
00154   // Menuentry
00155   N_("Angular Analysis"),
00156   // help text shown on menu
00157   N_("Calculate all gradients and present slope, direction as polar histogramm"),
00158   // more info...
00159   "Angular Analysis in polar representation",
00160   NULL,          // error msg, plugin may put error status msg here later
00161   NULL,          // Plugin Status, managed by Gxsm, plugin may manipulate it too
00162   // init-function pointer, can be "NULL", 
00163   // called if present at plugin load
00164   AngularAnalysis_init,  
00165   // query-function pointer, can be "NULL", 
00166   // called if present after plugin init to let plugin manage it install itself
00167   NULL, // query should be "NULL" for Gxsm-Math-Plugin !!!
00168   // about-function, can be "NULL"
00169   // can be called by "Plugin Details"
00170   AngularAnalysis_about,
00171   // configure-function, can be "NULL"
00172   // can be called by "Plugin Details"
00173   AngularAnalysis_configure,
00174   // run-function, can be "NULL", if non-Zero and no query defined, 
00175   // it is called on menupath->"plugin"
00176   NULL, // run should be "NULL" for Gxsm-Math-Plugin !!!
00177   // cleanup-function, can be "NULL"
00178   // called if present at plugin removeal
00179   AngularAnalysis_cleanup
00180 };
00181 
00182 // special math Plugin-Strucure, use
00183 // GxsmMathOneSrcPlugin AngularAnalysis_m1s_pi -> "OneSrcMath"
00184 // GxsmMathTwoSrcPlugin AngularAnalysis_m2s_pi -> "TwoSrcMath"
00185 #ifdef GXSM_ONE_SRC_PLUGIN__DEF
00186  GxsmMathOneSrcPlugin AngularAnalysis_m1s_pi
00187 #else
00188  GxsmMathTwoSrcPlugin AngularAnalysis_m2s_pi
00189 #endif
00190  = {
00191    // math-function to run, see prototype(s) above!!
00192    AngularAnalysis_run
00193  };
00194 
00195 // Plugin's config vars
00196 int FacetRadius  = 5;
00197 int PolSlices    = 90;
00198 int DataChannels = 60;
00199 double DataStart = 0.;
00200 double DataEnd   = 25.;
00201 int Vmode        = 1;
00202 
00203 // Text used in Aboutbox, please update!!
00204 static const char *about_text = N_("Gxsm AngularAnalysis Plugin\n\n"
00205                                    "Calculate all gradients and present slope, direction as polar histogramm");
00206 
00207 // Symbol "get_gxsm_plugin_info" is resolved by dlsym from Gxsm, used to get Plugin's info!! 
00208 // Essential Plugin Function!!
00209 GxsmPlugin *get_gxsm_plugin_info ( void ){ 
00210   AngularAnalysis_pi.description = g_strdup_printf(N_("Gxsm MathOneArg AngularAnalysis plugin %s"), VERSION);
00211   return &AngularAnalysis_pi; 
00212 }
00213 
00214 // Symbol "get_gxsm_math_one|two_src_plugin_info" is resolved by dlsym from Gxsm, 
00215 // used to find out which Math Type the Plugin is!! 
00216 // Essential Plugin Function!!
00217 #ifdef GXSM_ONE_SRC_PLUGIN__DEF
00218 GxsmMathOneSrcPlugin *get_gxsm_math_one_src_plugin_info( void ) {
00219   return &AngularAnalysis_m1s_pi; 
00220 }
00221 #else
00222 GxsmMathTwoSrcPlugin *get_gxsm_math_two_src_plugin_info( void ) { 
00223   return &AngularAnalysis_m2s_pi; 
00224 }
00225 #endif
00226 
00227 /* Here we go... */
00228 // init-Function
00229 static void AngularAnalysis_init(void)
00230 {
00231   PI_DEBUG (DBG_L2, "AngularAnalysis Plugin Init");
00232 }
00233 
00234 // about-Function
00235 static void AngularAnalysis_about(void)
00236 {
00237   const gchar *authors[] = { AngularAnalysis_pi.authors, NULL};
00238   gtk_widget_show(gnome_about_new ( AngularAnalysis_pi.name,
00239                                     VERSION,
00240                                     N_("(C) 2000 the Free Software Foundation"),
00241                                     about_text,
00242                                     authors,
00243                                     NULL, NULL, NULL
00244                                     ));
00245 }
00246 
00247 // configure-Function
00248 static void AngularAnalysis_configure(void)
00249 {
00250   GtkWidget *dialog;
00251   GtkWidget *vbox;
00252   GtkWidget *hbox;
00253   GtkWidget *info;
00254   GtkWidget *input;
00255   Gtk_EntryControl *ec;
00256 
00257   dialog = gnome_dialog_new(_("Angular Analysis Setup"),
00258                             GNOME_STOCK_BUTTON_OK,
00259                             NULL); 
00260         
00261   gnome_dialog_set_close(GNOME_DIALOG(dialog), FALSE);
00262   gnome_dialog_close_hides(GNOME_DIALOG(dialog), FALSE);
00263   gnome_dialog_set_default(GNOME_DIALOG(dialog), 0);
00264 
00265   vbox = gtk_vbox_new (FALSE, 0);
00266   gtk_widget_show (vbox);
00267 
00268   gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(dialog)->vbox),
00269                      vbox, TRUE, TRUE, GNOME_PAD);
00270 
00271   info = gtk_label_new ("Polar Histogramm Setup");
00272   gtk_widget_show (info);
00273   gtk_box_pack_start(GTK_BOX(vbox), info, TRUE, TRUE, GNOME_PAD);
00274 
00275   input = AngularAnalysis_pi.app->mygtk_create_input("Facet Radius", vbox, hbox);
00276   ec = new Gtk_EntryControl(AngularAnalysis_pi.app->xsm->Unity, 
00277                            "Value out of range !", 
00278                            &FacetRadius, 
00279                            1., 100., ".0f", input);
00280 
00281   input = AngularAnalysis_pi.app->mygtk_create_input("# angular slices", vbox, hbox);
00282   ec = new Gtk_EntryControl(AngularAnalysis_pi.app->xsm->Unity, 
00283                            "Value out of range !", 
00284                            &PolSlices, 
00285                            2., 3600., ".0f", input);
00286 
00287   input = AngularAnalysis_pi.app->mygtk_create_input("# data channels", vbox, hbox);
00288   ec = new Gtk_EntryControl(AngularAnalysis_pi.app->xsm->Unity, 
00289                            "Value out of range !",
00290                            &DataChannels,
00291                            2., 100000., ".0f", input);
00292 
00293   info = gtk_label_new ("Data Range (0...0 -> auto)");
00294   gtk_widget_show (info);
00295   gtk_box_pack_start(GTK_BOX(vbox), info, TRUE, TRUE, GNOME_PAD);
00296 
00297   input = AngularAnalysis_pi.app->mygtk_create_input("Data Start", vbox, hbox);
00298   ec = new Gtk_EntryControl(AngularAnalysis_pi.app->xsm->Unity, 
00299                            "Value out of range !",
00300                            &DataStart,
00301                            -1e10, 1e10, ".3f", input);
00302 
00303   input = AngularAnalysis_pi.app->mygtk_create_input("Data End", vbox, hbox);
00304   ec = new Gtk_EntryControl(AngularAnalysis_pi.app->xsm->Unity, 
00305                            "Value out of range !",
00306                            &DataEnd,
00307                            -1e10, 1e10, ".3f", input);
00308 
00309   input = AngularAnalysis_pi.app->mygtk_create_input("Vmode 1=cir,2=rect", vbox, hbox);
00310   ec = new Gtk_EntryControl(AngularAnalysis_pi.app->xsm->Unity, 
00311                            "Value out of range !",
00312                            &Vmode,
00313                            0., 10., ".0f", input);
00314 
00315   gtk_widget_show(dialog);
00316 
00317   gnome_dialog_run_and_close(GNOME_DIALOG(dialog));
00318 } 
00319 
00320 // cleanup-Function
00321 static void AngularAnalysis_cleanup(void)
00322 {
00323   PI_DEBUG (DBG_L2, "AngularAnalysis Plugin Cleanup");
00324 }
00325 
00326 typedef struct {
00327         double b,ax,ay;
00328 }APlane;
00329 
00330 typedef struct {
00331         int Cline, Crow, Crx, Cry;
00332 }Facet;
00333 
00334 // Do E Regress
00335 void FacetERegress(Scan *Src, Facet *fac, APlane *ap){
00336         double sumi, sumiy, sumyq, sumiq, sumy, val;
00337         double ysumi, ysumiy, ysumyq, ysumiq, ysumy;
00338         double a, b, nx, ny, imean, ymean,ax,bx,ay,by;
00339         int line, i;
00340 
00341         sumi = sumiq = sumy = sumyq = sumiy = ax = ay = bx = by = 0.0;
00342         ysumi = ysumiq = ysumy = ysumyq = ysumiy = 0.0;
00343         nx = ny = 0.;
00344   
00345         for (i = -fac->Crx; i <= fac->Crx; ++i){
00346                 sumiq += (double)(i)*(double)(i);
00347                 sumi  += (double)i;
00348                 nx += 1.;
00349         }
00350         imean = sumi / nx;
00351         for (line = -fac->Cry; line <= fac->Cry; line++) {
00352                 sumy = sumyq = sumiy = 0.0;
00353                 for (i = -fac->Crx; i <= fac->Crx; i++) {
00354                         val = Src->mem2d->GetDataPkt(i+fac->Crow, line+fac->Cline);
00355                         sumy   += val;
00356                         sumyq  += val*val;
00357                         sumiy  += val*i;
00358                 }
00359                 ymean = sumy / nx;
00360                 a = (sumiy - nx * imean * ymean ) / (sumiq - nx * imean * imean);
00361                 b =  ymean -  a * imean;
00362                 ax += a;
00363                 bx += b;
00364                 /* Werte fuer y-linregress */
00365                 ysumy  += b;
00366                 ysumyq += b*b;
00367                 ysumiy += b * line;
00368                 ysumiq += (double)(line)*(double)(line);
00369                 ysumi  += (double)line;
00370                 ny     += 1.;
00371         }
00372         ax = ax/ny;
00373         bx = bx/ny;
00374         imean = ysumi / ny;
00375         ymean = ysumy / ny;
00376         ay = (ysumiy - ny * imean * ymean ) / (ysumiq - ny * imean * imean);
00377         by =  ymean - ay * imean;
00378 
00379         // E-Facet: Y = by + xi*ax + yi*ay
00380 
00381         ap->b  = by;
00382         ap->ax = ax;
00383         ap->ay = ay;
00384 }
00385 
00386 double Phi(double dx, double dy){
00387         double q23=0.;
00388         if(dx<0.){
00389                 q23=180.;
00390                 if(dy<0. )
00391                         q23=-180;
00392         }
00393 
00394         if(fabs(dx)>1e-5)
00395                 return q23+180.*atan(dy/dx)/M_PI;
00396         else return dy>0.?90.:-90.;
00397 }
00398 
00399 void inline IncNumValPhi(double *n, int v, int p){ n[PolSlices*v + p] += 1.; }
00400 double inline GetNumValPhi(double *n, int v, int p){ return n[PolSlices*v + p]; }
00401 
00402 // run-Function
00403 static gboolean AngularAnalysis_run(Scan *Src, Scan *Dest)
00404 {
00405         AngularAnalysis_configure();
00406         int numsize = PolSlices * DataChannels;
00407         double *Num = new double[numsize];
00408         for (int i=0; i<numsize; Num[i++]=0.);
00409 
00410         double DataRange = DataEnd - DataStart;
00411         double SliceAng  = 360./(double)PolSlices;
00412   
00413         APlane ap;
00414         Facet  facet;
00415         facet.Crx   = FacetRadius;
00416         facet.Cry   = FacetRadius;
00417         double fac = Src->data.s.dz/((Src->data.s.dx+Src->data.s.dy)/2.);
00418 
00419         // Now do Calculation and Counting
00420         for(int line=FacetRadius; line<Src->mem2d->GetNy()-FacetRadius; ++line){
00421                 gchar *mld = g_strdup_printf("Calculating Angular Dist: %d/%d", 
00422                                              line, Dest->data.s.ny);
00423                 gapp->SetStatus(mld); 
00424                 g_free(mld);
00425                 SET_PROGRESS((double)line/(double)Dest->data.s.ny);
00426                 for(int row=FacetRadius; row<Src->mem2d->GetNx()-FacetRadius; ++row){
00427                         facet.Crow  = row;
00428                         facet.Cline = line;
00429                         FacetERegress(Src, &facet, &ap);
00430                         double phi = Phi(ap.ax, ap.ay);
00431                         double slp = 180.*acos(1./sqrt(1. + (ap.ax*ap.ax + ap.ay*ap.ay)*fac*fac))/M_PI;
00432                         int v = (int)rint((slp-DataStart)*(double)DataChannels/DataRange);
00433                         int p = (int)rint(phi/SliceAng);
00434                         p += PolSlices; p = p % PolSlices;
00435                         if( v < 0 || v >= DataChannels || p < 0 || p >= PolSlices)
00436                                 continue;
00437                         IncNumValPhi(Num, v, p);
00438                 }
00439         }
00440 
00441         // Setup Destination
00442         // and Fillup Polar Plot
00443         UnitObj *u;
00444         Dest->data.SetXUnit(u=new UnitObj("rPhi","rPhi"));
00445         Dest->data.SetYUnit(u); delete u;
00446         Dest->data.SetZUnit(u=new UnitObj("#","#")); delete u;
00447         Dest->data.s.dz = 1.;
00448 
00449         switch(Vmode){
00450         case 1:
00451                 Dest->data.s.nx = Dest->data.s.ny = DataChannels*2-1;
00452                 Dest->mem2d->Resize(Dest->data.s.nx, Dest->data.s.ny, ZD_FLOAT);
00453                 Dest->data.s.rx = Dest->data.s.ry = DataRange;
00454                 Dest->data.s.x0 = Dest->data.s.y0 = DataStart;
00455                 Dest->mem2d->data->MkXLookup(-DataRange, DataRange);
00456                 Dest->mem2d->data->MkYLookup(-DataRange, DataRange);
00457                 for(int line=0; line<Dest->data.s.ny; line++)
00458                         for(int col=0; col<Dest->data.s.nx; col++){
00459                                 int dx= col-Dest->data.s.nx/2;
00460                                 int dy=line-Dest->data.s.ny/2;
00461                                 int v = (int)rint(sqrt(dx*dx+dy*dy));
00462                                 int p = (int)rint(Phi(dx, dy)/SliceAng);
00463                                 p += PolSlices; p = p % PolSlices;
00464                                 if( v < 0 || v >= DataChannels || p < 0 || p >= PolSlices)
00465                                         continue;
00466                                 if(v > (int)((double)DataChannels/2/M_PI))
00467                                         Dest->mem2d->PutDataPkt(GetNumValPhi(Num, v, p), col, line);
00468                                 else{
00469                                         double sumup=0.;
00470                                         if(v>0){
00471                                                 for(int i=p-(int)((double)DataChannels/2/M_PI/v); 
00472                                                     i<=p+(int)((double)DataChannels/2/M_PI/v); ++i)
00473                                                         sumup += GetNumValPhi(Num, v, (i+PolSlices)%PolSlices);
00474                                                 sumup /= (1+2*(int)((double)DataChannels/2/M_PI/v));
00475                                                 sumup *= (double)DataChannels/2/M_PI/v;
00476                                         }
00477                                         else
00478                                                 for(int i=0; i<PolSlices; ++i)
00479                                                         sumup += GetNumValPhi(Num, v, i);
00480                                         Dest->mem2d->PutDataPkt(sumup, col, line);
00481                                 }
00482                         }
00483                 break;
00484         default:
00485                 Dest->data.s.nx = DataChannels;
00486                 Dest->data.s.ny = PolSlices;
00487                 Dest->mem2d->Resize(Dest->data.s.nx, Dest->data.s.ny, ZD_LONG);
00488                 Dest->data.s.rx = Dest->data.s.ry = DataRange;
00489                 Dest->data.s.x0 = Dest->data.s.y0 = DataStart;
00490                 Dest->mem2d->data->MkXLookup(0., DataRange);
00491                 Dest->mem2d->data->MkYLookup(0., 360.);
00492                 for(int line=0; line<Dest->data.s.ny; line++)
00493                         for(int col=0; col<Dest->data.s.nx; col++)
00494                                 Dest->mem2d->PutDataPkt(GetNumValPhi(Num, col, line), col, line);
00495                 break;
00496         }
00497 
00498         delete[] Num;
00499 
00500         return MATH_OK;
00501 }
00502 
00503 

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