dataio.C

Go to the documentation of this file.
00001 /* Gxsm - Gnome X Scanning Microscopy
00002  * universal STM/AFM/SARLS/SPALEED/... controlling and
00003  * data analysis software
00004  * 
00005  * Copyright (C) 1999,2000,2001,2002,2003 Percy Zahl
00006  *
00007  * Authors: Percy Zahl <zahl@users.sf.net>
00008  * additional features: Andreas Klust <klust@users.sf.net>
00009  * WWW Home: http://gxsm.sf.net
00010  *
00011  * This program is free software; you can redistribute it and/or modify
00012  * it under the terms of the GNU General Public License as published by
00013  * the Free Software Foundation; either version 2 of the License, or
00014  * (at your option) any later version.
00015  *
00016  * This program is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  * GNU General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU General Public License
00022  * along with this program; if not, write to the Free Software
00023  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
00024  */
00025 
00026 /* -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 8 c-style: "K&R" -*- */
00027 
00028 #define IMGMAXCOLORS 64
00029 
00030 
00031 #include <locale.h>
00032 #include <libintl.h>
00033 
00034 #include <fstream>
00035 
00036 #include <config.h>
00037 #include <gnome.h>
00038 
00039 
00040 #include "xsmdebug.h"
00041 #include "glbvars.h" // wegen Inst->... nur wegen dat Type !
00042 #include "util.h"
00043 
00044 
00045 #include "dataio.h"
00046 #include "plug-ins/control/spm_scancontrol.h"
00047 
00048 double Contrast_to_VRangeZ (double contrast, double dz){
00049         return 64.*dz/contrast;
00050 }
00051 double VRangeZ_to_Contrast (double vrz, double dz){
00052         return 64.*dz/vrz;
00053 }
00054 
00055 // BaseClass Dataio
00056 const char* Dataio::ioStatus(){
00057         switch(status){
00058         case FIO_OK: return 0;
00059         case FIO_OPEN_ERR: return "file open failed";
00060         case FIO_WRITE_ERR: return "file write failed";
00061         case FIO_READ_ERR: return "file read failed";
00062         case FIO_NSC_ERR: return "file read nsc-type failed, file truncated?";
00063         case FIO_NO_DATFILE: return "no valid dat file";
00064         case FIO_NO_NAME: return "no valid filename";
00065         case FIO_NO_MEM: return "no free memory";
00066         case FIO_NO_GNUFILE: return "no valid gnu or d2d file";
00067         case FIO_NO_NETCDFFILE: return "no valid NetCDF file";
00068         case FIO_NO_NETCDFXSMFILE: return "no valid NetCDF XSM file";
00069         case FIO_NOT_RESPONSIBLE_FOR_THAT_FILE: return "Handler does not support this filetype";
00070         case FIO_INVALID_FILE: return "invalid/inconsistent data file";
00071         default: return "Dataio: unknown error";
00072         }
00073         return 0;
00074 }
00075 
00076 
00077 // ==============================================================
00078 //
00079 // Standard Data Format NetCDF
00080 //
00081 // ==============================================================
00082 
00083 #define NUM(array) (sizeof(array)/sizeof(array[0]))
00084 
00085 FIO_STATUS NetCDF::Read(){
00086         int i;
00087         // switching off error messages, this is potentially
00088         // dangerous, because it may hide serious errors, OTOH
00089         // it hides the annoying non-existence messages when opening.
00090         //NcError ncerr(NcError::verbose_nonfatal);
00091         NcError ncerr(NcError::silent_nonfatal);
00092         
00093         ZD_TYPE zdata_typ=ZD_SHORT; // used by "H" -- Topographic STM/AFM data
00094 
00095         NcFile nc(name);
00096         // Check if the file was opened successfully
00097         if (! nc.is_valid())
00098                 return status = FIO_OPEN_ERR;
00099 
00100         gapp->progress_info_new ("NetCDF Read Progress", 2);
00101         gapp->progress_info_set_bar_fraction (0., 1);
00102         gapp->progress_info_set_bar_text (name, 1);
00103 
00104         scan->data.ui.SetName (name);
00105 
00106         NcVar *Data = NULL;
00107         if(! ( Data = nc.get_var("H")) ){ // not standart "SHORT" Topo Scan ?
00108                 if( ( Data = nc.get_var("Intensity") ) ) // Diffract Scan "LONG" ?
00109                         gapp->progress_info_set_bar_text ("H: Type LONG", 2),
00110                         zdata_typ=ZD_LONG; // used by "Intensity" -- diffraction counts
00111                 else
00112                         if( ( Data = nc.get_var("FloatField") ) ) // Float ?
00113                                 gapp->progress_info_set_bar_text ("H: Type FLOAT", 2),
00114                                 zdata_typ=ZD_FLOAT;
00115                         else
00116                                 if( ( Data = nc.get_var("DoubleField") ) ) // Double ?
00117                                         gapp->progress_info_set_bar_text ("H: Type DOUBLE", 2),
00118                                         zdata_typ=ZD_DOUBLE;
00119                                 else
00120                                         if( ( Data = nc.get_var("ByteField") ) ) // Byte ?
00121                                                 gapp->progress_info_set_bar_text ("H: Type BYTE", 2),
00122                                                 zdata_typ=ZD_BYTE;
00123                                         else
00124                                                 if( ( Data = nc.get_var("ComplexDoubleField") ) ) // Complex ?
00125                                                         gapp->progress_info_set_bar_text ("H: Type COMPLEX", 2),
00126                                                         zdata_typ=ZD_COMPLEX;
00127                                                 else
00128                                                         if( ( Data = nc.get_var("RGBA_ByteField") ) ) // RGBA Byte ?
00129                                                                 gapp->progress_info_set_bar_text ("H: Type RGBA", 2),
00130                                                                 zdata_typ=ZD_RGBA;
00131 
00132                 gapp->progress_info_set_bar_text ("H: Type SHORT", 2);
00133                 gapp->progress_info_set_bar_fraction (0., 2);
00134         }
00135   
00136         if(! Data){ // fremdes NetCDF File, search for 2D Data
00137                 int n,flg=0;
00138                 static char *types[] =
00139                         {"","byte","char","short","long","float","double"};
00140                 NcVar *vp;
00141 
00142                 gapp->progress_info_set_bar_text ("Other NetCDF Data", 2);
00143 
00144                 XSM_DEBUG(DBG_L2, "Searching for 2D Data in alien NetCDF..." );
00145                 for(n = 0; (vp = nc.get_var(n)) && !flg; n++) {
00146                         XSM_DEBUG_PLAIN (DBG_L3, "\t" << types[vp->type()] << " " << vp->name() );
00147                         if (vp->num_dims() > 0) {
00148                                 XSM_DEBUG_PLAIN (DBG_L3, "(");
00149                                 for (int d = 0; d < vp->num_dims(); d++) {
00150                                         NcDim* dim = vp->get_dim(d);
00151                                         XSM_DEBUG_PLAIN (DBG_L3, dim->name() );
00152                                         if (d < vp->num_dims()-1)
00153                                                 XSM_DEBUG_PLAIN (DBG_L3,  ", " );
00154                                 }
00155                                 XSM_DEBUG_PLAIN (DBG_L3, ")" );
00156                         }
00157                         if (vp->num_dims() == 2) {
00158                                 flg=1;
00159                                 NcDim* dimyd = vp->get_dim(0);
00160                                 NcDim* dimxd = vp->get_dim(1);
00161                                 XSM_DEBUG_PLAIN (DBG_L3, "(" << (scan->data.s.ny = dimyd->size()));
00162                                 XSM_DEBUG_PLAIN (DBG_L3, ")(" << (scan->data.s.nx = dimxd->size()) << ") found !!" );
00163                                 scan->mem2d->Resize(scan->data.s.nx, scan->data.s.ny);
00164 
00165                                 switch(vp->type()){
00166                                 case ncByte:
00167                                 {
00168                                         unsigned char *linebufc = new unsigned char[dimxd->size()];
00169                                         SHT *linebuf = new SHT[dimxd->size()];
00170                                         if(!linebuf || !linebufc)
00171                                                 return status = FIO_NO_MEM;
00172             
00173                                         for(int line=0; line<dimyd->size(); line++){
00174                                                 vp->set_cur(line);
00175                                                 vp->get(linebufc, 1,dimxd->size());
00176                                                 for(int i=0; i<dimxd->size(); i++)
00177                                                         linebuf[i] = linebufc[i];
00178                                                 scan->mem2d->PutDataLine(line, linebuf);
00179                                         }
00180                                         delete linebufc;
00181                                         delete linebuf;
00182                                 }
00183                                 break;
00184                                 case ncChar:
00185                                 {
00186                                         char *linebufc = new char[dimxd->size()];
00187                                         SHT *linebuf = new SHT[dimxd->size()];
00188                                         if(!linebuf || !linebufc)
00189                                                 return status = FIO_NO_MEM;
00190             
00191                                         for(int line=0; line<dimyd->size(); line++){
00192                                                 vp->set_cur(line);
00193                                                 vp->get(linebufc, 1,dimxd->size());
00194                                                 for(int i=0; i<dimxd->size(); i++)
00195                                                         linebuf[i] = linebufc[i];
00196                                                 scan->mem2d->PutDataLine(line, linebuf);
00197                                         }
00198                                         delete linebufc;
00199                                         delete linebuf;
00200                                 }
00201                                 break;
00202                                 case ncShort:
00203                                 {
00204                                         SHT *linebuf = new SHT[dimxd->size()];
00205                                         if(!linebuf)
00206                                                 return status = FIO_NO_MEM;
00207             
00208                                         for(int line=0; line<dimyd->size(); line++){
00209                                                 vp->set_cur(line);
00210                                                 vp->get(linebuf, 1,dimxd->size());
00211                                                 scan->mem2d->PutDataLine(line, linebuf);
00212                                         }
00213                                         delete linebuf;
00214                                 }
00215                                 break;
00216                                 default: flg=0; break;
00217                                 }
00218                         }    
00219                 }
00220                 if(flg)
00221                         return status = FIO_OK;
00222                 else
00223                         return status = FIO_NO_NETCDFXSMFILE;
00224         }
00225 
00226 
00227         gapp->progress_info_set_bar_text ("Variables", 2);
00228         gapp->progress_info_set_bar_fraction (0.25, 1);
00229 
00230         NcDim *timed = Data->get_dim(0);
00231         scan->data.s.ntimes  = timed->size();
00232 
00233         NcDim *valued = Data->get_dim(1);
00234         scan->data.s.nvalues = valued->size();
00235 
00236         NcDim *dimyd = Data->get_dim(2);
00237         scan->data.s.ny = dimyd->size();
00238 
00239         NcDim *dimxd = Data->get_dim(3);
00240         scan->data.s.nx = dimxd->size();
00241 
00242         scan->mem2d->Resize(scan->data.s.nx, scan->data.s.ny, scan->data.s.nvalues, zdata_typ);
00243         scan->mem2d->data->NcGet(Data);
00244 
00245         if (valued->size() > 1){
00246                 XSM_DEBUG(DBG_L2, "reading valued arr... n=" << valued->size() );
00247                 float *valuearr = new float[valued->size()];
00248                 if(!valuearr)
00249                         return status = FIO_NO_MEM;
00250           
00251                 XSM_DEBUG(DBG_L2, "getting array..." );
00252                 nc.get_var("value")->get (valuearr, valued->size());
00253                 for(i=0; i<valued->size(); i++){
00254                         scan->mem2d->data->SetVLookup(i, valuearr[i]);
00255                         XSM_DEBUG_PLAIN (DBG_L3, valuearr[i] << " ");
00256                 }
00257           
00258                 XSM_DEBUG_PLAIN (DBG_L3, "done." );
00259                 delete [] valuearr;
00260         }
00261 
00262         float *dimsx = new float[dimxd->size()];
00263         if(!dimsx)
00264                 return status = FIO_NO_MEM;
00265 
00266 //--OffRotFix-- -> check for old version and fix offset (not any longer in Lookup)
00267         
00268         double Xoff = 0.;
00269         double Yoff = 0.;
00270         if (! nc.get_var("dimx")->get_att("extra_info")){ // if this attribut is present, then no offset correction!
00271                 nc.get_var("offsetx")->get(&Xoff);
00272                 nc.get_var("offsety")->get(&Yoff);
00273         }
00274 
00275         nc.get_var("dimx")->get(dimsx, dimxd->size());
00276         for(i=0; i<dimxd->size(); i++)
00277                 scan->mem2d->data->SetXLookup(i, dimsx[i]-Xoff);
00278 
00279         delete [] dimsx;
00280 
00281         float *dimsy = new float[dimyd->size()];
00282         if(!dimsy)
00283                 return status = FIO_NO_MEM;
00284 
00285         nc.get_var("dimy")->get(dimsy, dimyd->size());
00286         for(i=0; i<dimyd->size(); i++)
00287                 scan->mem2d->data->SetYLookup(i, dimsy[i]-Yoff);
00288 
00289         delete [] dimsy;
00290 
00291         NcAtt *unit_att = NULL;
00292         NcAtt *label_att = NULL;
00293 
00294         if ((unit_att = nc.get_var("value")->get_att("unit"))){
00295                 if ((label_att = nc.get_var("value")->get_att("label"))){
00296                         NcValues *unit  = unit_att->values();
00297                         NcValues *label = label_att->values();
00298                         UnitObj *u = gapp->xsm->MakeUnit (unit->as_string(0), label->as_string(0));
00299                         scan->data.SetVUnit(u);
00300                         delete unit;
00301                         delete label;
00302                         delete u;
00303                         delete label_att;
00304                         label_att = NULL;
00305                 }
00306                 delete unit_att;
00307                 unit_att = NULL;
00308         }
00309 
00310         nc.get_var("rangex")->get(&scan->data.s.rx);
00311         if ((unit_att = nc.get_var("rangex")->get_att("unit"))){
00312                 if ((label_att = nc.get_var("rangex")->get_att("label"))){
00313                         NcValues *unit  = unit_att->values();
00314                         NcValues *label = label_att->values();
00315                         UnitObj *u = gapp->xsm->MakeUnit (unit->as_string(0), label->as_string(0));
00316                         scan->data.SetXUnit(u);
00317                         delete unit;
00318                         delete label;
00319                         delete u;
00320                         delete label_att;
00321                         label_att = NULL;
00322                 }
00323                 delete unit_att;
00324                 unit_att = NULL;
00325         }
00326         nc.get_var("rangey")->get(&scan->data.s.ry);
00327         if ((unit_att = nc.get_var("rangey")->get_att("unit"))){
00328                 if ((label_att = nc.get_var("rangey")->get_att("label"))){
00329                         NcValues *unit  = unit_att->values();
00330                         NcValues *label = label_att->values();
00331                         UnitObj *u = gapp->xsm->MakeUnit (unit->as_string(0), label->as_string(0));
00332                         scan->data.SetYUnit(u);
00333                         delete unit;
00334                         delete label;
00335                         delete u;
00336                         delete label_att;
00337                         label_att = NULL;
00338                 }
00339                 delete unit_att;
00340                 unit_att = NULL;
00341         }
00342         nc.get_var("rangez")->get(&scan->data.s.rz);
00343         if ((unit_att = nc.get_var("rangez")->get_att("unit"))){
00344                 if ((label_att = nc.get_var("rangez")->get_att("label"))){
00345                         NcValues *unit  = unit_att->values();
00346                         NcValues *label = label_att->values();
00347                         UnitObj *u = gapp->xsm->MakeUnit (unit->as_string(0), label->as_string(0));
00348                         scan->data.SetZUnit(u);
00349                         delete unit;
00350                         delete label;
00351                         delete u;
00352                         delete label_att;
00353                         label_att = NULL;
00354                 }
00355                 delete unit_att;
00356                 unit_att = NULL;
00357         }
00358         nc.get_var("dx")->get(&scan->data.s.dx);
00359         nc.get_var("dy")->get(&scan->data.s.dy);
00360         nc.get_var("dz")->get(&scan->data.s.dz);
00361         nc.get_var("offsetx")->get(&scan->data.s.x0);
00362         nc.get_var("offsety")->get(&scan->data.s.y0);
00363         nc.get_var("alpha")->get(&scan->data.s.alpha);
00364 
00365         nc.get_var("contrast")->get(&scan->data.display.contrast);
00366         nc.get_var("bright")->get(&scan->data.display.bright);
00367 
00368         scan->data.display.vrange_z = Contrast_to_VRangeZ (scan->data.display.contrast, scan->data.s.dz);
00369 
00370         NcVar *comment = nc.get_var("comment"); 
00371         G_NEWSIZE(scan->data.ui.comment, 1+comment->get_dim(0)->size());
00372         memset (scan->data.ui.comment, 0, 1+comment->get_dim(0)->size());
00373         comment->get(scan->data.ui.comment, comment->get_dim(0)->size());
00374 
00375         NcVar *username = nc.get_var("username"); 
00376         G_NEWSIZE(scan->data.ui.user, username->get_dim(0)->size());
00377         username->get(scan->data.ui.user, username->get_dim(0)->size());
00378 
00379         NcVar *dateofscan = nc.get_var("dateofscan"); 
00380         G_NEWSIZE(scan->data.ui.dateofscan, dateofscan->get_dim(0)->size());
00381         dateofscan->get(scan->data.ui.dateofscan, dateofscan->get_dim(0)->size());
00382 
00383         if(nc.get_var("t_start")) nc.get_var("t_start")->get(&scan->data.s.tStart);
00384         if(nc.get_var("t_end")) nc.get_var("t_end")->get(&scan->data.s.tEnd);
00385         // restore last view mode
00386         if(nc.get_var("viewmode")){ 
00387                 nc.get_var("viewmode")->get(&scan->data.display.ViewFlg); 
00388                 scan->SetVM(scan->data.display.ViewFlg);
00389         } 
00390         if(nc.get_var("vrange_z")) nc.get_var("vrange_z")->get(&scan->data.display.vrange_z);
00391         if(nc.get_var("voffset_z")) nc.get_var("voffset_z")->get(&scan->data.display.voffset_z);
00392 
00393         // invalidate maker points
00394         scan->PktVal=0;
00395 
00396         if(nc.get_var("basename")){
00397                 int len;
00398                 G_NEWSIZE(scan->data.ui.originalname, len=nc.get_var("basename")->get_dim(0)->size());
00399                 nc.get_var("basename")->get(scan->data.ui.originalname, len);
00400                 XSM_DEBUG (DBG_L2, "got original name:" << scan->data.ui.originalname);
00401         }
00402         else{
00403                 scan->data.ui.SetOriginalName ("original name is not available");
00404                 XSM_DEBUG (DBG_L2, "original name is not available");
00405         }
00406         if(nc.get_var("energy"  )) nc.get_var("energy"  )->get(&scan->data.s.Energy);
00407         if(nc.get_var("gatetime")){
00408                 nc.get_var("gatetime")->get(&scan->data.s.GateTime );
00409                 scan->data.display.cnttime = scan->data.s.GateTime;
00410                 scan->data.s.dz = 1./scan->data.display.cnttime;
00411         }
00412         if(nc.get_var("cnttime")){
00413                 nc.get_var("cnttime")->get(&scan->data.display.cnttime);
00414                 scan->data.s.dz = 1./scan->data.display.cnttime;
00415         }
00416         if(nc.get_var("cnt_high" )){
00417                 nc.get_var("cnt_high" )->get(&scan->data.display.cpshigh);
00418                 scan->data.display.cpshigh /= scan->data.display.cnttime;
00419         }
00420         if(nc.get_var("cps_high" )) nc.get_var("cps_high" )->get(&scan->data.display.cpshigh);
00421 
00422         if(nc.get_var("cnt_low"  )){
00423                 nc.get_var("cnt_low"  )->get(&scan->data.display.cpslow);
00424                 scan->data.display.cpslow /= scan->data.display.cnttime;
00425         }
00426         if(nc.get_var("cps_low" )) nc.get_var("cps_low" )->get(&scan->data.display.cpslow);
00427 
00428         if(nc.get_var("spa_orgx"  )) nc.get_var("spa_orgx"  )->get(&scan->data.s.SPA_OrgX);
00429         if(nc.get_var("spa_orgy"  )) nc.get_var("spa_orgy"  )->get(&scan->data.s.SPA_OrgY);
00430 
00431         //  if(nc.get_var("")) nc.get_var("")->get(&scan->data.hardpars.);
00432 
00433         // load attached Events, if any
00434         gapp->progress_info_set_bar_fraction (0.5, 1);
00435         gapp->progress_info_set_bar_text ("Events", 2);
00436         scan->mem2d->LoadScanEvents (&nc);
00437 
00438         // Signal PlugIns
00439         gapp->progress_info_set_bar_fraction (0.75, 1);
00440         gapp->progress_info_set_bar_text ("Plugin Data", 2);
00441         gapp->SignalCDFLoadEventToPlugins (&nc);
00442 
00443         gapp->progress_info_set_bar_fraction (1., 1);
00444         gapp->progress_info_close ();
00445         return status = FIO_OK; 
00446 }
00447 
00448 
00449 FIO_STATUS NetCDF::Write(){
00450         XSM_DEBUG (DBG_L2, "NetCDF::Write");
00451         // name convention NetCDF: *.nc
00452 
00453         NcError ncerr(NcError::verbose_nonfatal);
00454         NcFile nc(name, NcFile::Replace); // Create, leave in define mode
00455 
00456         scan->data.ui.SetName(name);
00457 
00458         // Check if the file was opened successfully
00459         if (! nc.is_valid())
00460                 return status = FIO_OPEN_ERR;
00461 
00462         gapp->progress_info_new ("NetCDF Write Progress",2);
00463         gapp->progress_info_set_bar_fraction (0., 1);
00464         gapp->progress_info_set_bar_text (name, 1);
00465         gapp->progress_info_set_bar_fraction (0., 2);
00466 
00467         XSM_DEBUG (DBG_L2, "NetCDF::Write-> open OK");
00468 
00469         // Create dimensions
00470 #define NTIMES   1
00471 #define TIMELEN 40
00472 #define VALUEDIM 1
00473         NcDim* timed  = nc.add_dim("time", scan->data.s.ntimes);        // Time of Scan
00474         NcDim* valued = nc.add_dim("value", scan->data.s.nvalues);     // Value of Scan, eg. Volt / Force
00475         NcDim* dimxd  = nc.add_dim("dimx", scan->mem2d->GetNx()); // Image Dim. in X (#Samples)
00476         NcDim* dimyd  = nc.add_dim("dimy", scan->mem2d->GetNy()); // Image Dim. in Y (#Samples)
00477   
00478         NcDim* reftimed  = nc.add_dim("reftime", TIMELEN);  // Starting time
00479   
00480         NcDim* commentd    = nc.add_dim("comment", strlen(scan->data.ui.comment)+1);       // Comment
00481         NcDim* titled      = nc.add_dim("title", strlen(scan->data.ui.title)+1);           // Title
00482         NcDim* usernamed   = nc.add_dim("username", strlen(scan->data.ui.user)+1);         // Username
00483         NcDim* dateofscand = nc.add_dim("dateofscan", strlen(scan->data.ui.dateofscan)+1); // Scandate
00484 
00485         XSM_DEBUG (DBG_L2, "NetCDF::Write-> Creating Data Var");
00486         // Create variables and their attributes
00487         NcVar* Data;
00488         switch(scan->mem2d->GetTyp()){
00489         case ZD_BYTE:
00490                 Data = nc.add_var("ByteField", ncByte, timed, valued, dimyd, dimxd);
00491                 Data->add_att("long_name", "byte data field");
00492                 Data->add_att("units", "not defined");
00493                 break;
00494         case ZD_SHORT:
00495                 Data = nc.add_var("H", ncShort, timed, valued, dimyd, dimxd);
00496                 Data->add_att("long_name", "Topographic");
00497                 Data->add_att("units", "Digital Units");
00498                 break;
00499         case ZD_LONG: 
00500                 Data = nc.add_var("Intensity", ncLong, timed, valued, dimyd, dimxd);
00501                 Data->add_att("long_name", "diffraction intensity");
00502                 Data->add_att("units", "counts (cnt), divide by cnttime (gatetime) to get CPS");
00503                 break;
00504         case ZD_FLOAT: 
00505                 Data = nc.add_var("FloatField", ncFloat, timed, valued, dimyd, dimxd);
00506                 Data->add_att("long_name", "float data field");
00507                 Data->add_att("units", "not defined");
00508                 break;
00509         case ZD_DOUBLE: 
00510                 Data = nc.add_var("DoubleField", ncDouble, timed, valued, dimyd, dimxd);
00511                 Data->add_att("long_name", "double data field");
00512                 Data->add_att("units", "not defined");
00513                 break;
00514         case ZD_COMPLEX: 
00515                 Data = nc.add_var("ComplexDoubleField", ncDouble, timed, valued, dimyd, dimxd);
00516                 Data->add_att("long_name", "complex (abs,re,im) double data field");
00517                 Data->add_att("units", "not defined");
00518                 break;
00519         case ZD_RGBA: 
00520                 Data = nc.add_var("RGBA_ByteField", ncDouble, timed, valued, dimyd, dimxd);
00521                 Data->add_att("long_name", "byte RGBA data field");
00522                 Data->add_att("units", "not defined");
00523                 break;
00524         default:
00525                 return status = FIO_NO_NETCDFXSMFILE;
00526                 break;
00527         }
00528 
00529         XSM_DEBUG (DBG_L2, "NetCDF::Write-> Adding Units ZLab");
00530 
00531         Data->add_att("ZLabel", scan->data.Zunit->Label());
00532         Data->add_att("unit", scan->data.Zunit->Symbol());
00533         if (scan->data.Zunit->Alias())
00534                 Data->add_att("ZSrcUnit", scan->data.Zunit->Alias());
00535         else
00536                 XSM_DEBUG(DBG_L2, "NetCDF::Write-> Warning: No Alias for Z unit, cannot restore unit on load" );
00537   
00538         XSM_DEBUG (DBG_L2, "NetCDF::Write-> Adding time, att");
00539 
00540         NcVar* time  = nc.add_var("time", ncLong, timed);
00541         time->add_att("long_name", "Time since reftime");
00542         time->add_att("unit", "s");
00543   
00544         XSM_DEBUG (DBG_L2, "NetCDF::Write-> Adding Units Value");
00545 
00546         NcVar* value = nc.add_var("value", ncFloat, valued);
00547         value->add_att("long_name", "Image Layers of SrcType at Values");
00548         if (scan->data.Vunit){
00549                 value->add_att("label", scan->data.Vunit->Label());
00550                 value->add_att("unit", scan->data.Vunit->Symbol());
00551         }else{
00552                 value->add_att("label", "Value");
00553                 value->add_att("unit", "A.U.");
00554         }
00555   
00556         XSM_DEBUG (DBG_L2, "NetCDF::Write-> dim x y reft");
00557 
00558         NcVar* dimx  = nc.add_var("dimx", ncFloat, dimxd);
00559         dimx->add_att("long_name", "# Pixels in X, contains X-Pos Lookup");
00560         dimx->add_att("extra_info", "X-Lookup without offset");
00561   
00562         NcVar* dimy  = nc.add_var("dimy", ncFloat, dimyd);
00563         dimy->add_att("long_name", "# Pixels in Y, contains Y-Pos Lookup");
00564         dimy->add_att("extra_info", "Y-Lookup without offset");
00565   
00566         NcVar* reftime  = nc.add_var("reftime", ncChar, reftimed);
00567         reftime->add_att("long_name", "Reference time, i.e. Scan Start");
00568         reftime->add_att("unit", "date string");
00569   
00570 
00571         XSM_DEBUG (DBG_L2, "NetCDF::Write-> Comment Title ...");
00572 
00573         NcVar* comment    = nc.add_var("comment", ncChar, commentd);
00574         NcVar* title      = nc.add_var("title", ncChar, titled);
00575         NcVar* username   = nc.add_var("username", ncChar, usernamed);
00576         NcVar* dateofscan = nc.add_var("dateofscan", ncChar, dateofscand);
00577   
00578 // This unit and label entries are used to restore the correct unit later!
00579         NcVar* rangex     = nc.add_var("rangex", ncDouble);
00580         rangex->add_att("Info", "This number is alwalys in Angstroem. Unit is used for display only!");
00581         rangex->add_att("label", scan->data.Xunit->Label());
00582         if (scan->data.Xunit->Alias())
00583                 rangex->add_att("unit", scan->data.Xunit->Alias());
00584         else
00585                 rangex->add_att("unitSymbol", scan->data.Xunit->Symbol());
00586 
00587         NcVar* rangey     = nc.add_var("rangey", ncDouble);
00588         rangey->add_att("label", scan->data.Yunit->Label());
00589         rangey->add_att("Info", "This number is alwalys in Angstroem. Unit is used for display only!");
00590         if (scan->data.Yunit->Alias())
00591                 rangey->add_att("unit", scan->data.Yunit->Alias());
00592         else
00593                 rangey->add_att("unitSymbol", scan->data.Yunit->Symbol());
00594 
00595         NcVar* rangez     = nc.add_var("rangez", ncDouble);
00596         rangez->add_att("label", scan->data.Zunit->Label());
00597         if (scan->data.Zunit->Alias())
00598                 rangez->add_att("unit", scan->data.Zunit->Alias());
00599         else
00600                 rangez->add_att("unitSymbol", scan->data.Zunit->Symbol());
00601 
00602         NcVar* dx         = nc.add_var("dx", ncDouble);
00603         dx->add_att("Info", "This number is alwalys in Angstroem. Unit is used for display only!");
00604         dx->add_att("label", scan->data.Xunit->Label());
00605         dx->add_att("unit", scan->data.Xunit->Symbol());
00606         NcVar* dy         = nc.add_var("dy", ncDouble);
00607         dy->add_att("Info", "This number is alwalys in Angstroem. Unit is used for display only!");
00608         dy->add_att("label", scan->data.Yunit->Label());
00609         dy->add_att("unit", scan->data.Yunit->Symbol());
00610         NcVar* dz         = nc.add_var("dz", ncDouble);
00611         dz->add_att("Info", "This number is alwalys in Angstroem. Unit is used for display only!");
00612         dz->add_att("label", scan->data.Yunit->Label());
00613         dz->add_att("unit", scan->data.Zunit->Symbol());
00614         NcVar* offsetx    = nc.add_var("offsetx", ncDouble);
00615         offsetx->add_att("Info", "This number is alwalys in Angstroem. Unit is used for display only!");
00616         offsetx->add_att("unit", scan->data.Xunit->Symbol());
00617         NcVar* offsety    = nc.add_var("offsety", ncDouble);
00618         offsety->add_att("unit", scan->data.Yunit->Symbol());
00619         offsety->add_att("Info", "This number is alwalys in Angstroem. Unit is used for display only!");
00620         NcVar* alpha      = nc.add_var("alpha", ncDouble);
00621         alpha->add_att("unit", "Grad");
00622   
00623         NcVar* contrast   = nc.add_var("contrast", ncDouble);
00624         NcVar* bright     = nc.add_var("bright", ncDouble);
00625 
00626         XSM_DEBUG (DBG_L2, "NetCDF::Write-> Creating Options Vars");
00627         // optional...
00628         NcVar* display_vrange_z  = NULL;
00629         NcVar* display_voffset_z = NULL;
00630 
00631         if(!(IS_SPALEED_CTRL)){
00632                 display_vrange_z = nc.add_var("vrange_z", ncDouble);
00633                 display_vrange_z->add_att("long_name", "View Range Z");
00634                 display_vrange_z->add_att("label", scan->data.Zunit->Label());
00635                 if (scan->data.Zunit->Alias())
00636                         display_vrange_z->add_att("unit", scan->data.Zunit->Alias());
00637 
00638                 display_voffset_z = nc.add_var("voffset_z", ncDouble);
00639                 display_voffset_z->add_att("long_name", "View Offset Z");
00640                 display_voffset_z->add_att("label", scan->data.Zunit->Label());
00641                 if (scan->data.Zunit->Alias())
00642                         display_voffset_z->add_att("unit", scan->data.Zunit->Alias());
00643         }
00644 
00645         NcVar* t_start      = nc.add_var("t_start", ncLong);
00646         NcVar* t_end        = nc.add_var("t_end", ncLong);
00647 
00648         NcVar* viewmode     = nc.add_var("viewmode", ncLong);
00649         viewmode->add_att("long_name", "last viewmode flag");
00650 
00651         // data.ui.basename:
00652         // filename with the original data (set once and never changed again)
00653         if ( strcmp(scan->data.ui.originalname, "unknown (not saved)") == 0 ){
00654                 scan->data.ui.SetOriginalName( name );
00655                 XSM_DEBUG (DBG_L2, "got original name:" << scan->data.ui.originalname);
00656         }else{
00657                 XSM_DEBUG (DBG_L2, "original left untouched:" << name << " != " << scan->data.ui.originalname);
00658         }
00659 
00660         // donīt confuse: NC basenase := originalname  --  program: ui.basename is only for automatic namegenerating
00661         NcDim* basenamed   = nc.add_dim("basename", strlen(scan->data.ui.originalname)+1);
00662         NcVar* basename    = nc.add_var("basename", ncChar, basenamed);
00663 
00664 
00665         // only for LEED like Instruments
00666         NcVar* energy   = NULL;
00667         NcVar* gatetime = NULL;
00668         NcVar* cnttime  = NULL;
00669         NcVar* cpshigh  = NULL;
00670         NcVar* cpslow   = NULL;
00671         NcVar* spaorgx  = NULL;
00672         NcVar* spaorgy  = NULL;
00673   
00674         if(IS_SPALEED_CTRL){
00675                 energy   = nc.add_var("energy", ncDouble);
00676                 energy->add_att("unit", "eV");
00677 
00678                 gatetime = nc.add_var("gatetime", ncDouble);
00679                 gatetime->add_att("unit", "s");
00680 
00681                 cnttime = nc.add_var("cnttime", ncDouble);
00682                 cnttime->add_att("unit", "s");
00683 
00684                 cpshigh  = nc.add_var("cps_high", ncDouble);
00685                 cpshigh->add_att("unit", "CPS");
00686 
00687                 cpslow   = nc.add_var("cps_low", ncDouble);
00688                 cpslow->add_att("unit", "CPS");
00689 
00690                 spaorgx  = nc.add_var("spa_orgx", ncDouble);
00691                 spaorgx->add_att("unit", "V");
00692 
00693                 spaorgy  = nc.add_var("spa_orgy", ncDouble);
00694                 spaorgy->add_att("unit", "V");
00695         }
00696 
00697         // ....
00698   
00699         // Global attributes
00700         nc.add_att("Creator", PACKAGE);
00701         nc.add_att("Version", VERSION);
00702         nc.add_att("build_from", COMPILEDBYNAME);
00703         nc.add_att("DataIOVer", 
00704                    "$Header: /cvsroot/gxsm/Gxsm-2.0/src/dataio.C,v 1.23 2005/11/02 20:14:42 zahl Exp $"
00705                 );
00706         nc.add_att("HardwareCtrlType", xsmres.HardwareType);
00707         nc.add_att("HardwareConnectionDev", xsmres.DSPDev);
00708         nc.add_att("InstrumentType", xsmres.InstrumentType);
00709         nc.add_att("InstrumentName", xsmres.InstrumentName);
00710   
00711         // Start writing data, implictly leaves define mode
00712 
00713         XSM_DEBUG (DBG_L2, "NetCDF::Write-> NcPut Data");
00714         XSM_DEBUG (DBG_L2, "NC write: " << timed->size() << "x" << valued->size() << "x" << dimxd->size() << "x" << dimyd->size());
00715   
00716         scan->mem2d->data->NcPut(Data);
00717 
00718         time_t timearr[] = { scan->data.s.tEnd-scan->data.s.tStart };
00719         time->put(timearr, NUM(timearr));
00720 
00721         float *valuearr = new float[valued->size()];
00722         if(!valuearr)
00723                 return status = FIO_NO_MEM;
00724 
00725         XSM_DEBUG (DBG_L2, "NetCDF::Write-> NcPut Lookups");
00726         for(int i=0; i<valued->size(); i++)
00727                 valuearr[i] = scan->mem2d->data->GetVLookup(i);
00728 
00729         value->put(valuearr, valued->size());
00730         delete [] valuearr;
00731 
00732         int i;
00733         //  float x0=scan->data.s.x0-scan->data.s.rx/2.;
00734         float *dimsx = new float[dimxd->size()];
00735         if(!dimsx)
00736                 return status = FIO_NO_MEM;
00737 
00738         for(i=0; i<dimxd->size(); i++)
00739                 dimsx[i] = scan->mem2d->data->GetXLookup(i);
00740 
00741         dimx->put(dimsx, dimxd->size());
00742         delete [] dimsx;
00743 
00744         //  float y0=scan->data.s.y0;
00745         float *dimsy = new float[dimyd->size()];
00746         if(!dimsy)
00747                 return status = FIO_NO_MEM;
00748 
00749         for(i=0; i<dimyd->size(); i++)
00750                 dimsy[i] = scan->mem2d->data->GetYLookup(i);
00751 
00752         dimy->put(dimsy, dimyd->size());
00753         delete [] dimsy;
00754 
00755         XSM_DEBUG (DBG_L2, "NetCDF::Write-> NcPut Vars...");
00756         char* s = ctime(&scan->data.s.tStart);
00757         reftime->put(s, strlen(s));
00758   
00759         comment->put(scan->data.ui.comment, commentd->size());
00760 
00761 
00762         title->put(scan->data.ui.title, titled->size());
00763         username->put(scan->data.ui.user, usernamed->size());
00764         dateofscan->put(scan->data.ui.dateofscan, dateofscand->size());
00765 
00766         rangex ->put( &scan->data.s.rx);
00767         rangey ->put( &scan->data.s.ry);
00768         rangez ->put( &scan->data.s.rz); 
00769         dx     ->put( &scan->data.s.dx); 
00770         dy     ->put( &scan->data.s.dy); 
00771         dz     ->put( &scan->data.s.dz); 
00772         offsetx->put( &scan->data.s.x0); 
00773         offsety->put( &scan->data.s.y0); 
00774         alpha  ->put( &scan->data.s.alpha);
00775 
00776         contrast->put( &scan->data.display.contrast); 
00777         bright  ->put( &scan->data.display.bright); 
00778 
00779         // Minimalsatz Variablen endet hier =================================
00780 
00781         // Additional Parameters are following ...
00782 
00783         // Display...
00784         if(display_vrange_z) display_vrange_z->put( &scan->data.display.vrange_z);
00785         if(display_voffset_z) display_voffset_z->put( &scan->data.display.voffset_z);
00786 
00787         t_start->put( &scan->data.s.tStart );
00788         t_end  ->put( &scan->data.s.tEnd );
00789 
00790         viewmode->put( &scan->data.display.ViewFlg );
00791 
00792         basename->put(scan->data.ui.originalname, basenamed->size());
00793 
00794         // only if needed
00795         if(energy   ) energy  ->put( &scan->data.s.Energy );
00796         if(gatetime ) gatetime->put( &scan->data.s.GateTime );
00797         if(cnttime  ) cnttime ->put( &scan->data.display.cnttime);
00798         if(cpshigh  ) cpshigh ->put( &scan->data.display.cpshigh );
00799         if(cpslow   ) cpslow  ->put( &scan->data.display.cpslow );
00800         if(spaorgx  ) spaorgx ->put( &scan->data.s.SPA_OrgX );
00801         if(spaorgy  ) spaorgy ->put( &scan->data.s.SPA_OrgY );
00802 
00803 
00804         // write attached Events, if any
00805         scan->mem2d->WriteScanEvents (&nc);
00806 
00807         // Signal PlugIns
00808         // g_print ("gapp->SignalCDFSaveEventToPlugins (&nc);  (%x)\n", &nc);
00809         XSM_DEBUG (DBG_L2, "NetCDF::Write-> SignalCDFSaveEventToPlugins (&nc);");
00810         gapp->SignalCDFSaveEventToPlugins (&nc);
00811 
00812         // close of nc takes place in destructor
00813         scan->draw ();
00814 
00815         // Check if the file was written successfully
00816         if ( ncerr.get_err() )
00817                 return status = FIO_WRITE_ERR;
00818 
00819 
00820         XSM_DEBUG (DBG_L2, "NetCDF::Write-> OK.");
00821         gapp->progress_info_close ();
00822 
00823         return status = FIO_OK; 
00824 }
00825 

Generated on Sat Apr 1 09:03:52 2006 for GXSM by  doxygen 1.4.6