spa4_d2d_im_export.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: g_dat_im_export.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  * --------------------------------------------------------------------------------
00032 % BeginPlugInDocuSection
00033 % PlugInDocuCaption: SPA--LEED (SPA4) d2d data file Import
00034 % PlugInName: spa4_im_export
00035 % PlugInAuthor: Percy Zahl
00036 % PlugInAuthorEmail: zahl@users.sf.net
00037 % PlugInMenuPath: File/Import/SPA4-d2d
00038 
00039 % PlugInDescription
00040 \label{plugins:spa4_d2d_im_export}
00041 The \GxsmEmph{spa4\_d2d\_im\_export} plug-in supports reading of SPA--LEED (SPA4) d2d data files.
00042 
00043 PlugIn in construction.
00044 
00045 % PlugInUsage
00046 The plug-in is called by \GxsmMenu{File/Import/SPA4-d2d}.
00047 
00048 % OptPlugInKnownBugs
00049 Not yet tested.
00050 
00051 % EndPlugInDocuSection
00052  * -------------------------------------------------------------------------------- 
00053  */
00054 
00055 #include <gtk/gtk.h>
00056 #include "config.h"
00057 #include "gxsm/plugin.h"
00058 #include "gxsm/dataio.h"
00059 #include "gxsm/action_id.h"
00060 #include "gxsm/util.h"
00061 #include "batch.h"
00062 #include "fileio.c"
00063 
00064 #ifndef WORDS_BIGENDIAN
00065 # define WORDS_BIGENDIAN 0
00066 #else
00067 # define WORDS_BIGENDIAN 1
00068 #endif
00069 
00070 using namespace std;
00071 
00072 // Plugin Prototypes
00073 static void spa4_im_export_init (void);
00074 static void spa4_im_export_query (void);
00075 static void spa4_im_export_about (void);
00076 static void spa4_im_export_configure (void);
00077 static void spa4_im_export_cleanup (void);
00078 
00079 static void spa4_im_export_filecheck_load_callback (gpointer data );
00080 static void spa4_im_export_filecheck_save_callback (gpointer data );
00081 
00082 static void spa4_im_export_import_callback (GtkWidget *w, void *data);
00083 static void spa4_im_export_export_callback (GtkWidget *w, void *data);
00084 
00085 // Fill in the GxsmPlugin Description here
00086 GxsmPlugin spa4_im_export_pi = {
00087   NULL,                   // filled in and used by Gxsm, don't touch !
00088   NULL,                   // filled in and used by Gxsm, don't touch !
00089   0,                      // filled in and used by Gxsm, don't touch !
00090   NULL,                   // The Gxsm-App Class Ref.pointer (called "gapp" in Gxsm) is 
00091                           // filled in here by Gxsm on Plugin load, 
00092                           // just after init() is called !!!
00093   "Spa4_Im_Export",
00094   NULL,                   // PlugIn's Categorie, set to NULL for all, I just don't want this always to be loaded!
00095   // Description, is shown by PluginViewer (Plugin: listplugin, Tools->Plugin Details)
00096   "Im/Export of the SPA4 d2d data file format.",
00097   "Percy Zahl",
00098   N_("_File/_Import/,_File/_Export/"),
00099   N_("SPA4-d2d,SPA4-d2d"),
00100   N_("SPA4 d2d import,SPA4 d2d export"),
00101   N_("SPA-LEED (SPA4) d2d data file import and export filter."),
00102   NULL,          // error msg, plugin may put error status msg here later
00103   NULL,          // Plugin Status, managed by Gxsm, plugin may manipulate it too
00104   spa4_im_export_init,
00105   spa4_im_export_query,
00106   // about-function, can be "NULL"
00107   // can be called by "Plugin Details"
00108   spa4_im_export_about,
00109   // configure-function, can be "NULL"
00110   // can be called by "Plugin Details"
00111   spa4_im_export_configure,
00112   // run-function, can be "NULL", if non-Zero and no query defined, 
00113   // it is called on menupath->"plugin"
00114   NULL,
00115   // cleanup-function, can be "NULL"
00116   // called if present at plugin removeal
00117   spa4_im_export_cleanup
00118 };
00119 
00120 // Text used in Aboutbox, please update!!
00121   static const char *about_text = N_("GXSM SPA4 'd2d' data file Import/Export Plugin\n\n");
00122 
00123 static const char *file_mask = "*.d2d";
00124 
00125 // Symbol "get_gxsm_plugin_info" is resolved by dlsym from Gxsm, used to get Plugin's info!! 
00126 // Essential Plugin Function!!
00127 GxsmPlugin *get_gxsm_plugin_info ( void ){ 
00128   spa4_im_export_pi.description = g_strdup_printf(N_("Gxsm im_export plugin %s"), VERSION);
00129   return &spa4_im_export_pi; 
00130 }
00131 
00132 // Query Function, installs Plugin's in File/Import and Export Menupaths!
00133 // ----------------------------------------------------------------------
00134 // Import Menupath is "File/Import/GME Dat"
00135 // Export Menupath is "File/Export/GME Dat"
00136 // ----------------------------------------------------------------------
00137 // !!!! make sure the "spa4_im_export_cleanup()" function (see below) !!!!
00138 // !!!! removes the correct menuentries !!!!
00139 
00140 static void spa4_im_export_query(void)
00141 {
00142         gchar **path  = g_strsplit (spa4_im_export_pi.menupath, ",", 2);
00143         gchar **entry = g_strsplit (spa4_im_export_pi.menuentry, ",", 2);
00144         gchar **help  = g_strsplit (spa4_im_export_pi.help, ",", 2);
00145 
00146         static GnomeUIInfo menuinfo_i[] = { 
00147                 { GNOME_APP_UI_ITEM, NULL, NULL,
00148                   NULL, NULL,
00149                   NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_OPEN,
00150                   0, GDK_CONTROL_MASK, NULL },
00151                 GNOMEUIINFO_END
00152         };
00153         menuinfo_i[0].label  = entry[0];
00154         menuinfo_i[0].hint   = help[0];
00155         menuinfo_i[0].moreinfo  = (gpointer) spa4_im_export_import_callback; 
00156         menuinfo_i[0].user_data = spa4_im_export_pi.name;
00157 
00158         gnome_app_insert_menus (
00159                 GNOME_APP(spa4_im_export_pi.app->getApp()), 
00160                 path[0], 
00161                 menuinfo_i
00162                 );
00163         
00164 
00165         static GnomeUIInfo menuinfo_e[] = { 
00166                 { GNOME_APP_UI_ITEM, NULL, NULL,
00167                   NULL, NULL,
00168                   NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_SAVE,
00169                   0, GDK_CONTROL_MASK, NULL },
00170                 GNOMEUIINFO_END
00171         };
00172         menuinfo_e[0].label  = entry[1];
00173         menuinfo_e[0].hint   = help[1];
00174         menuinfo_e[0].moreinfo  = (gpointer) spa4_im_export_export_callback; 
00175         menuinfo_e[0].user_data = spa4_im_export_pi.name;
00176 
00177         gnome_app_insert_menus (
00178                 GNOME_APP(spa4_im_export_pi.app->getApp()), 
00179                 path[1],
00180                 menuinfo_e
00181                 );
00182 
00183         if(spa4_im_export_pi.status) g_free(spa4_im_export_pi.status); 
00184         spa4_im_export_pi.status = g_strconcat (
00185                 N_("Plugin query has attached "),
00186                 spa4_im_export_pi.name, 
00187                 N_(": File IO Filters are ready to use."),
00188                 NULL);
00189         
00190         // clean up
00191         g_strfreev (path);
00192         g_strfreev (entry);
00193         g_strfreev (help);
00194 
00195 // register this plugins filecheck functions with Gxsm now!
00196 // This allows Gxsm to check files from DnD, open, 
00197 // and cmdline sources against all known formats automatically - no explicit im/export is necessary.
00198         spa4_im_export_pi.app->ConnectPluginToLoadFileEvent (spa4_im_export_filecheck_load_callback);
00199         spa4_im_export_pi.app->ConnectPluginToSaveFileEvent (spa4_im_export_filecheck_save_callback);
00200 }
00201 
00202 
00203 // 5.) Start here with the plugins code, vars def., etc.... here.
00204 // ----------------------------------------------------------------------
00205 //
00206 
00207 
00208 // init-Function
00209 static void spa4_im_export_init(void)
00210 {
00211         PI_DEBUG (DBG_L2, spa4_im_export_pi.name << "Plugin Init");
00212 }
00213 
00214 // about-Function
00215 static void spa4_im_export_about(void)
00216 {
00217         const gchar *authors[] = { spa4_im_export_pi.authors, NULL};
00218         gtk_widget_show(gnome_about_new ( spa4_im_export_pi.name,
00219                                           VERSION,
00220                                           N_("(C) 2001 the Free Software Foundation"),
00221                                           about_text,
00222                                           authors,
00223                                           NULL, NULL, NULL
00224                                           ));
00225 }
00226 
00227 // configure-Function
00228 static void spa4_im_export_configure(void)
00229 {
00230         if(spa4_im_export_pi.app)
00231                 spa4_im_export_pi.app->message("spa4_im_export Plugin Configuration");
00232 }
00233 
00234 // cleanup-Function, make sure the Menustrings are matching those above!!!
00235 static void spa4_im_export_cleanup(void)
00236 {
00237         gchar **path  = g_strsplit (spa4_im_export_pi.menupath, ",", 2);
00238         gchar **entry = g_strsplit (spa4_im_export_pi.menuentry, ",", 2);
00239 
00240         gchar *tmp = g_strconcat (path[0], entry[0], NULL);
00241         gnome_app_remove_menus (GNOME_APP (spa4_im_export_pi.app->getApp()), tmp, 1);
00242         g_free (tmp);
00243 
00244         tmp = g_strconcat (path[1], entry[1], NULL);
00245         gnome_app_remove_menus (GNOME_APP (spa4_im_export_pi.app->getApp()), tmp, 1);
00246         g_free (tmp);
00247 
00248         g_strfreev (path);
00249         g_strfreev (entry);
00250 
00251         PI_DEBUG (DBG_L2, "Plugin Cleanup done.");
00252 }
00253 
00254 // make a new derivate of the base class "Dataio"
00255 class spa4_ImExportFile : public Dataio{
00256 public:
00257         spa4_ImExportFile(Scan *s, const char *n) : Dataio(s,n){ };
00258         virtual FIO_STATUS Read();
00259         virtual FIO_STATUS Write();
00260 private:
00261         FIO_STATUS import(const char *fname);
00262 };
00263 
00264 FIO_STATUS spa4_ImExportFile::Read(){
00265         FIO_STATUS ret;
00266         gchar *fname=NULL;
00267 
00268         fname = (gchar*)name;
00269 
00270         // name should have at least 4 chars: ".ext"
00271         if (fname == NULL || strlen(fname) < 4)
00272                 return  FIO_NOT_RESPONSIBLE_FOR_THAT_FILE;
00273  
00274         // check for file exists and is OK !
00275         // else open File Dlg
00276         ifstream f;
00277         f.open(fname, ios::in);
00278         if(!f.good()){
00279                 PI_DEBUG (DBG_L2, "Error at file open. File not good/readable.");
00280                 return status=FIO_OPEN_ERR;
00281         }
00282         f.close();
00283 
00284         // Check all known File Types:
00285         if ((ret=import (fname)) !=  FIO_NOT_RESPONSIBLE_FOR_THAT_FILE)
00286                 return ret;
00287 
00288         return  FIO_NOT_RESPONSIBLE_FOR_THAT_FILE;
00289 }
00290 
00291 FIO_STATUS spa4_ImExportFile::import(const char *fname){
00292         D2D_SPA_DAT_HEADER d2d;
00293         char fill[48];
00294         union RAW { guint64 i; gdouble f; } raw;
00295 
00296         // Am I resposible for that file, is it a "Gme-Dat" format ?
00297         ifstream f;
00298         GString *FileList=NULL;
00299 
00300         if (strncasecmp(fname+strlen(fname)-4,".d2d",4)){
00301                 f.close ();
00302                 return status=FIO_NOT_RESPONSIBLE_FOR_THAT_FILE;
00303         }
00304 
00305         f.open(name, ios::in);
00306         if (!f.good())
00307                 return status=FIO_OPEN_ERR;
00308         
00309 
00310         f.read ((char*)&d2d, sizeof (d2d));
00311         f.read ((char*)&fill, sizeof (fill));
00312         
00313         if (WORDS_BIGENDIAN){
00314                 d2d.PointsX = GINT16_FROM_LE (d2d.PointsX);
00315                 d2d.PointsY = GINT16_FROM_LE (d2d.PointsY);
00316 
00317                 raw.f = d2d.XYdist;
00318                 raw.i = GUINT64_FROM_LE (raw.i);
00319                 d2d.XYdist = raw.f;
00320 
00321                 raw.f = d2d.Xo;
00322                 raw.i = GUINT64_FROM_LE (raw.i);
00323                 d2d.Xo = raw.f;
00324 
00325                 raw.f = d2d.Yo;
00326                 raw.i = GUINT64_FROM_LE (raw.i);
00327                 d2d.Yo = raw.f;
00328 
00329                 raw.f = d2d.GateTime;
00330                 raw.i = GUINT64_FROM_LE (raw.i);
00331                 d2d.GateTime = raw.f;
00332 
00333                 raw.f = d2d.Energy;
00334                 raw.i = GUINT64_FROM_LE (raw.i);
00335                 d2d.Energy = raw.f;
00336 
00337                 raw.f = d2d.CpsLow;
00338                 raw.i = GUINT64_FROM_LE (raw.i);
00339                 d2d.CpsLow = raw.f;
00340 
00341                 raw.f = d2d.CpsHigh;
00342                 raw.i = GUINT64_FROM_LE (raw.i);
00343                 d2d.CpsHigh = raw.f;
00344         }
00345 
00346         time_t t; // Scan - Startzeit eintragen 
00347         time(&t);
00348         gchar *tmp = g_strconcat ((ctime(&t)), " (Imported)", NULL); scan->data.ui.SetDateOfScan (tmp); g_free (tmp);
00349         scan->data.ui.SetName (fname);
00350         scan->data.ui.SetOriginalName (fname);
00351         scan->data.ui.SetType ("old dat"); 
00352 
00353 
00354         // this is mandatory.
00355         scan->data.s.ntimes  = 1;
00356         scan->data.s.nvalues = 1;
00357   
00358   
00359         // put some usefull values in the ui structure
00360         if(getlogin()){
00361                 scan->data.ui.SetUser (getlogin());
00362         }
00363         else{
00364                 scan->data.ui.SetUser ("unkonwn user");
00365         }
00366 
00367         // initialize scan structure -- this is a minimum example
00368         scan->data.s.nx = d2d.PointsX;
00369         scan->data.s.ny = d2d.PointsY;
00370         scan->data.s.dx = d2d.XYdist/d2d.PointsX;;
00371         scan->data.s.dy = d2d.XYdist*d2d.PointsY/d2d.PointsX/d2d.PointsX;
00372         scan->data.s.dz = 1;
00373         scan->data.s.rx = scan->data.s.nx*scan->data.s.dx;
00374         scan->data.s.ry = scan->data.s.ny*scan->data.s.dy;
00375         scan->data.s.x0 = d2d.Xo;
00376         scan->data.s.y0 = d2d.Yo;
00377         scan->data.s.alpha = 0;
00378 
00379         // be nice and reset this to some defined state
00380         scan->data.s.GateTime = d2d.GateTime*1e-3;
00381         scan->data.s.Energy   = d2d.Energy;
00382         scan->data.s.SPA_OrgX     = 0.;
00383         scan->data.s.SPA_OrgY     = 0.;
00384         scan->data.display.cpshigh       = d2d.CpsHigh;
00385         scan->data.display.cpslow        = d2d.CpsLow;
00386         scan->data.display.cnttime       = d2d.GateTime;
00387 
00388         // set the default view parameters
00389         scan->data.display.bright = 32.;
00390         scan->data.display.contrast = 1.0;
00391 
00392         // FYI: (PZ)
00393         //  scan->data.display.vrange_z  = ; // View Range Z in base ZUnits
00394         //  scan->data.display.voffset_z = 0; // View Offset Z in base ZUnits
00395         //  scan->AutoDisplay([...]); // may be used too...
00396   
00397 
00398         FileList = g_string_new ("Imported by GXSM from SPA4-d2d data file.\n");
00399         g_string_sprintfa (FileList, "Original Filename: %s\n", fname);
00400         g_string_append (FileList, "Orig. Comment: ");
00401         g_string_append (FileList, d2d.comment);
00402         g_string_append (FileList, "\n");
00403         g_string_append (FileList, "Orig. Date of Scan: ");
00404         g_string_append (FileList, d2d.dateofscan);
00405         g_string_append (FileList, "\n");
00406 
00407         scan->data.ui.SetComment (FileList->str);
00408         g_string_free(FileList, TRUE); 
00409         FileList=NULL;
00410 
00411         scan->data.s.dx = scan->data.s.rx / scan->data.s.nx;
00412         scan->data.s.dy = scan->data.s.ry / scan->data.s.ny;
00413 
00414         // Read Img Data.
00415         scan->mem2d->Resize (scan->data.s.nx, scan->data.s.ny);
00416         scan->mem2d->DataD2DRead (f, d2d.GateTime);
00417 
00418         scan->data.orgmode = SCAN_ORG_CENTER;
00419         scan->mem2d->data->MkXLookup (-scan->data.s.rx/2., scan->data.s.rx/2.);
00420         scan->mem2d->data->MkYLookup (-scan->data.s.ry/2., scan->data.s.ry/2.);
00421   
00422         return FIO_OK; 
00423 }
00424 
00425 
00426 FIO_STATUS spa4_ImExportFile::Write(){
00427         GtkWidget *dialog = gtk_message_dialog_new (NULL,
00428                                                     GTK_DIALOG_DESTROY_WITH_PARENT,
00429                                                     GTK_MESSAGE_INFO,
00430                                                     GTK_BUTTONS_OK,
00431                                                     N_("Sorry, not yet implemented.")
00432                                                     );
00433         gtk_dialog_run (GTK_DIALOG (dialog));
00434         gtk_widget_destroy (dialog);
00435 
00436 #if 0
00437         gchar tmp[0x4004];
00438         const gchar *fname;
00439         ofstream f;
00440 
00441         memset (tmp, 0, sizeof (tmp));
00442 
00443         if(strlen(name)>0)
00444                 fname = (const char*)name;
00445         else
00446                 fname = gapp->file_dialog("File Export: SPA4 d2d"," ",file_mask,"","SPA4 d2d write");
00447         if (fname == NULL) return FIO_NO_NAME;
00448 
00449         // check if we like to handle this
00450         if (strncmp(fname+strlen(fname)-4,".d2d",4))
00451                 return FIO_NOT_RESPONSIBLE_FOR_THAT_FILE;
00452 
00453 
00454         f.open(name, ios::out);
00455         if (!f.good())
00456                 return status=FIO_OPEN_ERR;
00457 
00458 //      scan->mem2d->DataWrite(f);
00459 #endif
00460   return FIO_OK; 
00461 }
00462 
00463 // Plugin's Notify Cb's, registered to be called on file load/save to check file
00464 // return via filepointer, it is set to Zero or passed as Zero if file has been processed!
00465 // That's all fine, you should just change the Text Stings below...
00466 
00467 
00468 static void spa4_im_export_filecheck_load_callback (gpointer data ){
00469         gchar **fn = (gchar**)data;
00470         if (*fn){
00471                 PI_DEBUG (DBG_L2, 
00472                           "Check File: spa4_im_export_filecheck_load_callback called with >"
00473                           << *fn << "<" );
00474 
00475                 Scan *dst = gapp->xsm->GetActiveScan();
00476                 if(!dst){ 
00477                         gapp->xsm->ActivateFreeChannel();
00478                         dst = gapp->xsm->GetActiveScan();
00479                 }
00480                 spa4_ImExportFile fileobj (dst, *fn);
00481 
00482                 FIO_STATUS ret = fileobj.Read(); 
00483                 if (ret != FIO_OK){ 
00484                         // I'am responsible! (But failed)
00485                         if (ret != FIO_NOT_RESPONSIBLE_FOR_THAT_FILE)
00486                                 *fn=NULL;
00487                         // no more data: remove allocated and unused scan now, force!
00488                         gapp->xsm->SetMode(-1, ID_CH_M_OFF, TRUE); 
00489                         PI_DEBUG (DBG_L2, "Read Error " << ((int)ret) << "!!!!!!!!" );
00490                 }else{
00491                         // got it!
00492                         *fn=NULL;
00493 
00494                         // Now update gxsm main window data fields
00495                         gapp->xsm->ActiveScan->GetDataSet(gapp->xsm->data);
00496                         gapp->spm_update_all();
00497                         dst->draw();
00498                 }
00499         }else{
00500                 PI_DEBUG (DBG_L2, "spa4_im_export_filecheck_load: Skipping" );
00501         }
00502 }
00503 
00504 static void spa4_im_export_filecheck_save_callback (gpointer data ){
00505         gchar **fn = (gchar**)data;
00506         if (*fn){
00507                 Scan *src;
00508                 PI_DEBUG (DBG_L2,
00509                           "Check File: spa4_im_export_filecheck_save_callback called with >"
00510                           << *fn << "<" );
00511 
00512                 spa4_ImExportFile fileobj (src = gapp->xsm->GetActiveScan(), *fn);
00513 
00514                 FIO_STATUS ret;
00515                 ret = fileobj.Write(); 
00516 
00517                 if(ret != FIO_OK){
00518                         // I'am responsible! (But failed)
00519                         if (ret != FIO_NOT_RESPONSIBLE_FOR_THAT_FILE)
00520                                 *fn=NULL;
00521                         PI_DEBUG (DBG_L2, "Write Error " << ((int)ret) << "!!!!!!!!" );
00522                 }else{
00523                         // write done!
00524                         *fn=NULL;
00525                 }
00526         }else{
00527                 PI_DEBUG (DBG_L2, "spa4_im_export_filecheck_save: Skipping >" << *fn << "<" );
00528         }
00529 }
00530 
00531 // Menu Call Back Fkte
00532 
00533 static void spa4_im_export_import_callback(GtkWidget *w, void *data){
00534         gchar **help = g_strsplit (spa4_im_export_pi.help, ",", 2);
00535         gchar *dlgid = g_strconcat (spa4_im_export_pi.name, "-import", NULL);
00536         gchar *fn = gapp->file_dialog(help[0], NULL, file_mask, NULL, dlgid);
00537         g_strfreev (help); 
00538         g_free (dlgid);
00539         spa4_im_export_filecheck_load_callback (&fn );
00540 }
00541 
00542 static void spa4_im_export_export_callback(GtkWidget *w, void *data){
00543         gchar **help = g_strsplit (spa4_im_export_pi.help, ",", 2);
00544         gchar *dlgid = g_strconcat (spa4_im_export_pi.name, "-export", NULL);
00545         gchar *fn = gapp->file_dialog(help[1], NULL, file_mask, NULL, dlgid);
00546         g_strfreev (help); 
00547         g_free (dlgid);
00548         spa4_im_export_filecheck_save_callback (&fn );
00549 }

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