00001 /* Gnome gxsm - Gnome X Scanning Microscopy 00002 * universal STM/AFM/SARLS/SPALEED/... controlling and 00003 * data analysis software 00004 * 00005 * Gxsm Plugin Name: spectrocut.C 00006 * ======================================== 00007 * 00008 * Copyright (C) 2002 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 00029 /* Please do not change the Begin/End lines of this comment section! 00030 * this is a LaTeX style section used for auto generation of the PlugIn Manual 00031 * Chapter. Add a complete PlugIn documentation inbetween the Begin/End marks! 00032 * -------------------------------------------------------------------------------- 00033 % BeginPlugInDocuSection 00034 % PlugInDocuCaption: Cut spectra from 3D data 00035 % PlugInName: spectrocut 00036 % PlugInAuthor: Andreas Klust 00037 % PlugInAuthorEmail: klust@users.sf.net 00038 % PlugInMenuPath: Math/Misc/Spectrocut 00039 00040 % PlugInDescription 00041 \label{plugin:spectrocut} 00042 This plug-in is made for choosing areas from a topograhic scan using the 00043 \GxsmEmph{rectangle} object. The spectra in the correspondent spectroscopic 00044 data taken simultaneously with the topographic data are then cut out and 00045 saved in a file. Currently, only an index vector is saved in the GNU Octave 00046 ASCII format for further analysis of the data. Its filename is hard coded 00047 ("/tmp/spec.ivec"). 00048 00049 % OptPlugInHints 00050 This plug-in is in a very alpha stage. 00051 00052 % PlugInUsage 00053 The topographic scan must be the active, the scan with the spectoscopic data 00054 the X channel. The plug-in is called via \GxsmMenu{Math/Misc/Spectrocut}. 00055 00056 %% OptPlugInKnownBugs 00057 %No known. 00058 00059 % EndPlugInDocuSection 00060 * -------------------------------------------------------------------------------- 00061 */ 00062 00063 00064 #include <gtk/gtk.h> 00065 #include <string.h> 00066 #include "config.h" 00067 #include "gxsm/plugin.h" 00068 #include "gxsm/scan.h" 00069 #include "gxsm/xsmmath.h" 00070 00071 using namespace std; 00072 00073 00074 #ifndef WORDS_BIGENDIAN 00075 # define WORDS_BIGENDIAN 0 00076 #endif 00077 00078 // Plugin Prototypes 00079 static void spectrocut_init( void ); 00080 static void spectrocut_about( void ); 00081 static void spectrocut_configure( void ); 00082 static void spectrocut_cleanup( void ); 00083 00084 // Math-Run-Function, "TwoSrc" Prototype 00085 static gboolean spectrocut_run( Scan *Src1, Scan *Src2, Scan *Dest ); 00086 00087 // Fill in the GxsmPlugin Description here 00088 GxsmPlugin spectrocut_pi = { 00089 NULL, // filled in and used by Gxsm, don't touch ! 00090 NULL, // filled in and used by Gxsm, don't touch ! 00091 0, // filled in and used by Gxsm, don't touch ! 00092 NULL, // The Gxsm-App Class Ref.pointer (called "gapp" in Gxsm) is 00093 // filled in here by Gxsm on Plugin load, 00094 // just after init() is called !!! 00095 // ---------------------------------------------------------------------- 00096 // Plugins Name, CodeStly is like: Name-M1S|M2S-BG|F1D|F2D|ST|TR|Misc 00097 "Spectrocut-" 00098 "M2S" 00099 "-Misc", 00100 // Plugin's Category - used to autodecide on Pluginloading or ignoring 00101 // NULL: load, else 00102 // example: "+noHARD +STM +AFM" 00103 // load only, if "+noHARD: no hardware" and Instrument is STM or AFM 00104 // +/-xxxHARD und (+/-INST or ...) 00105 NULL, 00106 // Description, is shown by PluginViewer (Plugin: listplugin, Tools->Plugin Details) 00107 "uses marked areas in topographic scans (active) to cut corresponding areas from chan. X.", 00108 // Author(s) 00109 "Andreas Klust", 00110 // Menupath to position where it is appendet to 00111 N_("_Math/_Misc/"), 00112 // Menuentry 00113 N_("Spectrocut"), 00114 // help text shown on menu 00115 N_("cut areas marked in active scan out of X channel."), 00116 // more info... 00117 "no more info", 00118 NULL, // error msg, plugin may put error status msg here later 00119 NULL, // Plugin Status, managed by Gxsm, plugin may manipulate it too 00120 // init-function pointer, can be "NULL", 00121 // called if present at plugin load 00122 spectrocut_init, 00123 // query-function pointer, can be "NULL", 00124 // called if present after plugin init to let plugin manage it install itself 00125 NULL, // query should be "NULL" for Gxsm-Math-Plugin !!! 00126 // about-function, can be "NULL" 00127 // can be called by "Plugin Details" 00128 spectrocut_about, 00129 // configure-function, can be "NULL" 00130 // can be called by "Plugin Details" 00131 spectrocut_configure, 00132 // run-function, can be "NULL", if non-Zero and no query defined, 00133 // it is called on menupath->"plugin" 00134 NULL, // run should be "NULL" for Gxsm-Math-Plugin !!! 00135 // cleanup-function, can be "NULL" 00136 // called if present at plugin removeal 00137 spectrocut_cleanup 00138 }; 00139 00140 // special math Plugin-Strucure, use 00141 // GxsmMathOneSrcPlugin spectrocut_m1s_pi -> "OneSrcMath" 00142 // GxsmMathTwoSrcPlugin spectrocut_m2s_pi -> "TwoSrcMath" 00143 GxsmMathTwoSrcPlugin spectrocut_m2s_pi 00144 = { 00145 // math-function to run, see prototype(s) above!! 00146 spectrocut_run 00147 }; 00148 00149 // Text used in Aboutbox, please update!! 00150 static const char *about_text = N_("Gxsm Spectrocut Plugin\n\n" 00151 "Spectrocut Code for OneSrcArgMath"); 00152 00153 // Symbol "get_gxsm_plugin_info" is resolved by dlsym from Gxsm, used to get Plugin's info!! 00154 // Essential Plugin Function!! 00155 GxsmPlugin *get_gxsm_plugin_info ( void ){ 00156 spectrocut_pi.description = g_strdup_printf(N_("Gxsm MathTwoArg spectrocut plugin %s"), VERSION); 00157 return &spectrocut_pi; 00158 } 00159 00160 // Symbol "get_gxsm_math_one|two_src_plugin_info" is resolved by dlsym from Gxsm, 00161 // used to find out which Math Type the Plugin is!! 00162 // Essential Plugin Function!! 00163 GxsmMathTwoSrcPlugin *get_gxsm_math_two_src_no_same_size_check_plugin_info( void ) { 00164 return &spectrocut_m2s_pi; 00165 } 00166 00167 // 00168 // 5.) Start here with the plugins code, vars def., etc.... here. 00169 // ---------------------------------------------------------------------- 00170 // 00171 00172 00173 // init-Function 00174 static void spectrocut_init(void) 00175 { 00176 PI_DEBUG (DBG_L2, "Spectrocut Plugin Init"); 00177 } 00178 00179 // about-Function 00180 static void spectrocut_about(void) 00181 { 00182 const gchar *authors[] = { spectrocut_pi.authors, NULL}; 00183 gtk_widget_show(gnome_about_new ( spectrocut_pi.name, 00184 VERSION, 00185 N_("(C) 2002 the Free Software Foundation"), 00186 about_text, 00187 authors, 00188 NULL, NULL, NULL 00189 )); 00190 } 00191 00192 // configure-Function 00193 static void spectrocut_configure(void) 00194 { 00195 if(spectrocut_pi.app) 00196 spectrocut_pi.app->message("Spectrocut Plugin Configuration"); 00197 } 00198 00199 // cleanup-Function 00200 static void spectrocut_cleanup(void) 00201 { 00202 PI_DEBUG (DBG_L2, "Spectrocut Plugin Cleanup"); 00203 } 00204 00205 // run-Function 00206 static gboolean spectrocut_run(Scan *Src1, Scan *Src2, Scan *Dest) 00207 { 00208 // reduce Dest size to save memory 00209 Dest->mem2d->Resize(0, 0); 00210 00211 // first check some prerequisites: 00212 00213 // both sources must have the same real space size, but may 00214 // have different resolution 00215 if (Src1->data.s.rx != Src2->data.s.rx || Src1->data.s.ry != Src2->data.s.ry) 00216 return MATH_SELECTIONERR; 00217 00218 // I need at least one object 00219 int n_obj = Src1->number_of_object (); 00220 if (n_obj < 1) 00221 return MATH_SELECTIONERR; 00222 00223 // iterate over all objects 00224 for (int i=0; i<n_obj; i++) 00225 { 00226 scan_object_data *obj_data; 00227 obj_data = Src1->get_object_data (i); 00228 00229 obj_data->dump (); 00230 00231 // only rectangles are supported: 00232 // if (!strncmp (obj_data->get_name (), "Rectangle", 9) ) 00233 // return MATH_SELECTIONERR; 00234 00235 int n_pts = obj_data->get_num_points (); 00236 // support for two-point objects, only 00237 if (n_pts != 2) 00238 return MATH_SELECTIONERR; 00239 00240 // get real world coordinates 00241 double x0, y0, x1, y1; 00242 obj_data->get_xy (0, x0, y0); 00243 obj_data->get_xy (1, x1, y1); 00244 00245 // sort the points, that point 0 becomes the lower left corner 00246 if (x1 < x0) 00247 { 00248 double swap = x0; 00249 x0 = x1; 00250 x1 = swap; 00251 } 00252 if (y1 < y0) 00253 { 00254 double swap = y0; 00255 y0 = y1; 00256 y1 = swap; 00257 } 00258 00259 cout << x0 << " " << y0 << endl; 00260 cout << x1 << " " << y1 << endl; 00261 00262 // calculate pixel coordinates 00263 int xl = (int)( (x0 - Src2->data.s.x0 + Src2->data.s.rx/2) / Src2->data.s.dx ); 00264 int xr = (int)( (x1 - Src2->data.s.x0 + Src2->data.s.rx/2) / Src2->data.s.dx ); 00265 int yb = (int)( (Src2->data.s.y0 - y0) / Src2->data.s.dy ); 00266 int yt = (int)( (Src2->data.s.y0 - y1) / Src2->data.s.dy ); 00267 00268 cout << xl << " " << yb << endl; 00269 cout << xr << " " << yt << endl; 00270 00271 // make sure the pixel coord. lie within the scan Src2 00272 if (xl < 0) xl=0; 00273 if (xl > Src2->mem2d->GetNx()-1) xl = Src2->mem2d->GetNx()-1; 00274 if (xr < 0) xr=0; 00275 if (xr > Src2->mem2d->GetNx()-1) xr = Src2->mem2d->GetNx()-1; 00276 if (yb < 0) yb=0; 00277 if (yb > Src2->mem2d->GetNy()-1) yb = Src2->mem2d->GetNy()-1; 00278 if (yt < 0) yt=0; 00279 if (yt > Src2->mem2d->GetNy()-1) yt = Src2->mem2d->GetNy()-1; 00280 00281 cout << xl << " " << yb << endl; 00282 cout << xr << " " << yt << endl; 00283 00284 00285 // let's dump the spectroscopic data 00286 00287 short *buf; 00288 if(!(buf = g_new(short, (xr-xl+1)*(yb-yt+1)))) 00289 return MATH_NOMEM; 00290 00291 ofstream f; 00292 f.open("/tmp/spec.ivec", ios::out); 00293 00294 // write header for octave file 00295 f << "# Created by the Gxsm spectrocut plug-in" << endl; 00296 f << "# name: index_vector" << endl; 00297 f << "# type: matrix" << endl; 00298 f << "# rows: 1" << endl; 00299 f << "# columns: " << (xr-xl+1)*(yb-yt+1) << endl; 00300 00301 for (int j=yt; j<=yb; j++) 00302 for (int i=xl; i<=xr; i++) 00303 f << i + Src2->mem2d->GetNx() * (Src2->mem2d->GetNy()-j-1) << " "; 00304 00305 f << endl; 00306 00307 // for (int v=0; v < Src2->data.lp.nvalues; v++) 00308 // { 00309 // short *pt = buf; 00310 // for (int i=xl; i<=xr; i++) 00311 // for (int j=yt; j<=yb; j++, pt++) 00312 // { 00313 // *pt = (short) Src2->mem2d->GetDataPkt (i, j, v); 00314 // // dump using big endian format 00315 // // to maintain compatibility with SCALA SPM files 00316 // if (!WORDS_BIGENDIAN) { 00317 // char *cpt = (char*)pt; 00318 // char low = cpt[0]; 00319 // cpt[0] = cpt[1]; 00320 // cpt[1] = low; 00321 // } 00322 // } 00323 00324 // if(f.good()) 00325 // f.write((void*)buf, sizeof(short) * (xr-xl+1)*(yb-yt+1)); 00326 // else { 00327 // g_free(buf); 00328 // return MATH_FILE_ERROR; 00329 // } 00330 00331 // } 00332 00333 g_free(buf); 00334 f.close(); 00335 00336 } 00337 00338 return MATH_OK; 00339 } 00340 00341 // end of spectrocut.C