DataLoad.cpp

Go to the documentation of this file.
00001 // DataLoad.cpp
00002 
00003 /*************************************************************/
00004 //
00005 // GreyLabWindow
00006 //
00007 // Data loading routines for the GreyLabWindow class
00008 //
00009 //-------------------------------------------------------------
00010 //
00011 // v 1.15 - 2007/09/23 - Changes to allow <ChA> etc use
00012 // v 1.14 - 2007/08/26 - Matrix data type loading
00013 // v 1.13 - 2007/05/30 - Changes to load header file
00014 // v 1.12 - 2007/02/09 - X target range and better autoranging
00015 // v 1.11 - 2007/02/07 - Info in title bar
00016 // v 1.10 - 2007/02/01 - ysd scatter option
00017 // v 1.9 - 2006/11/23 - File stat
00018 // v 1.8 - 2006/08/28 - Fixed a bug where pointers were not NULLed after a failed load
00019 // v 1.7 - 2006/08/16 - Acorn CryoMeas Acorn file loading (v2.4.0)
00020 // v 1.6 - 2006/08/07 - More better handling of the SD mess (v2.2.4)
00021 // v 1.5 - 2006/07/31 - Better handling of the SD mess (v2.2.3)
00022 // v 1.4 - 2006/07/11 - Improvements to auto ranging on analysis tab (v2.2.2)
00023 // v 1.3 - 2006/07/10 - Fixed 'midpoint' sweeps
00024 // v 1.2 - 2006/07/08 - Fixed a bug on notification of Iconlist clear
00025 // v 1.1 - 2006/07/07 - Changes to autorange
00026 // v 1.0 - 2006/04/19 - Initial release
00027 //
00028 // See LICENSE.txt for distribution and usage restrictions
00029 // Copyright (c) 2005-2007 Simon Chorley
00030 // www.mylaboratory.co.uk - greylab@mylaboratory.co.uk
00031 //
00032 /*************************************************************/
00033 
00034 
00035 ///Data loading functions
00036 /**
00037  * Provides implementation of GreyLabWindow functions to load the data.
00038  * @file DataLoad.cpp
00039  * @version 1.14 - 2007/08/26
00040  */
00041 
00042 
00043 #include "GreyLab.h"
00044 #include "LAfile.h"
00045 
00046 #include <iostream>
00047 #include <fstream>
00048 
00049 #define MAXSTRING 1000000
00050 
00051 
00052 ///Starts the data loading procedure
00053 /**
00054  * Chooses the loading algorithm and calls the appropriate function. All parameters are ignored.
00055  */
00056 long GreyLabWindow::cmdLoad(FXObject* o, FXSelector, void*)
00057 {
00058         FXString s = separatorTextfield->getText();
00059         if (s.length() == 0) sdinfo.separator = '\t';
00060         else if (s.length() == 1) sdinfo.separator = s[0];
00061         else
00062         {
00063                 if (s == "\\t") sdinfo.separator = '\t';
00064                 else sdinfo.separator = s[0];
00065         }
00066 
00067         this->setTitle(FXStringFormat("GreyLab %d.%d.%d - ", MAJORV, MINORV, BUILDV)+pathTextfield->getText().rafter('/').rafter('\\')+" - "+projfile.rafter('/').rafter('\\'));
00068         hdText->setText(FXString("No header information"));
00069 
00070         sdinfo.ch298 = -1;
00071         sdinfo.ch299 = -1;
00072         settranslatechCheckbutton->disable();
00073 
00074         FXString err;
00075         if (sdasciiRadiobutton->getCheck() == true)
00076         {
00077                 if (dataTextSDLoad(err) == -1)  //for some reason I can't use message boxes inside this function??
00078                 {
00079                         if (err.length() > 0) FXMessageBox::error(this, FX::MBOX_OK, "Error!", err.text());
00080 //                      contentsTabbook->enable();
00081                         return(1);
00082                 }
00083         }
00084         else if (sdacornRadiobutton->getCheck() == true)
00085         {
00086                 if (dataBinarySDLoad(err) == -1)
00087                 {
00088                         if (err.length() > 0) FXMessageBox::error(this, FX::MBOX_OK, "Error!", err.text());
00089 //                      contentsTabbook->enable();
00090                         return(1);
00091                 }
00092         }
00093         else if (sdmatrixRadiobutton->getCheck() == true)
00094         {
00095                 if (dataTextMatrixLoad(err) == -1)      //for some reason I can't use message boxes inside this function??
00096                 {
00097                         if (err.length() > 0) FXMessageBox::error(this, FX::MBOX_OK, "Error!", err.text());
00098 //                      contentsTabbook->enable();
00099                         return(1);
00100                 }
00101         }
00102         else
00103         {
00104                 if (dataTextLoad(err) == -1)
00105                 {
00106                         if (err.length() > 0) FXMessageBox::error(this, FX::MBOX_OK, "Error!", err.text());
00107 //                      contentsTabbook->enable();
00108                         return(1);
00109                 }
00110         }
00111 
00112 #ifdef WIN32
00113         _stat(pathTextfield->getText().text(), &fileinfo);
00114 #else
00115         stat(pathTextfield->getText().text(), &fileinfo);
00116 #endif
00117 
00118 
00119         dayminTextfield->disable();
00120         daymaxTextfield->disable();
00121 //      if (setautoscaleCheckbutton->getCheck() == true)        //removed 07/12/2007
00122         cmdDARangeChange(NULL, 0, NULL);
00123         if (setautobinCheckbutton->getCheck() == true)
00124         {
00125                 if (sd != NULL)
00126                 {
00127                         if (sd[0].npoints > 1)
00128                         {
00129                                 daxtgtresTextfield->setText(FXStringVal(fabs(
00130                                         (rawdata[0][sd[0].npoints-1]-rawdata[0][0])/((float)sd[0].npoints/FXFloatVal(setbinsizeTextfield->getText())))));
00131                         }
00132                 }
00133         }
00134         contentsTabbook->enable();
00135 
00136         return(1);
00137 }
00138 
00139 
00140 #define CHECK   if (strlen(dataline) == MAXSTRING-1) { e = "Input SD line too long"; sdstream.close(); return(1); }
00141 #define CHECK2  if (strlen(dataline) == MAXSTRING-1) { e = "Input data line too long"; datafile.close(); return(1); }
00142 
00143 ///Loads data using a CryoMeasLV status data file
00144 /**
00145  * @param[out] e Error string.
00146  * @return Success (0) or failure (-1).
00147  */
00148 long GreyLabWindow::dataTextSDLoad(FXString &e)
00149 {
00150         int i, j, c;
00151 
00152         //Delete old data
00153         if (sd != NULL)
00154         {
00155                 for (i = 0; i < sdinfo.nsweeps; ++i)
00156                         if (sd[i].item != NULL)
00157                         {
00158                                 delete[] sd[i].item;
00159                                 sd[i].item = NULL;
00160                         }
00161                 delete[] sd;
00162                 sd = NULL;
00163         }
00164         if (rawdata != NULL)
00165         {
00166                 for (i = 0; i < sdinfo.nsweeps*sdinfo.ncols; ++i)
00167                         if (rawdata[i] != NULL)
00168                         {
00169                                 delete[] rawdata[i];
00170                                 rawdata[i] = NULL;
00171                         }
00172                 delete[] rawdata;
00173                 rawdata = NULL;
00174         }
00175 
00176         std::ifstream hdrstream;
00177         FXString hdrfile = pathTextfield->getText();
00178         FXString hdr;
00179         hdrfile.insert(hdrfile.find_last_of('.', hdrfile.length()-1), "Hdr");
00180         hdrstream.open(hdrfile.text(), std::ifstream::in);
00181         if (hdrstream.is_open())
00182         {
00183                 char hdrbuf[10000];
00184                 do
00185                 {
00186                         hdrstream.getline(hdrbuf, 10000);
00187                         hdr.append(hdrbuf);
00188                         hdr.trimEnd();
00189                         hdr += '\n';
00190                 }
00191                 while (!hdrstream.eof());
00192                 hdText->setText(hdr);
00193                 hdrstream.close();
00194         }
00195 
00196 ///////////////////
00197 // Load SD
00198 ///////////////////
00199         std::ifstream sdstream;
00200 
00201         FXString sdfile = pathTextfield->getText();
00202         sdfile.insert(sdfile.find_last_of('.', sdfile.length()-1), "SD");
00203 
00204         sdstream.open(sdfile.text(), std::ifstream::in);
00205         if (!sdstream.is_open())
00206         {
00207                 e = "No such input file";
00208                 return(-1);
00209         }
00210 
00211         char dataline[MAXSTRING];
00212         char ch;
00213         sdstream >> ch;
00214         int linesbefore = 0;    //lines before the SD proper
00215         while (((ch < '0') || (ch > '9')) && (!sdstream.eof())) //while not a number
00216         {
00217                 sdstream.getline(dataline, MAXSTRING);          //discard line
00218                 ++linesbefore;
00219                 CHECK
00220                 sdstream >> ch;
00221         }
00222         if (sdstream.eof())
00223         {
00224                 e = "The format of the status data file is not recognised (could not find the number of sweeps)";
00225                 return(-1);
00226         }
00227         sdstream.seekg(-1, std::ios::cur);      //seek back 1 character
00228 
00229         float val;
00230         sdstream >> val;
00231         sdinfo.nsweeps = (int)val;
00232         sdnsweepsTextfield->setText(FXStringVal(sdinfo.nsweeps));
00233         sdstream.getline(dataline, MAXSTRING);
00234         CHECK
00235         sdstream >> val;
00236         sdinfo.ncols = (int)val;
00237         sdncolsTextfield->setText(FXStringVal(sdinfo.ncols));
00238         sdstream.getline(dataline, MAXSTRING);
00239         CHECK
00240         sdstream >> val;
00241         sdinfo.nsd = (int)val;
00242         sdnsdTextfield->setText(FXStringVal(sdinfo.nsd));
00243         sdstream.getline(dataline, MAXSTRING);
00244         CHECK
00245         sdstream >> val;
00246         sdinfo.npoints = (int)val;
00247         sdnptsTextfield->setText(FXStringVal((unsigned int)sdinfo.npoints));
00248         sdstream.getline(dataline, MAXSTRING);
00249         CHECK
00250         sdstream >> sdinfo.version;
00251         if ((sdinfo.version < 2.0) || (sdinfo.version >= 3.0))
00252         {
00253                 e = "Input SD version wrong";
00254                 sdstream.close();
00255                 return(-1);
00256         }
00257 
00258         // Clear SD iconlist
00259         sdIconlist->clearItems(false);
00260         for (i = sdIconlist->getNumHeaders(); i > 0; --i)
00261                 sdIconlist->removeHeader(i-1);
00262 
00263         FXString sdheaders;
00264         FXString temp;
00265         int tempi, snpos, slpos;        //sweep number position, sweep length position
00266         bool snfirst;
00267         sdstream.seekg(0, std::ios::beg);
00268         for (i = 0; i < linesbefore; ++i)
00269                 sdstream.getline(dataline, MAXSTRING);
00270         if (sdstream.eof())
00271         {
00272                 e = "The format of the status data file is not recognised (could not find the SD column labels)";
00273                 return(-1);
00274         }
00275         sdheaders = dataline;
00276         tempi = sdheaders.find("Sweep number\t");
00277         if (tempi != -1)        //probably LV-like
00278         {
00279                 snpos = (sdheaders.left(tempi)).contains('\t');
00280                 slpos = (sdheaders.left(sdheaders.find("sweep length\t"))).contains('\t');
00281                 if (snpos < slpos)
00282                 {
00283                         snfirst = true;
00284                         slpos -= snpos;
00285                 }
00286                 else
00287                 {
00288                         snfirst = false;
00289                         snpos -= slpos;
00290                 }
00291         }
00292         else
00293         {
00294                 tempi = sdheaders.find("number\t");
00295                 if (tempi == -1)
00296                 {
00297                         e = "The format of the status data file is not recognised (could not find the sweep number column)";
00298                         return(-1);
00299                 }
00300                 snpos = (sdheaders.left(tempi)).contains('\t');
00301                 slpos = (sdheaders.left(sdheaders.find("rows in sweep\t"))).contains('\t');
00302                 if (snpos < slpos)
00303                 {
00304                         snfirst = true;
00305                         slpos -= snpos;
00306                 }
00307                 else
00308                 {
00309                         snfirst = false;
00310                         snpos -= slpos;
00311                 }
00312         }
00313 
00314 
00315         FXString ilheaders;// = "Swp N\nSwp len\nX col";        //icon list headers
00316         sdIconlist->appendHeader("Swp N");
00317         sdIconlist->appendHeader("Swp len");
00318         sdIconlist->appendHeader("X col");
00319         sdheaders = (sdheaders.right(sdheaders.length()-sdheaders.find("SD "))).after('\t', 1);
00320         daysdListbox->clearItems();     //clear ysd list
00321         daysdListbox->appendItem("<Swp N>");
00322         daysdListbox->appendItem("<Manual>");
00323         for (i = 0; i < sdinfo.nsd; ++i)
00324         {
00325 //              ilheaders += FXString("\n");
00326                 temp = (sdheaders.before('\t', 1)).trimEnd();
00327                 if (temp.length() != 0)         //if item not blank
00328                 {
00329 //                      ilheaders += temp;
00330                         if (temp.rfind(':') != -1)      //new style with channel numbers
00331                         {
00332                                 FXString ch = temp.rafter(':');
00333                                 sdIconlist->appendHeader(temp.rbefore(':')+"\n"+ch);
00334                                 if (ch == "298")
00335                                         sdinfo.ch298 = i;
00336                                 else if (ch == "299")
00337                                         sdinfo.ch299 = i;
00338                         }
00339                         else    //old style without channel numbers
00340                         {
00341                                 sdIconlist->appendHeader(temp);
00342                         }
00343                         daysdListbox->appendItem(temp);
00344                 }
00345                 else
00346                 {
00347 //                      ilheaders += FXStringVal(i);
00348                         sdIconlist->appendHeader(FXStringVal(i));
00349                         daysdListbox->appendItem(FXStringVal(i));
00350                 }
00351                 sdheaders = sdheaders.after('\t', 1);
00352         }
00353         if ((sdinfo.ch298 != -1) || (sdinfo.ch299 != -1))
00354                 settranslatechCheckbutton->enable();
00355 //      sdIconlist->setHeaders(ilheaders, 3+sdinfo.nsd);
00356         sdIconlist->setHeaderSize(0, 30);
00357         sdIconlist->setHeaderSize(1, 50);
00358         sdIconlist->setHeaderSize(2, 20);
00359         for (i = 0; i < sdinfo.nsd; ++i)
00360         {
00361                 sdIconlist->setHeaderSize(3+i, 60);
00362         }
00363 //      cerr << '\"' << ilheaders.text() << '\"';
00364 
00365         ilheaders = "\0";
00366         double d;
00367         statusProgressbar->setTotal(sdinfo.nsweeps);
00368         int maxlines = 0;       //so we know how long to make the progress bar
00369         sd = new statusdata[sdinfo.nsweeps];
00370         for (i = 0; i < sdinfo.nsweeps; ++i)
00371         {
00372                 sd[i].npoints = 0;
00373                 sd[i].item = NULL;
00374         }
00375         int previous = -1, current = -1;
00376         i = 0;
00377         unsigned int p = 0;
00378         sdstream.seekg(0, std::ios::beg);
00379         for (i = 0; i <= linesbefore; ++i)
00380                 sdstream.getline(dataline, MAXSTRING);
00381         i = 0;
00382         do
00383         {
00384                 sdheaders = dataline;
00385                 if (snfirst == true)
00386                 {
00387                         sdheaders = sdheaders.after('\t', snpos);
00388                         current = (int)FXDoubleVal((sdheaders.before('\t', 1)).trimEnd());      //sweep number
00389                         sdheaders = sdheaders.after('\t', slpos);
00390                         d = FXDoubleVal((sdheaders.before('\t', 1)).trimEnd()); //npoints in sweep
00391                         p = (unsigned int)d;
00392                         sdheaders = sdheaders.after('\t', 4-snpos-slpos);
00393                 }
00394                 else
00395                 {
00396                         sdheaders = sdheaders.after('\t', slpos);
00397                         d = FXDoubleVal((sdheaders.before('\t', 1)).trimEnd()); //npoints in sweep
00398                         p = (unsigned int)d;
00399                         sdheaders = sdheaders.after('\t', snpos);
00400                         current = (int)FXDoubleVal((sdheaders.before('\t', 1)).trimEnd());      //sweep number
00401                         sdheaders = sdheaders.after('\t', 4-snpos-slpos);
00402                 }
00403                 if (current > 0)
00404                 {
00405                         if (current != previous)
00406                         {
00407                                 sd[i].xcol = (int)FXDoubleVal((sdheaders.before('\t', 1)).trimEnd());   //x column
00408                                 sdheaders = sdheaders.after('\t', 1);
00409                                 sd[i].item = new double[sdinfo.nsd];
00410                                 for (j = 0; j < sdinfo.nsd; ++j)
00411                                 {
00412                                         sdheaders = sdheaders.after('\t', 1);
00413                                         d = FXDoubleVal((sdheaders.before('\t', 1)).trimEnd());
00414                                         sd[i].item[j] = d;
00415                                 }
00416                                 sd[i].npoints = p;
00417                                 statusProgressbar->setProgress(i+1);
00418                                 previous = current;
00419                                 ++i;
00420                         }
00421                 }
00422                 sdstream.getline(dataline, MAXSTRING);
00423         }
00424         while ((current != 0) && (strlen(dataline) != 0));
00425         if (i == 0)
00426         {
00427                 e = "The format of the status data file is not recognised (could not work out column ordering or there are no sweeps)";
00428                 return(-1);
00429         }
00430         for (i = 0; i < sdinfo.nsweeps; ++i)
00431         {
00432                 ilheaders += FXStringVal(i)+FXString("\t");
00433                 ilheaders += FXStringVal((unsigned int)sd[i].npoints)+FXString("\t");
00434                 if (sd[i].npoints > maxlines) maxlines = sd[i].npoints;
00435                 ilheaders += FXStringVal(sd[i].xcol);
00436                 for (j = 0; j < sdinfo.nsd; ++j)
00437                 {
00438                         ilheaders += FXString("\t");
00439                         ilheaders += FXStringVal(sd[i].item[j]);        //SD
00440                 }
00441                 ilheaders += FXString("\n");
00442         }
00443         sdIconlist->fillItems(ilheaders, NULL, NULL, NULL, true);
00444 
00445         for (i = 0; i < sdinfo.nsweeps; ++i)
00446                 sdIconlist->selectItem(i, true);
00447 
00448 /*
00449         std::ifstream sdstream;
00450 
00451         FXString sdfile = pathTextfield->getText();
00452         sdfile.insert(sdfile.find_last_of('.', sdfile.length()-1), "SD");
00453 //      cerr << sdfile.text();
00454 
00455         sdstream.open(sdfile.text(), std::ifstream::in);
00456         if (!sdstream.is_open())
00457         {
00458                 e = "No such input file";
00459                 return(-1);
00460         }
00461 
00462         char dataline[MAXSTRING];
00463         sdstream.getline(dataline, MAXSTRING);          //discard 1st line
00464         CHECK
00465         sdstream.getline(dataline, MAXSTRING);          //get 2nd line
00466 
00467         float val;
00468         sdstream >> val;
00469         sdinfo.nsweeps = (int)val;
00470         sdnsweepsTextfield->setText(FXStringVal(sdinfo.nsweeps));
00471         sdstream.getline(dataline, MAXSTRING);
00472         CHECK
00473         sdstream >> val;
00474         sdinfo.ncols = (int)val;
00475         sdncolsTextfield->setText(FXStringVal(sdinfo.ncols));
00476         sdstream.getline(dataline, MAXSTRING);
00477         CHECK
00478         sdstream >> val;
00479         sdinfo.nsd = (int)val;
00480         sdnsdTextfield->setText(FXStringVal(sdinfo.nsd));
00481         sdstream.getline(dataline, MAXSTRING);
00482         CHECK
00483         sdstream >> val;
00484         sdinfo.npoints = (int)val;
00485         sdnptsTextfield->setText(FXStringVal((unsigned int)sdinfo.npoints));
00486         sdstream.getline(dataline, MAXSTRING);
00487         CHECK
00488         sdstream >> sdinfo.version;
00489         if (sdinfo.version != 2.0)
00490         {
00491                 e = "Input SD version wrong";
00492                 sdstream.close();
00493                 return(-1);
00494         }
00495 //      sdstream.close();
00496 
00497         // Clear SD iconlist
00498         sdIconlist->clearItems(false);
00499         for (i = sdIconlist->getNumHeaders(); i > 0; --i)
00500                 sdIconlist->removeHeader(i-1);
00501 
00502         // Load SD data
00503 //      sdstream.open(sdfile.text(), ifstream::in);
00504 //      if (!sdstream.is_open())
00505 //      {
00506 //              FXMessageBox::error(this, FX::MBOX_OK, "Error!", "No such input file");
00507 //              return(1);
00508 //      }
00509         sdstream.seekg(0, std::ios::beg);
00510         sdstream.getline(dataline, MAXSTRING);
00511         sdstream.getline(dataline, MAXSTRING);
00512         FXString sdheaders = dataline;
00513         FXString ilheaders = "Swp N\nSwp len\nX col";   //icon list headers
00514         sdheaders = sdheaders.after('\t', 6);
00515         FXString temp;
00516         daysdListbox->clearItems();     //clear ysd list
00517         daysdListbox->appendItem("<Swp N>");
00518         daysdListbox->appendItem("<Manual>");
00519         for (i = 0; i < sdinfo.nsd; ++i)
00520         {
00521                 ilheaders += FXString("\n");
00522                 temp = (sdheaders.before('\t', 1)).trimEnd();
00523                 if (temp.length() != 0)         //if item not blank
00524                 {
00525                         ilheaders += temp;
00526                         daysdListbox->appendItem(temp);
00527                 }
00528                 else
00529                 {
00530                         ilheaders += FXStringVal(i);
00531                         daysdListbox->appendItem(FXStringVal(i));
00532                 }
00533 //              cerr << '>' << (sdheaders.before('\t', 1)).text() << "<\n";
00534                 sdheaders = sdheaders.after('\t', 1);
00535         }
00536         sdIconlist->setHeaders(ilheaders, 3+sdinfo.nsd);
00537         sdIconlist->setHeaderSize(0, 30);
00538         sdIconlist->setHeaderSize(1, 50);
00539         sdIconlist->setHeaderSize(2, 20);
00540         for (i = 0; i < sdinfo.nsd; ++i)
00541         {
00542                 sdIconlist->setHeaderSize(3+i, 60);
00543         }
00544 //      cerr << '\"' << ilheaders.text() << '\"';
00545 
00546         ilheaders = "\0";
00547         double d;
00548         statusProgressbar->setTotal(sdinfo.nsweeps);
00549         int maxlines = 0;       //so we know how long to make the progress bar
00550         sd = new statusdata[sdinfo.nsweeps];
00551         for (i = 0; i < sdinfo.nsweeps; ++i)
00552                 sd[i].npoints = 0;
00553         int previous = -1, current = -1;
00554         i = 0;
00555         unsigned int p = 0;
00556         sdstream.getline(dataline, MAXSTRING);
00557         do
00558         {
00559                 sdheaders = dataline;
00560                 if (sdlabviewRadiobutton->getCheck() == true)
00561                 {
00562                         sdheaders = sdheaders.after('\t', 1);
00563                         current = (int)FXDoubleVal((sdheaders.before('\t', 1)).trimEnd());      //sweep number
00564                         sdheaders = sdheaders.after('\t', 2);
00565                         d = FXDoubleVal((sdheaders.before('\t', 1)).trimEnd()); //npoints in sweep
00566                         p = (unsigned int)d;
00567                         sdheaders = sdheaders.after('\t', 1);
00568                 }
00569                 else
00570                 {
00571                         sdheaders = sdheaders.after('\t', 1);
00572                         d = FXDoubleVal((sdheaders.before('\t', 1)).trimEnd()); //npoints in sweep
00573                         p = (unsigned int)d;
00574                         sdheaders = sdheaders.after('\t', 2);
00575                         current = (int)FXDoubleVal((sdheaders.before('\t', 1)).trimEnd());      //sweep number
00576                         sdheaders = sdheaders.after('\t', 1);
00577                 }
00578                 if (current > 0)
00579                 {
00580                         if (current != previous)
00581                         {
00582                                 sd[i].xcol = (int)FXDoubleVal((sdheaders.before('\t', 1)).trimEnd());   //x column
00583                                 sdheaders = sdheaders.after('\t', 1);
00584                                 sd[i].item = new double[sdinfo.nsd];
00585                                 for (j = 0; j < sdinfo.nsd; ++j)
00586                                 {
00587                                         sdheaders = sdheaders.after('\t', 1);
00588                                         d = FXDoubleVal((sdheaders.before('\t', 1)).trimEnd());
00589                                         sd[i].item[j] = d;
00590                                 }
00591                                 sd[i].npoints = p;
00592                                 statusProgressbar->setProgress(i+1);
00593                                 previous = current;
00594                                 ++i;
00595                         }
00596                 }
00597                 sdstream.getline(dataline, MAXSTRING);
00598         }
00599         while ((current != 0) && (strlen(dataline) != 0));
00600         for (i = 0; i < sdinfo.nsweeps; ++i)
00601         {
00602                 ilheaders += FXStringVal(i)+FXString("\t");
00603                 ilheaders += FXStringVal((unsigned int)sd[i].npoints)+FXString("\t");
00604                 if (sd[i].npoints > maxlines) maxlines = sd[i].npoints;
00605                 ilheaders += FXStringVal(sd[i].xcol);
00606                 for (j = 0; j < sdinfo.nsd; ++j)
00607                 {
00608                         ilheaders += FXString("\t");
00609                         ilheaders += FXStringVal(sd[i].item[j]);        //SD
00610                 }
00611                 ilheaders += FXString("\n");
00612         }
00613         sdIconlist->fillItems(ilheaders, NULL, NULL, NULL, true);
00614 
00615         for (i = 0; i < sdinfo.nsweeps; ++i)
00616                 sdIconlist->selectItem(i, true);
00617 */
00618 ///////////////////
00619 // Load real data
00620 ///////////////////
00621 
00622         std::ifstream datafile;
00623         datafile.open(pathTextfield->getText().text(), std::ifstream::in);
00624         if (!datafile.is_open())
00625         {
00626                 e = "No such input file";
00627                 return(-1);
00628         }
00629 
00630         rawdata = new double*[sdinfo.nsweeps*sdinfo.ncols];
00631         for (i = 0; i < sdinfo.nsweeps*sdinfo.ncols; ++i)
00632         {
00633                 rawdata[i] = new double[sd[i/sdinfo.ncols].npoints];
00634                 if (rawdata[i] == NULL)
00635                 {
00636                         e = "Cannot create an image this big";
00637                         datafile.close();
00638                         return(-1);
00639                 }
00640         }
00641 
00642 
00643         datafile >> ch;
00644         linesbefore = 0;
00645         while (!((ch >= '0') && (ch <= '9')) && (ch != '-') && (!datafile.eof()))       //while not a number
00646         {
00647                 datafile.getline(dataline, MAXSTRING);          //discard line
00648                 ++linesbefore;
00649                 CHECK2
00650                 datafile >> ch;
00651         }
00652         if (datafile.eof())
00653         {
00654                 e = "The format of the data file is not recognised (could not find the data)";
00655                 return(-1);
00656         }
00657 
00658         datafile.seekg(0, std::ios::beg);
00659         for (i = 0; i < linesbefore; ++i)
00660                 datafile.getline(dataline, MAXSTRING);
00661 //      datafile.getline(dataline, MAXSTRING, '\n');    //Skip column labels
00662 //      datafile.getline(dataline, MAXSTRING, '\n');    //Extract column titles
00663         if (strlen(dataline) >= MAXSTRING-1)
00664         {
00665                 e = "Input line too long";
00666                 datafile.close();
00667                 return(-1);
00668         }
00669         daxcolListbox->clearItems();
00670         dazcolListbox->clearItems();
00671         dascatterListbox->clearItems();
00672         dascatterListbox->appendItem("<ysd>");
00673         sdheaders = dataline;
00674         for (i = 0; i < sdinfo.ncols; ++i)
00675         {
00676                 temp = ((sdheaders.after(sdinfo.separator, i)).before(sdinfo.separator, 1)).trimEnd();          //sdinfo.separator replaced '\t'
00677                 if (temp.length() == 0) temp = FXStringVal(i);
00678                 daxcolListbox->appendItem(temp);
00679                 dazcolListbox->appendItem(temp);
00680                 dascatterListbox->appendItem(temp);
00681         }
00682         daxcolListbox->setCurrentItem(0);
00683         dazcolListbox->setCurrentItem(1);
00684         dascatterListbox->setCurrentItem(1);
00685 
00686 
00687         //Get numbers
00688         statusProgressbar->setTotal(maxlines);
00689         char *ibuffer;
00690         unsigned int rowcounter = 0;
00691         FXApp *a = getApp();
00692         while (!datafile.eof())
00693         {
00694                 datafile.getline(dataline, MAXSTRING, '\n');
00695                 if (strlen(dataline) >= MAXSTRING-1)
00696                 {
00697                         e = "Input line too long";
00698                         datafile.close();
00699                         return(-1);
00700                 }
00701                 ibuffer = dataline;
00702                 for (c = 0; c < sdinfo.nsweeps*sdinfo.ncols; ++c)
00703                 {
00704                         if (ibuffer[0] != sdinfo.separator)
00705                                 if (rowcounter < sd[c/sdinfo.ncols].npoints)
00706                                         rawdata[c][rowcounter] = atof(ibuffer); //Get number
00707                         if (ibuffer == NULL) break;
00708                         ibuffer = strchr(ibuffer, sdinfo.separator);
00709                         if (ibuffer == NULL) break;
00710                         ibuffer = &ibuffer[1];
00711                 }
00712                 ++rowcounter;
00713                 statusProgressbar->setProgress(rowcounter);
00714                 a->forceRefresh();
00715                 a->repaint();
00716         }
00717 
00718         datafile.close();
00719 
00720         cmdDAXChange(NULL, 0, NULL);
00721         cmdDARangeChange(NULL, 0, NULL);
00722         statusProgressbar->setProgress(0);
00723 //cerr << rawdata[0][0] << ',' << rawdata[0][1] << ',' << rawdata[0][2] << ',' << rawdata[1][1] << ',' << rawdata[2][0] << ',';
00724 
00725 
00726         return(1);
00727 }
00728 
00729 
00730 ///Loads Acorn CryoMeas binary file
00731 /**
00732  * @author Code written by Jonathan Prance, jp376@cam.ac.uk
00733  * @param[out] e Error string.
00734  * @return Success (0) or failure (-1).
00735  */
00736 long GreyLabWindow::dataBinarySDLoad(FXString &e)
00737 {
00738         int i;
00739         //Delete old data
00740 
00741         if (sd != NULL)
00742         {
00743                 for (int i = 0; i < sdinfo.nsweeps; ++i)
00744                         if (sd[i].item != NULL)
00745                         {
00746                                 delete[] sd[i].item;
00747                                 sd[i].item = NULL;
00748                         }
00749                 delete[] sd;
00750                 sd = NULL;
00751         }
00752         if (rawdata != NULL)
00753         {
00754                 for (int i = 0; i < sdinfo.nsweeps*sdinfo.ncols; ++i)
00755                         if (rawdata[i] != NULL)
00756                         {
00757                                 delete[] rawdata[i];
00758                                 rawdata[i] = NULL;
00759                         }
00760                 delete[] rawdata;
00761                 rawdata = NULL;
00762         }
00763 
00764         //
00765         // Load the data file from Acorn binary CryoMeas format into memory
00766         //
00767 
00768         bool noerror;
00769         char *hdr;
00770         FXString filename = pathTextfield->getText();
00771         FILE *se = stderr;
00772         freopen("acorn.txt", "w", stderr);
00773         LAfile* infile = new LAfile((char*)filename.text(), noerror, hdr);
00774         fclose(stderr);
00775         stderr = se;
00776         if (noerror == false)
00777         {
00778                 e = "There was an error whilst loading the file. Check 'acorn.txt' for details.";
00779                 return(-1);
00780         }
00781         hdText->setText(FXString(hdr));
00782         delete[] hdr;
00783 
00784         //
00785         // Fill in status data names and values
00786         //
00787 
00788         sdinfo.nsweeps = (int)infile->FileInfo.nsweeps;
00789         sdnsweepsTextfield->setText(FXStringVal(sdinfo.nsweeps));
00790         sdinfo.ncols = (int)infile->FileInfo.ncol;
00791         sdncolsTextfield->setText(FXStringVal(sdinfo.ncols));
00792         sdinfo.nsd = (int)infile->FileInfo.nsd;
00793         sdnsdTextfield->setText(FXStringVal(sdinfo.nsd));
00794         sdinfo.npoints = (int)infile->FileInfo.points;
00795         sdnptsTextfield->setText(FXStringVal((unsigned int)sdinfo.npoints));
00796 
00797         // Clear SD iconlist    
00798         sdIconlist->clearItems(false);
00799         for (i = sdIconlist->getNumHeaders(); i > 0; --i) {
00800                 sdIconlist->removeHeader(i-1);
00801         }
00802 
00803         // Clear ysd list
00804         daysdListbox->clearItems();     
00805         daysdListbox->appendItem("<Swp N>");
00806         daysdListbox->appendItem("<Manual>");
00807 
00808         // Populate ysd list and iconlist headers with the status data names
00809         FXString ilheaders;// = "Swp N\nSwp len\nX col";        //icon list headers
00810         sdIconlist->appendHeader("Swp N");
00811         sdIconlist->appendHeader("Swp len");
00812         sdIconlist->appendHeader("X col");
00813 
00814         for(i = 0; i < sdinfo.nsd; i++) {
00815                 FXString sd(infile->FileInfo.sd[i].name);
00816                 unsigned int ch = infile->FileInfo.sd[i].channel;
00817 
00818                 if(sd.length() != 0) {
00819                         sdIconlist->appendHeader(sd+"\n"+FXStringVal(ch));
00820                         if (ch == 298)
00821                                 sdinfo.ch298 = i;
00822                         else if (ch == 299)
00823                                 sdinfo.ch299 = i;
00824                         daysdListbox->appendItem(sd+":"+FXStringVal(ch));
00825                 } else {
00826                         ilheaders += FXStringVal(i);
00827                         daysdListbox->appendItem(FXStringVal(i));
00828                 }
00829         }
00830         if ((sdinfo.ch298 != -1) || (sdinfo.ch299 != -1))
00831                 settranslatechCheckbutton->enable();
00832 
00833         sdIconlist->setHeaderSize(0, 30);
00834         sdIconlist->setHeaderSize(1, 50);
00835         sdIconlist->setHeaderSize(2, 20);
00836 
00837         for (i = 0; i < sdinfo.nsd; ++i) {
00838                 sdIconlist->setHeaderSize(3+i, 60);
00839         }
00840 
00841         // Populate the status data icon list with values for each sweep
00842         statusProgressbar->setTotal(sdinfo.nsweeps);
00843         sd = new statusdata[sdinfo.nsweeps];
00844 
00845         ilheaders = "\0";
00846         
00847         for(i = 0; i < sdinfo.nsweeps; i++) {
00848                 // Sweep number
00849                 ilheaders += FXStringVal(i)+FXString("\t");
00850                 
00851                 // Points per sweep
00852                 sd[i].npoints = infile->FileInfo.npoints[i];
00853                 ilheaders += FXStringVal((unsigned int)sd[i].npoints) + FXString("\t");
00854                 
00855                 // x column
00856                 sd[i].xcol = infile->FileInfo.xcols[i];
00857                 if(sd[i].xcol == 0) { sd[i].xcol = 1; }
00858                 ilheaders += FXStringVal(sd[i].xcol);
00859                 
00860                 sd[i].item = new double[sdinfo.nsd];
00861                 
00862                 for(int j = 0; j < sdinfo.nsd; j++) {
00863                         sd[i].item[j] = (infile->FileInfo.sdvalues[i])[j];
00864                         ilheaders += FXString("\t");
00865                         ilheaders += FXStringVal(sd[i].item[j]);        //SD
00866                 }
00867                 
00868                 statusProgressbar->setProgress(i+1);
00869                 ilheaders += "\n";
00870         }
00871         
00872         sdIconlist->fillItems(ilheaders, NULL, NULL, NULL, true);
00873         for (i = 0; i < sdinfo.nsweeps; ++i) { sdIconlist->selectItem(i, true); }
00874         
00875         //
00876         // Load the column names
00877         //
00878         
00879         daxcolListbox->clearItems();
00880         dazcolListbox->clearItems();
00881         dascatterListbox->clearItems();
00882         dascatterListbox->appendItem("<ysd>");
00883         
00884         for (i = 0; i < sdinfo.ncols; i++) {
00885                 FXString temp(infile->FileInfo.col[i].name);
00886                 daxcolListbox->appendItem(temp);
00887                 dazcolListbox->appendItem(temp);
00888                 dascatterListbox->appendItem(temp);
00889         }
00890         
00891         daxcolListbox->setCurrentItem(0);
00892         dazcolListbox->setCurrentItem(1);
00893         dascatterListbox->setCurrentItem(1);
00894         
00895         //
00896         // Load the data
00897         //
00898         
00899         statusProgressbar->setTotal(sdinfo.nsweeps);
00900         rawdata = new double*[sdinfo.nsweeps*sdinfo.ncols];
00901         
00902         for (i = 0; i < sdinfo.nsweeps*sdinfo.ncols; i++) {
00903                 rawdata[i] = new double[sd[i/sdinfo.ncols].npoints];
00904                 if (rawdata[i] == NULL) {
00905                         e = "Cannot create an image this big";
00906                         return(-1);
00907                 }
00908         }
00909         
00910         int irow, orow;
00911         
00912         for(int sw = 0; sw < sdinfo.nsweeps; sw++) {
00913                 orow = 0;
00914                 int start_row = infile->FileInfo.swpptr[sw] + infile->FileInfo.sdrow;
00915                 
00916                 for(irow = 0; irow < sd[sw].npoints; irow++) {
00917                         
00918                         if(infile->FileInfo.col[0].colptr[start_row+irow] >= 1.0e21) {
00919                                 // Take account of interrupted sweeps by columns that start with a value >= 1.0e21
00920                                 // by skipping ahead one row in the input file
00921                                 start_row++;
00922                         }
00923                         
00924                         for(int c = 0; c < sdinfo.ncols; c++) {
00925                                 int i = (sw * sdinfo.ncols) + c;
00926                                 rawdata[i][orow] = infile->FileInfo.col[c].colptr[start_row+irow];
00927                         }
00928                         
00929                         orow++;
00930                 }
00931                 
00932                 statusProgressbar->setProgress(sw);
00933         }
00934         
00935         delete infile;
00936         
00937         cmdDAXChange(NULL, 0, NULL);
00938         cmdDARangeChange(NULL, 0, NULL);
00939         statusProgressbar->setProgress(0);
00940         
00941         return(1);
00942 }
00943 
00944 
00945 ///Loads data based only on the data file
00946 /**
00947  * @param[out] e Error string.
00948  * @return Success (0) or failure (-1).
00949  */
00950 long GreyLabWindow::dataTextLoad(FXString &e)
00951 {
00952         int i, b, c, f, g;
00953 
00954         if (sd != NULL)
00955         {
00956                 for (i = 0; i < sdinfo.nsweeps; ++i)
00957                         if (sd[i].item != NULL)
00958                         {
00959                                 delete[] sd[i].item;
00960                                 sd[i].item = NULL;
00961                         }
00962                 delete[] sd;
00963                 sd = NULL;
00964         }
00965         if (rawdata != NULL)
00966         {
00967                 for (i = 0; i < sdinfo.nsweeps*sdinfo.ncols; ++i)
00968                         if (rawdata[i] != NULL)
00969                         {
00970                                 delete[] rawdata[i];
00971                                 rawdata[i] = NULL;
00972                         }
00973                 delete[] rawdata;
00974                 rawdata = NULL;
00975         }
00976 
00977 ///////////////////
00978 // Approximate SD
00979 ///////////////////
00980         std::ifstream datafile;
00981         FXString sdfile = pathTextfield->getText();
00982         
00983         datafile.open(sdfile.text(), std::ifstream::in);
00984         if (!datafile.is_open())
00985         {
00986                 e = "No such input file";
00987                 return(-1);
00988         }
00989         
00990         char dataline[MAXSTRING];
00991         if (sdsmartRadiobutton->getCheck() == true)     //smart method
00992                 for (i = 0; i < FXIntVal(smarttitlesTextfield->getText()); ++i)
00993                         datafile.getline(dataline, MAXSTRING);          //discard n lines
00994         else
00995                 for (i = 0; i < FXIntVal(dumbdataTextfield->getText()); ++i)
00996                         datafile.getline(dataline, MAXSTRING);          //discard n lines
00997 
00998         CHECK2
00999         datafile.getline(dataline, MAXSTRING);          //get next line
01000 //cerr << dataline << '\n';
01001         FXString sdline = dataline;
01002         sdinfo.nsweeps = sdline.contains(sdinfo.separator);
01003 
01004         if (sdsmartRadiobutton->getCheck() == true)     //smart method only
01005         {
01006                 FXString heading = sdline.before(sdinfo.separator).trimEnd();
01007 //cerr << heading.text() << '\n';
01008 //cerr << sdline.find(heading, 1) << '\n';
01009                 sdline = sdline.left(sdline.find(heading, 1));
01010 //cerr << sdline.text() << '\n';
01011                 if (sdline.length() > 0)
01012                 {
01013                         sdinfo.ncols = sdline.contains(sdinfo.separator);
01014                         sdinfo.nsweeps = (sdinfo.nsweeps+1)/sdinfo.ncols;
01015                 }
01016                 else    //only one column
01017                 {
01018                         sdinfo.ncols = sdinfo.nsweeps+1;
01019                         sdinfo.nsweeps = 1;
01020                 }
01021         }
01022         else
01023         {
01024                 sdinfo.ncols = FXIntVal(dumbcolsperTextfield->getText());
01025                 sdinfo.nsweeps = (sdinfo.nsweeps+1)/sdinfo.ncols;
01026         }
01027 //      --sdinfo.nsweeps;
01028         dassweepTextfield->setText("0");
01029         daesweepTextfield->setText(FXStringVal(sdinfo.nsweeps-1));
01030         sdnsweepsTextfield->setText(FXStringVal(