VacancyLineAnalysis.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          =Jacob
00007 pluginname              =VacancyLineAnalysis
00008 pluginmenuentry         =Vacancy Line Analysis
00009 menupath                =Math/Statistics/
00010 entryplace              =Statistics
00011 shortentryplace =ST
00012 abouttext               =Determines position of vacancy lines
00013 smallhelp               =Use lines to mark positions of vacancy lines.
00014 longhelp                =Rotate sample so vacancy lines are vertical.
00015                          Dimer size, and searching parameters can be set in
00016                          the configure dialog.
00017  * 
00018  * Gxsm Plugin Name: VacancyLineAnalysis.C
00019  * ========================================
00020  * 
00021  * Copyright (C) 1999 The Free Software Foundation
00022  *
00023  * Authors: Percy Zahl <zahl@fkp.uni-hannover.de>
00024  * additional features: Andreas Klust <klust@fkp.uni-hannover.de>
00025  *
00026  * This program is free software; you can redistribute it and/or modify
00027  * it under the terms of the GNU General Public License as published by
00028  * the Free Software Foundation; either version 2 of the License, or
00029  * (at your option) any later version.
00030  *
00031  * This program is distributed in the hope that it will be useful,
00032  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00033  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00034  * GNU General Public License for more details.
00035  *
00036  * You should have received a copy of the GNU General Public License
00037  * along with this program; if not, write to the Free Software
00038  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
00039  */
00040 
00041 
00042 /* Please do not change the Begin/End lines of this comment section!
00043  * this is a LaTeX style section used for auto generation of the PlugIn Manual 
00044  * Chapter. Add a complete PlugIn documentation inbetween the Begin/End marks!
00045  * --------------------------------------------------------------------------------
00046 % BeginPlugInDocuSection
00047 % PlugInDocuCaption: Vacancy Line Analysis
00048 % PlugInName: VacancyLineAnalysis
00049 % PlugInAuthor: J.S. Palmer
00050 % PlugInAuthorEmail: jspalmer@mines.edu
00051 % PlugInMenuPath: Math/Statistics/Vacancy Line Analysis
00052 
00053 % PlugInDescription
00054 This plugin is used to find the location of dimer vacancy lines.
00055 It was designed to determine statistics of thin layers of SiGe.  A very
00056 important feature to note is that scans must be rotated so that the
00057 vacancy lines are vertical. Lines are searched for vertically down the
00058 scan.  Line objects are used to mark the start and stop positions
00059 for the vacancy lines
00060 
00061 Four output results can be created. The most apparent is the copy of
00062 the scan with the position of the vacancy lines standing out as raised
00063 up. A second layer of that scan shows a 3D histogram of the relative
00064 horizontal positions of two vacancies on the same vacancy line
00065 separated by $n$ dimer rows.  $n=0$ is shown at the top of the screen and
00066 the separations are all 0.  The next row down shows a histogram for
00067 $n=1$, the next is $n=2$ and so forth up to $N$ rows down defined in the
00068 configuration (Dimer Rows included in histogram).  The positions of
00069 the vacancies are also saved to a file.  The last output is an
00070 histogram of the space between vacancy lines.
00071 
00072 % PlugInUsage
00073 Call it from \GxsmMenu{Math/Statistics/Vacancy Line Analysis}.
00074 
00075 % OptPlugInSources
00076 The active channel is used as data source.
00077 
00078 % OptPlugInObjects
00079 Lines must be used to show where the vacancy lines should start and
00080 end. Use  one line for each vacancy line to be located.
00081 
00082 % OptPlugInDest
00083 The position of the vacancy lines is displayed in the math channel or
00084 a new channel if a math channel is not open.  This channel will have a
00085 second layer showing a histogram of the vacancy line straightness. If
00086 a histogram showing the vacancy line separation is chosen, a new
00087 profile window is also opened.
00088 
00089 % OptPlugInConfig
00090 Several parameters are adjustable in the configuration window.  
00091 
00092 \begin{description}
00093 \item[Dimer Spacing] The spacing of the dimers -- is $7.68\:$\AA\ on Si.  
00094 \item[Max Vacancy Line Shift] The horizontal distance searched in each
00095   direction for the position on the dimer vacancy.  Typical
00096   values are $2\dots3$ atomic rows.
00097 \item[Pixels to Average] Number of pixels in horizontal direction to
00098   average in searching for vacancy.
00099 \item[Dimer rows included in 3D Histogram] The Maximum number of dimer
00100   rows between two vacancies on the on the same vacancy line to be
00101   included in the histogram. ($N$ as described above in the Description
00102   area)
00103 \item[3D Histogram Size] The size can be either $1:1$ (default), meaning
00104   that the horizontal scale is correct.  If $0$ is entered the output is
00105   scaled to fill the window.
00106 \item[Line-Spacing Histogram Bin Width] The width of each bin in the
00107   histogram showing the vacancy line spacing.  If $0$ is entered no
00108   histogram is created.
00109 \end{description}
00110 
00111 % OptPlugInFiles
00112 The user is prompted for an output file. A matrix is saved in the file
00113 containing the positions of the vacancy lines.  Each column in the
00114 matrix represents a vacancy line.  Each row represents a dimer row.
00115 The value of a matrix position is the horizontal pixel coordinates of
00116 the dimer vacancy.  A value of $-1$ means is is before the beginning of
00117 the line or after the end of the line.  Two rows before the matrix are
00118 used to designate the row number for the first and last dimer vacancy
00119 in that column (vacancy line).  The first row is designated as $0$.
00120 Also included in the heading is the dimer spacing used, which gives
00121 the conversion for rows to vertical position, and the x and y pixel
00122 spacing. The x pixel spacing provide a conversion from pixel position
00123 to horizontal position.
00124  
00125 
00126 %% OptPlugInRefs
00127 %nope.
00128 
00129 %% OptPlugInKnownBugs
00130 %No known.
00131 
00132 %% OptPlugInNotes
00133 %Hmm, no notes\dots
00134 
00135 % OptPlugInHints
00136 Here is a quick check list:
00137 \begin{enumerate}
00138 \item Rotate the scan so the Vacancy lines are as close to vertical as
00139 possible.
00140 \item Move start and stop positions or divide a line in two using two
00141   objects if the vacancy line is difficult to follow.
00142 \item Save your line objects -- it is time consuming to put them in and
00143   check to make sure each line is accurately located.
00144 \item Determine the correct dimer spacing for your image using a
00145   Power Spectrum of SPALEED simulation.
00146 \end{enumerate}
00147 
00148 
00149 % EndPlugInDocuSection
00150  * -------------------------------------------------------------------------------- 
00151  */
00152 
00153 #include <gtk/gtk.h>
00154 #include "config.h"
00155 #include "gxsm/plugin.h"
00156 #include "gxsm/app_profile.h"
00157 
00158 
00159 typedef struct {
00160         int x,yt,yb;
00161 } my_point;
00162 typedef struct {
00163         int first,last;
00164 } matrix_elements;
00165 
00166 // Plugin Prototypes
00167 static void VacancyLineAnalysis_init( void );
00168 static void VacancyLineAnalysis_about( void );
00169 static void VacancyLineAnalysis_configure( void );
00170 static void VacancyLineAnalysis_cleanup( void );
00171 
00172 // Define Type of math plugin here, only one line should be commented in!!
00173 #define GXSM_ONE_SRC_PLUGIN__DEF
00174 // #define GXSM_TWO_SRC_PLUGIN__DEF
00175 
00176 // Math-Run-Function, use only one of (automatically done :=)
00177 #ifdef GXSM_ONE_SRC_PLUGIN__DEF
00178 // "OneSrc" Prototype
00179  static gboolean VacancyLineAnalysis_run( Scan *Src, Scan *Dest);
00180 #else
00181 // "TwoSrc" Prototype
00182  static gboolean VacancyLineAnalysis_run( Scan *Src1, Scan *Src2, Scan *Dest );
00183 #endif
00184 
00185 // Fill in the GxsmPlugin Description here
00186 GxsmPlugin VacancyLineAnalysis_pi = {
00187   NULL,                   // filled in and used by Gxsm, don't touch !
00188   NULL,                   // filled in and used by Gxsm, don't touch !
00189   0,                      // filled in and used by Gxsm, don't touch !
00190   NULL,                   // The Gxsm-App Class Ref.pointer (called "gapp" in Gxsm) is 
00191                           // filled in here by Gxsm on Plugin load, 
00192                           // just after init() is called !!!
00193   // ----------------------------------------------------------------------
00194   // Plugins Name, CodeStly is like: Name-M1S|M2S-BG|F1D|F2D|ST|TR|Misc
00195   "VacancyLineAnalysis-"
00196 #ifdef GXSM_ONE_SRC_PLUGIN__DEF
00197   "M1S"
00198 #else
00199   "M2S"
00200 #endif
00201   "-ST",
00202   // Plugin's Category - used to autodecide on Pluginloading or ignoring
00203   // NULL: load, else
00204   // example: "+noHARD +STM +AFM"
00205   // load only, if "+noHARD: no hardware" and Instrument is STM or AFM
00206   // +/-xxxHARD und (+/-INST or ...)
00207   NULL,
00208   // Description, is shown by PluginViewer (Plugin: listplugin, Tools->Plugin Details)
00209   "Rotate sample so vacancy lines are vertical."
00210   "  Dimer size, and searching parameters can be set in "
00211   " the configure dialog.",                   
00212   // Author(s)
00213   "Jacob",
00214   // Menupath to position where it is appendet to
00215   N_("_Math/_Statistics/"),
00216   // Menuentry
00217   N_("Vacancy Line Analysis"),
00218   // help text shown on menu
00219   N_(  "Rotate sample so vacancy lines are vertical."
00220        "  Dimer size, and searching parameters can be set in "
00221        " the configure dialog."),                   
00222   // more info...
00223   "Use lines to mark positions of vacancy lines",
00224   NULL,          // error msg, plugin may put error status msg here later
00225   NULL,          // Plugin Status, managed by Gxsm, plugin may manipulate it too
00226   // init-function pointer, can be "NULL", 
00227   // called if present at plugin load
00228   VacancyLineAnalysis_init,  
00229   // query-function pointer, can be "NULL", 
00230   // called if present after plugin init to let plugin manage it install itself
00231   NULL, // query should be "NULL" for Gxsm-Math-Plugin !!!
00232   // about-function, can be "NULL"
00233   // can be called by "Plugin Details"
00234   VacancyLineAnalysis_about,
00235   // configure-function, can be "NULL"
00236   // can be called by "Plugin Details"
00237   VacancyLineAnalysis_configure,
00238   // run-function, can be "NULL", if non-Zero and no query defined, 
00239   // it is called on menupath->"plugin"
00240   NULL, // run should be "NULL" for Gxsm-Math-Plugin !!!
00241   // cleanup-function, can be "NULL"
00242   // called if present at plugin removeal
00243   VacancyLineAnalysis_cleanup
00244 };
00245 
00246 // special math Plugin-Strucure, use
00247 // GxsmMathOneSrcPlugin VacancyLineAnalysis_m1s_pi -> "OneSrcMath"
00248 // GxsmMathTwoSrcPlugin VacancyLineAnalysis_m2s_pi -> "TwoSrcMath"
00249 #ifdef GXSM_ONE_SRC_PLUGIN__DEF
00250  GxsmMathOneSrcPlugin VacancyLineAnalysis_m1s_pi
00251 #else
00252  GxsmMathTwoSrcPlugin VacancyLineAnalysis_m2s_pi
00253 #endif
00254  = {
00255    // math-function to run, see prototype(s) above!!
00256    VacancyLineAnalysis_run
00257  };
00258 
00259 // Text used in Aboutbox, please update!!
00260 static const char *about_text = N_("Gxsm VacancyLineAnalysis Plugin\n\n"
00261          "Determines position of vacancy lines for statistical analysis");
00262 
00263 // Symbol "get_gxsm_plugin_info" is resolved by dlsym from Gxsm, used to get Plugin's info!! 
00264 // Essential Plugin Function!!
00265 GxsmPlugin *get_gxsm_plugin_info ( void ){ 
00266   VacancyLineAnalysis_pi.description = g_strdup_printf(N_("Gxsm MathOneArg VacancyLineAnalysis plugin %s"), VERSION);
00267   return &VacancyLineAnalysis_pi; 
00268 }
00269 
00270 // Symbol "get_gxsm_math_one|two_src_plugin_info" is resolved by dlsym from Gxsm, 
00271 // used to find out which Math Type the Plugin is!! 
00272 // Essential Plugin Function!!
00273 #ifdef GXSM_ONE_SRC_PLUGIN__DEF
00274 GxsmMathOneSrcPlugin *get_gxsm_math_one_src_plugin_info( void ) {
00275   return &VacancyLineAnalysis_m1s_pi; 
00276 }
00277 #else
00278 GxsmMathTwoSrcPlugin *get_gxsm_math_two_src_plugin_info( void ) { 
00279   return &VacancyLineAnalysis_m2s_pi; 
00280 }
00281 #endif
00282 
00283 /* Here we go... */
00284 // init-Function
00285 static void VacancyLineAnalysis_init(void)
00286 {
00287   PI_DEBUG (DBG_L2, "VacancyLineAnalysis Plugin Init");
00288 }
00289 
00290 // about-Function
00291 static void VacancyLineAnalysis_about(void)
00292 {
00293   const gchar *authors[] = { VacancyLineAnalysis_pi.authors, NULL};
00294   gtk_widget_show(gnome_about_new ( VacancyLineAnalysis_pi.name,
00295                                     VERSION,
00296                                     N_("(C) 2000 the Free Software Foundation"),
00297                                     about_text,
00298                                     authors,
00299                                     NULL, NULL, NULL
00300                                     ));
00301 }
00302 
00303 // configure-Function
00304 double yaverage=7.68;  // Distance between dimer rows
00305 double spred=11.52;     // Maximum shift in vacancy line per dimer row
00306 double xaverage=3.;   // x distance average used to find minimum 
00307 double bin_width=0.;  //default - no histogram of line spacing
00308 double n_dimer_rows=10.;  // # of dimer rows included for determining straightness 
00309 double hist_scale=1.;
00310 
00311 static void VacancyLineAnalysis_configure(void)
00312 {
00313   GtkWidget *dialog;
00314   GtkWidget *vbox;
00315   GtkWidget *hbox;
00316   GtkWidget *info;
00317   GtkWidget *input;
00318 
00319   dialog = gnome_dialog_new(_("VacancyLineAnalysis Setup"),
00320                             GNOME_STOCK_BUTTON_OK,
00321                             NULL); 
00322         
00323   gnome_dialog_set_close(GNOME_DIALOG(dialog), FALSE);
00324   gnome_dialog_close_hides(GNOME_DIALOG(dialog), FALSE);
00325   gnome_dialog_set_default(GNOME_DIALOG(dialog), 0);
00326 
00327   vbox = gtk_vbox_new (FALSE, 0);
00328   gtk_widget_show (vbox);
00329 
00330   gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(dialog)->vbox),
00331                      vbox, TRUE, TRUE, GNOME_PAD);
00332 
00333   info = gtk_label_new ("Enter Analysis Information");
00334   gtk_widget_show (info);
00335   gtk_box_pack_start(GTK_BOX(vbox), info, TRUE, TRUE, GNOME_PAD);
00336 
00337   input = VacancyLineAnalysis_pi.app->mygtk_create_input
00338           ("Dimer Spacing (A):", vbox, hbox,400,50);
00339   Gtk_EntryControl ECvar11
00340           (VacancyLineAnalysis_pi.app->xsm->Unity, "Value out of range !", 
00341            &yaverage, .01, 100., ".2f", input);
00342 
00343   input = VacancyLineAnalysis_pi.app->mygtk_create_input
00344           ("Max Vacancy Line Shift [A]:", vbox, hbox,400,50);
00345   Gtk_EntryControl ECvar21
00346           (VacancyLineAnalysis_pi.app->xsm->Unity, "Value out of range !", 
00347            &spred, 1., 100., ".2f", input);
00348   
00349   input = VacancyLineAnalysis_pi.app->mygtk_create_input
00350           ("Pixels to Average:", vbox, hbox,400,50);
00351   Gtk_EntryControl ECvar31
00352           (VacancyLineAnalysis_pi.app->xsm->Unity, "Value out of range !",
00353            &xaverage, 0., 100., ".0f", input);
00354 
00355   input = VacancyLineAnalysis_pi.app->mygtk_create_input
00356           ("Dimer rows included in 3D Histogram", vbox, hbox,400,50);
00357   Gtk_EntryControl ECvar41
00358           (VacancyLineAnalysis_pi.app->xsm->Unity, "Value out of range !",
00359            &n_dimer_rows, 1., 100., ".0f", input);
00360   
00361   input = VacancyLineAnalysis_pi.app->mygtk_create_input
00362           ("3D Histogram Size (0=Scaled,1=1:1)", vbox, hbox,400,50);
00363   Gtk_EntryControl ECvar51
00364           (VacancyLineAnalysis_pi.app->xsm->Unity, "Value out of range !",
00365            &hist_scale, 0., 1., ".0f", input); 
00366 
00367   input = VacancyLineAnalysis_pi.app->mygtk_create_input
00368           ("Line-Spacing Histogram Bin Width [A]", vbox, hbox,400,50);
00369   Gtk_EntryControl ECvar61
00370           (VacancyLineAnalysis_pi.app->xsm->Unity, "Value out of range !",
00371            &bin_width, 0., 100., ".2f", input);
00372   
00373   info = gtk_label_new ("(Enter 0 for no line-spacing histogram)");
00374   gtk_widget_show (info);
00375   gtk_box_pack_start(GTK_BOX(vbox), info, TRUE, TRUE, GNOME_PAD);
00376 
00377   gtk_widget_show(dialog);
00378 
00379   gnome_dialog_run_and_close(GNOME_DIALOG(dialog));
00380 }
00381 
00382 
00383 
00384 // cleanup-Function
00385 static void VacancyLineAnalysis_cleanup(void)
00386 {
00387   PI_DEBUG (DBG_L2, "VacancyLineAnalysis Plugin Cleanup");
00388 }
00389 
00390 // run-Function
00391 #ifdef GXSM_ONE_SRC_PLUGIN__DEF
00392  static gboolean VacancyLineAnalysis_run(Scan *Src, Scan *Dest)
00393 #else
00394  static gboolean VacancyLineAnalysis_run(Scan *Src1, Scan *Src2, Scan *Dest)
00395 #endif
00396 {
00397         // put plugins math code here...
00398         // For more math-access methods have a look at xsmmath.C
00399 #ifdef GXSM_ONE_SRC_PLUGIN__DEF
00400 // *********************************************************************************
00401 // Add second layer to output scan
00402         Dest->data.s.dz = 1;
00403         Dest->data.s.nvalues = 2;
00404         UnitObj *Events_tmp = new UnitObj("","",".0f","#");
00405         Dest->data.SetZUnit (Events_tmp);
00406         delete Events_tmp;
00407         Dest->mem2d->Resize (Src->mem2d->GetNx(), Src->mem2d->GetNy(), Dest->data.s.nvalues);
00408         Dest->mem2d->data->MkVLookup (0., 1.);
00409 
00410         Dest->mem2d->SetLayer (0);
00411 // *********************************************************************************
00412 // data from config-Function
00413 
00414         double dy = Src->data.s.dy;
00415         double stepsize = (yaverage /dy );     
00416         PI_DEBUG (DBG_L2, "stepsize" << stepsize);
00417         int xsmoothing = (int) floor((xaverage-1)/2.);
00418         double dx =  Src->data.s.dx;
00419         int width = (int) (spred / dx );
00420 
00421 // *********************************************************************************
00422 // Copies over data from sourse window
00423      for(int line=0; line<Dest->mem2d->GetNy(); line++){
00424 
00425 
00426              for(int col=0; col<Dest->mem2d->GetNx(); col++){
00427 
00428                      Dest->mem2d->PutDataPkt(Src->mem2d->
00429                                              GetDataPkt(col, line), col, line);
00430              }
00431      }
00432 
00433 // *********************************************************************************
00434 //Locate and order all Objects 
00435      // I need at least one object
00436      int n_obj = Src->number_of_object ();
00437      if (n_obj < 1) 
00438              return MATH_SELECTIONERR;
00439 
00440      // iterate over all objects
00441 
00442      int *lookup = new int[n_obj];
00443      for (int i=0;i<n_obj; i++) lookup[i]=0;
00444         
00445      my_point *end_points = new my_point[n_obj];
00446 
00447      int n_lines = n_obj; 
00448      for (int i=0; i<n_obj; i++){
00449              scan_object_data *obj_data;
00450              obj_data = Src->get_object_data (i);
00451 
00452              obj_data->dump ();
00453 
00454              // only lines are supported:
00455              if (strncmp (obj_data->get_name (), "Line", 9) ){
00456                      lookup[i]=n_obj+1;
00457                      n_lines-=1;
00458                      end_points[i].x=Src->mem2d->GetNx();
00459                      continue;
00460              }
00461 
00462              int n_pts = obj_data->get_num_points ();
00463              // support for point objects, only
00464              if (n_pts != 2){
00465                      lookup[i]=n_obj+1;
00466                      n_lines-=1;
00467                      end_points[i].x=Src->mem2d->GetNx();
00468                      continue;
00469              }
00470 
00471              // get real world coordinates
00472              double x0,y0,x1,y1;                
00473              obj_data->get_xy (0, x0, y0);
00474              obj_data->get_xy (1, x1, y1);
00475              // PI_DEBUG (DBG_L2, "x0 " << x0 << " y0 " << y0 );
00476              // PI_DEBUG (DBG_L2, "x1 " << x1 << " y1 " << y1 );
00477 
00478              // calculate pixel coordinates
00479              int xl = (int)( (x0 - Src->data.s.x0 + Src->data.s.rx/2) / Src->data.s.dx );
00480              int yt = (int)( (Src->data.s.y0 - y0) / Src->data.s.dy );
00481              int xr = (int)( (x1 - Src->data.s.x0 + Src->data.s.rx/2) / Src->data.s.dx );
00482              int yb = (int)( (Src->data.s.y0 - y1) / Src->data.s.dy );
00483         
00484              // make sure the pixel coord. lie within the scan Src2
00485              if (xl < 0)  xl=0;
00486              if (xl > Src->mem2d->GetNx()-1)  xl = Src->mem2d->GetNx()-1;
00487              if (yt < 0)  yt=0;
00488              if (yt > Src->mem2d->GetNy()-1)  yt = Src->mem2d->GetNy()-1;
00489              if (xr < 0)  xr=0;
00490              if (xr > Src->mem2d->GetNx()-1)  xr = Src->mem2d->GetNx()-1;
00491              if (yb < 0)  yb=0;
00492              if (yb > Src->mem2d->GetNy()-1)  yb = Src->mem2d->GetNy()-1;
00493              // PI_DEBUG (DBG_L2, "xl " << xl << " yt " << yt );
00494              // PI_DEBUG (DBG_L2, "xr " << xr << " yb " << yb );
00495 
00496              // Set (xl,yt) as upper and (xr,yb) as lower points        
00497              if (yt>yb){
00498                      int ytemp=yt;yt=yb;yb=ytemp;
00499                      int xtemp=xl;xl=xr;xr=xtemp;
00500              }
00501              end_points[i].x=xl;
00502              end_points[i].yt=yt;
00503              end_points[i].yb=yb;
00504 
00505              // Create lookup table for order of lines
00506              for (int j=0; j<i;j++)
00507              {               if ((xl<end_points[j].x)||
00508                                  ((xl==end_points[j].x)&&(yt<end_points[j].yt)))
00509                      lookup[j]++;
00510              else lookup[i]++;
00511              }
00512      }
00513 // *********************************************************************************
00514 // remove non-line objects
00515      for (int i=0; i< n_lines; i++)
00516              if (lookup[i]>n_obj){
00517                      for (int j=i;j<n_obj-1;j++){
00518                              lookup[j]=lookup[j+1];
00519                              end_points[j].x=end_points[j+1].x;
00520                              end_points[j].yt=end_points[j+1].yt;
00521                              end_points[j].yb=end_points[j+1].yb;
00522                      }
00523                      if (i<n_lines-1) i-=1;
00524              }
00525      n_obj=n_lines; // only include lines in future analysis
00526      if (n_obj < 1) 
00527              return MATH_SELECTIONERR;
00528 
00529 
00530 // *********************************************************************************
00531 // Find Minimum and Maximum line end points
00532      int top_line=end_points[0].yt, bottom_line=end_points[0].yb;
00533      for (int i=1; i<n_obj; i++){ 
00534              if (top_line > end_points[i].yt)
00535                      top_line=end_points[i].yt;
00536              if (bottom_line < end_points[i].yb)
00537                      bottom_line=end_points[i].yb;
00538      }
00539      PI_DEBUG (DBG_L2, "top " << top_line << " bottom " << bottom_line );
00540 
00541 // *********************************************************************************
00542 // Set up matrix for line positions in pixels
00543      const int n_rows = (int) ceil((bottom_line-top_line)/stepsize)+1;
00544      const int n_elements = n_rows*n_obj;
00545      int *line_matrix = new int[n_elements];
00546      for (int i=0; i<n_elements; i++) line_matrix[i]=-1;
00547 
00548      PI_DEBUG (DBG_L2, "number of rows " << n_rows );
00549 
00550 
00551 
00552 // *********************************************************************************
00553 //Find the Minimum in each line, diplay it on scan and record position in matrix
00554 
00555      for (int i=0; i<n_obj; i++){
00556              int minposition=end_points[i].x;
00557              for(int step=0; 
00558                  (end_points[i].yt+ceil(stepsize*step))<end_points[i].yb;
00559                  step++){
00560                      int line=(int) (end_points[i].yt+floor(stepsize*step));    
00561         
00562                      double minvalue=10000000;
00563                      int bound=minposition;
00564 
00565                      for(int col=bound-width; col<bound+width+1; col++) 
00566                              if(col-xsmoothing>0 && col<Src->mem2d->GetNx()-1+xsmoothing){
00567                                      double total=0;
00568                                      for(int line2=(int) (line-floor(stepsize)); (line2<Dest->mem2d->GetNy()) && 
00569                                                  (line2<(line+floor(2*stepsize)))
00570                                                  && (line2>0); line2++)
00571                                              for (int col2=col-xsmoothing;col2<col+xsmoothing+1;col2++)
00572                                                      total+=Src->mem2d->GetDataPkt(col2, line2);
00573                                      if (total<minvalue){
00574                                              minvalue=total;
00575                                              minposition=col;
00576                                      }
00577                              }
00578              // writing position to matrix
00579                      int element=(int) ((floor((end_points[i].yt-top_line)/stepsize)+step)*(n_obj)+lookup[i]);
00580                      line_matrix[element]=minposition;
00581              // diplaying position on scan
00582                      for(int line2=line; (line2<Dest->mem2d->GetNy()) && 
00583                                  (line2<(line+ ceil(stepsize)));line2++) 
00584                              Dest->mem2d->PutDataPkt (
00585                                      Src->mem2d->GetDataPkt(minposition,line2)+1000, 
00586                                      minposition,line2);
00587 //                   std::cout << (end_points[i].yt+floor(stepsize*step))<<" "<<end_points[i].yb<<std::endl;
00588 //                   std::cout  << " minposition for line"  << line  <<" is "<< minposition << std::endl;
00589              }
00590      }
00591 
00592 // ********************************************************************************
00593 // Start and stop positions of each line in the matrix
00594      matrix_elements *matrix_end = new matrix_elements[n_obj];
00595      for (int i=0; i<n_obj; i++){
00596              matrix_end[lookup[i]].first=(int) floor((end_points[i].yt-top_line)/stepsize);
00597              for(matrix_end[lookup[i]].last=(int) (floor((end_points[i].yt-top_line)/stepsize)+
00598                      floor((end_points[i].yb-end_points[i].yt)/stepsize));
00599                  line_matrix[matrix_end[lookup[i]].last*n_obj+lookup[i]]<0;
00600                  matrix_end[lookup[i]].last--);
00601              
00602      }
00603 
00604 // *********************************************************************************
00605 // Check for overlapped lines and change order
00606      {
00607              for (int col=0;col<n_obj-1; col++){ 
00608                      int sum=0;
00609                      for(int row=matrix_end[col].first; row<matrix_end[col].last+1; row++)
00610                              if (line_matrix[n_obj*row+col+1]!=-1)
00611                                      sum +=( line_matrix[n_obj*row+col+1]-line_matrix[n_obj*row+col]);
00612 
00613 
00614 //                   for(int row=0; row<n_rows; row++)
00615 //                           if ((line_matrix[n_obj*row+col]!=-1) && (line_matrix[n_obj*row+col+1]!=-1))
00616 //                                   sum +=( line_matrix[n_obj*row+col+1]-line_matrix[n_obj*row+col]);
00617                      if (sum<0){
00618                              int temp = matrix_end[col].first;
00619                              matrix_end[col].first=matrix_end[col+1].first;
00620                              matrix_end[col+1].first=temp;
00621                              temp = matrix_end[col].last;
00622                              matrix_end[col].last=matrix_end[col+1].last;
00623                              matrix_end[col+1].last=temp;
00624 
00625                              for(int row=0; row<n_rows; row++){
00626                                      temp = line_matrix[n_obj*row+col+1];
00627                                      line_matrix[n_obj*row+col+1]=line_matrix[n_obj*row+col];
00628                                      line_matrix[n_obj*row+col]=temp;
00629                              }
00630                                                  
00631                      }
00632              }
00633      }       
00634 // std::cout order of lines
00635      PI_DEBUG (DBG_L2, "lookup ");
00636      for (int i=0;i<n_obj; i++) std::cout << lookup[i] <<" "<<end_points[i].x<<" ";
00637      std::cout << std::endl;
00638 
00639 
00640 // *********************************************************************************
00641 // OutPut data to a choosen file in Angstroms
00642      /*
00643      gchar *file_name = gapp->file_dialog("asc Export", NULL,
00644                                           "*.asc", 
00645                                           "", "asc-Export");
00646 
00647      ofstream file_out;
00648      file_out.open(file_name);
00649      file_out.setf(ios::fixed);
00650      file_out << "Vacancy Line Positions");   
00651      file_out << "Dimer spacing: " << stepsize << " A");
00652      file_out << "x pixels spacing: " << dx << " A/pixel");
00653      file_out << "y pixels spacing: " << dy << " A/pixel");
00654      for (int i=0; i<n_rows;i++){
00655              for (int j=0; j<n_obj; j++)
00656                      if (line_matrix[n_obj*i+j]==-1)
00657                              file_out << -1. << "\t"; 
00658                      else
00659                              file_out << line_matrix[n_obj*i+j]/dx<<"\t";
00660              file_out << std::endl;
00661      }
00662      file_out.close();
00663      PI_DEBUG (DBG_L2, "file name "<< file_name );
00664      */
00665 // *********************************************************************************
00666 // OutPut data to a choosen file in Pixels
00667 
00668      gchar *file_name = gapp->file_dialog("asc Export", NULL,
00669                                           "*.asc", 
00670                                           "", "asc-Export");
00671 
00672      std::ofstream file_out;
00673      file_out.open(file_name);
00674      file_out.setf(std::ios::fixed);
00675      file_out << "Vacancy Line Positions (Pixels)" << std::endl;   
00676      file_out << "Dimer spacing: " << yaverage << " A" << std::endl;
00677      file_out << "x pixels spacing: " << dx << " A/pixel" << std::endl;
00678      file_out << "y pixels spacing: " << dy << " A/pixel" << std::endl;
00679      file_out << "First and last matrix elements containing data (0=first)" << std::endl;
00680      for (int i=0; i<n_obj; i++)
00681              file_out << matrix_end[i].first <<"\t";
00682      file_out << std::endl;
00683      for (int i=0; i<n_obj; i++)
00684              file_out <<matrix_end[i].last <<"\t";
00685      file_out << std::endl << std::endl;
00686      for (int i=0; i<n_rows;i++){
00687              for (int j=0; j<n_obj; j++)
00688                      file_out << line_matrix[n_obj*i+j]<<"\t";
00689              file_out << std::endl;
00690      }
00691      file_out.close();
00692      PI_DEBUG (DBG_L2, "file name "<< file_name );
00693 
00694 // *********************************************************************************
00695 // OutPut Line Information in pixels to screen
00696 /*
00697      PI_DEBUG (DBG_L2, "Vacancy Line Positions");   
00698      PI_DEBUG (DBG_L2, "Dimer spacing: " << stepsize << " A");
00699      PI_DEBUG (DBG_L2, "x pixels spacing: " << dx << " A/pixel");
00700      PI_DEBUG (DBG_L2, "y pixels spacing: " << dy << " A/pixel");    
00701      for (int i=0; i<n_rows;i++){
00702              for (int j=0; j<n_obj; j++)
00703                      std::cout << line_matrix[(n_obj*i)+j]<<" ";
00704              std::cout << std::endl;
00705      }
00706 */
00707 
00708 
00709 // *********************************************************************************
00710 //   Analyze data
00711 //   Line Straightness
00712 
00713 // Initialize second layer for histogram of line straightness
00714      Dest->mem2d->SetLayer (1);
00715      for(int line=0; line<Dest->mem2d->GetNy(); line++){
00716              for(int col=0; col<Dest->mem2d->GetNx(); col++){
00717                      Dest->mem2d->PutDataPkt(0, col, line);
00718              }
00719      }
00720      int Ny = Dest->mem2d->GetNy();
00721      int Nx = Dest->mem2d->GetNx();
00722      int center = (int) Ny/2; 
00723      int n_rows_down = (int)n_dimer_rows+1;
00724      int x_pixel = 1;
00725      int y_pixel = (int) stepsize;
00726      if (hist_scale==0){
00727              // Determines number of bins to include
00728              int max_offset = 1;
00729              for (int row_down=0; row_down < n_rows_down; row_down++)
00730                      for (int col=0; col<n_obj; col++)
00731                              for (int row = matrix_end[col].first; 
00732                                   row < matrix_end[col].last-row_down+1; row++)
00733                                      if ( abs(line_matrix[n_obj*(row+row_down)+col]-
00734                                               line_matrix[n_obj*row+col])>max_offset)
00735                                              max_offset = abs(line_matrix[n_obj*(row+row_down)+col]-
00736                                                               line_matrix[n_obj*row+col]);      
00737              x_pixel = (int) floor(Nx/(2.2*max_offset));
00738              y_pixel = (int) floor(Ny/n_rows_down);
00739      }
00740   
00741 
00742      PI_DEBUG (DBG_L2, "x_pixel " << x_pixel );
00743      PI_DEBUG (DBG_L2, "y_pixel " << y_pixel );
00744      for (int row_down=0; row_down < n_rows_down; row_down++)
00745              for (int col=0; col<n_obj; col++)
00746                      for (int row = matrix_end[col].first;
00747                           row < matrix_end[col].last-row_down+1; row++)
00748                              for (int row2 = row_down*y_pixel; 
00749                                   row2<(row_down+1)*y_pixel; row2++)
00750                                      for (int col2 = center + x_pixel*(
00751                                                   line_matrix[n_obj*(row+row_down)+col]-
00752                                                   line_matrix[n_obj*row+col]);
00753                                           col2< center + x_pixel*(
00754                                                   line_matrix[n_obj*(row+row_down)+col]-
00755                                                   line_matrix[n_obj*row+col]+1); col2++)
00756                                              if ((col2<Nx) && (col2>0)) 
00757                                                      Dest->mem2d->data->Zadd(1,col2, row2);
00758      Dest->mem2d->SetLayer (0);
00759 
00760 
00761 
00762 // ******************************************************************************************************
00763 
00764 //  Line Spacing  // will not be performed if bin width is set to 0 in configuration
00765      if (bin_width>0) 
00766      {
00767              // determine the range of values for histogram
00768              double bin_w=bin_width/dy;
00769              int min_spacing=1000;
00770              int max_spacing=0;
00771              for(int row=0; row<n_rows; row++)
00772                      for (int col=0;col<n_obj-1; col++) 
00773                              if ((line_matrix[n_obj*row+col]!=-1) && (line_matrix[n_obj*row+col+1]!=-1)){
00774                                      if (line_matrix[n_obj*row+col+1]-line_matrix[n_obj*row+col]<min_spacing)
00775                                              min_spacing=(line_matrix[n_obj*row+col+1]-line_matrix[n_obj*row+col]);
00776                                      if (line_matrix[n_obj*row+col+1]-line_matrix[n_obj*row+col]>max_spacing)
00777                                              max_spacing=(line_matrix[n_obj*row+col+1]-line_matrix[n_obj*row+col]);
00778                              }
00779              // increase range on each side by 20%
00780              int range= max_spacing-min_spacing;
00781              min_spacing-= (int)(0.2*range);
00782              max_spacing+= (int)(0.2*range);
00783              
00784              // set the the number of bins depending on range and bin width given in configuration 
00785              int n_bins = (int) ceil((max_spacing-min_spacing)/bin_w);
00786              int *bin_cnts = new int[n_bins];
00787              for (int i=0; i<n_bins; i++) bin_cnts[i]=0;
00788 
00789              for (int col=0; col< n_obj-1; col++)
00790                      for (int row=0; row< n_rows; row++)
00791                              if (line_matrix[n_obj*row+col]!=-1)
00792                                      for (int nextcol=col+1; nextcol<n_obj; nextcol++)
00793                                              if (line_matrix[n_obj*row+nextcol]!=-1){
00794                                                      if((int)((line_matrix[n_obj*row+nextcol]-
00795                                                         line_matrix[n_obj*row+col]-min_spacing)/bin_w)<n_bins) 
00796                                                              bin_cnts[(int)((line_matrix[n_obj*row+nextcol]-
00797                                                               line_matrix[n_obj*row+col]-min_spacing)/bin_w)]+=1;
00798                                                      nextcol=n_obj;
00799                                              }
00800  
00801 
00802              UnitObj *Events = new UnitObj("","","g","#");
00803              gchar *txt;
00804              txt= g_strdup_printf ("Vacancy_Line_Spacing_Histogram");
00805 
00806              ProfileControl *pc2 = new ProfileControl (txt, 
00807                                                        n_bins, 
00808                                                        Src->data.Xunit, Events, 
00809                                                        min_spacing*dx, max_spacing*dx);
00810              for(int i = 0; i < n_bins; i++)
00811                      pc2->SetPoint (i, bin_cnts[i]);
00812              pc2->drawScans();
00813      
00814              for (int i=0;i<n_bins; i++) std::cout << bin_cnts[i] << " ";
00815              std::cout << std::endl;
00816              delete [] bin_cnts;
00817      }
00818 
00819      delete [] end_points;
00820      delete [] matrix_end;
00821      delete [] lookup;
00822      delete [] line_matrix;
00823 
00824 
00825 #else
00826   // simple example for 2sourced Mathoperation: Source1 and Source2 are added.
00827   int line, col;
00828 
00829   if(Src1->data.s.nx != Src2->data.s.nx || Src1->data.s.ny != Src2->data.s.ny)
00830     return MATH_SELECTIONERR;
00831 
00832   for(line=0; line<Dest->data.s.ny; line++)
00833     for(col=0; col<Dest->data.s.nx; col++)
00834       Dest->mem2d->PutDataPkt(
00835                               Src1->mem2d->GetDataPkt(col, line)
00836                             + Src2->mem2d->GetDataPkt(col, line),
00837                               col, line);
00838 #endif
00839 
00840   return MATH_OK;
00841 }
00842 
00843 

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