DataAnalysis.cpp

Go to the documentation of this file.
00001 //DataAnalysis.cpp
00002 
00003 /*************************************************************/
00004 //
00005 // GreyLabWindow
00006 //
00007 // Data analysis routines for the GreyLabWindow class
00008 //
00009 //-------------------------------------------------------------
00010 //
00011 // v 1.20 - 2008/03/10 - Matlab export
00012 // v 1.19 - 2007/12/13 - Rounding of z-axis, fixed
00013 // v 1.18 - 2007/12/13 - Rounding of z-axis
00014 // v 1.17 - 2007/11/26 - Fixed auto binning when using functions
00015 // v 1.16 - 2007/06/15 - Updates to cursor labels
00016 // v 1.15 - 2007/06/12 - 2.17.2 improvements
00017 // v 1.14 - 2007/06/06 - Fixed lack of image binding when writing output
00018 // v 1.13 - 2007/05/30 - Zoom back feature
00019 // v 1.12 - 2007/02/17 - Changes for linescan range plotting
00020 // v 1.11 - 2007/02/09 - X target range and better autoranging
00021 // v 1.10 - 2007/02/01 - ysd scatter option
00022 // v 1.9 - 2007/01/06 - Changes for 2.11.0
00023 // v 1.8 - 2006/11/23 - Hires image save etc
00024 // v 1.7 - 2006/11/19 - Autorange Z and equal range Z
00025 // v 1.6 - 2006/11/19 - Fixed zooming
00026 // v 1.5 - 2006/11/18 - Lots of changes for 2.10.0
00027 // v 1.5 - 2006/11/13 - Export all columns options
00028 // v 1.4 - 2006/11/10 - Fixed mouse clicks
00029 // v 1.3 - 2006/09/07 - Acorn export of data
00030 // v 1.2 - 2006/09/06 - Tab on export was the wrong side of the data
00031 // v 1.1 - 2006/08/29 - Fixed a bug crashing the processing when 1st sweep > 0 in a block of sweeps
00032 // v 1.0 - 2006/08/28 - Initial release
00033 //
00034 // See LICENSE.txt for distribution and usage restrictions
00035 // Copyright (c) 2005-2007 Simon Chorley
00036 // www.mylaboratory.co.uk - greylab@mylaboratory.co.uk
00037 //
00038 /*************************************************************/
00039 
00040 
00041 ///Data analysis functions
00042 /**
00043  * Provides implementation of GreyLabWindow functions to process the data.
00044  * @file DataAnalysis.cpp
00045  * @version 1.20 - 2008/03/10
00046  */
00047 
00048 
00049 #include "GreyLab.h"
00050 
00051 
00052 #include <fstream>
00053 
00054 
00055 FXString strip(FXString s)
00056 {
00057         unsigned int i;
00058         for (i = 0; i < s.length(); ++i)
00059                 if (!(((s[i] >= 'a') && (s[i] <= 'z')) || ((s[i] >= 'A') && (s[i] <= 'Z')) || ((s[i] >= '0') && (s[i] <= '9')) || (s[i] == '_')))
00060                         s[i] = '_';
00061         return(s);
00062 }
00063 
00064 
00065 ///Rounds a number to the nearest 1, 2 or 5
00066 /**
00067  * @param step Number to quantise.
00068  * @return Rounded number.
00069  */
00070 double GreyLabWindow::quantise(double step)
00071 {
00072         int i;
00073         double test = fabs(step)*0.1;
00074         for (i = 0; i < 500; ++i)
00075         {
00076                 test *= 10.0;
00077                 if ((test > 0.75) && (test <= 1.5))     //1
00078                         return(pow(10.0, -i));
00079                 if ((test > 1.5) && (test <= 3.5))      //2
00080                         return(2.0*pow(10.0, -i));
00081                 if ((test > 3.5) && (test <= 7.5))      //5
00082                         return(5.0*pow(10, -i));
00083         }
00084         test = fabs(step)*10.0;
00085         for (i = 0; i < 500; ++i)
00086         {
00087                 test *= 0.1;
00088                 if ((test > 0.75) && (test <= 1.5))     //1
00089                         return(pow(10.0, i));
00090                 if ((test > 1.5) && (test <= 3.5))      //2
00091                         return(2.0*pow(10.0, i));
00092                 if ((test > 3.5) && (test <= 7.5))      //5
00093                         return(5.0*pow(10, i));
00094         }
00095         return(1.0);
00096 }
00097 
00098 
00099 double GreyLabWindow::quantiseupZ(double step)
00100 {
00101         int i, j;
00102         for (j = 0; j < 10; ++j)
00103                 if ((fabs(step) > (float)j) && (fabs(step) <= (float)(j+1)))
00104                         return((float)(j+1));
00105 /*      double test = fabs(step)*0.1;
00106         for (i = 0; i < 500; ++i)
00107         {
00108                 test *= 10.0;
00109                 for (j = 1; j < 10; ++j)
00110                         if ((test > (float)j) && (test <= (float)(j+1)))
00111                                 return((float)(j+1)*pow(10.0, -i));
00112         }
00113         test = fabs(step)*10.0;
00114         for (i = 0; i < 500; ++i)
00115         {
00116                 test *= 0.1;
00117                 for (j = 1; j < 10; ++j)
00118                         if ((test > (float)j) && (test <= (float)(j+1)))
00119                                 return((float)(j+1)*pow(10.0, -i));
00120         }*/
00121         return(1.0);
00122 }
00123 
00124 
00125 double GreyLabWindow::quantisedownZ(double step)
00126 {
00127         int i, j;
00128         for (j = 0; j < 10; ++j)
00129                 if ((fabs(step) > (float)j) && (fabs(step) <= (float)(j+1)))
00130                         return((float)(j));
00131 /*      double test = fabs(step)*0.1;
00132         for (i = 0; i < 500; ++i)
00133         {
00134                 test *= 10.0;
00135                 for (j = 1; j < 10; ++j)
00136                         if ((test > (float)j) && (test <= (float)(j+1)))
00137                                 return((float)(j)*pow(10.0, -i));
00138         }
00139         test = fabs(step)*10.0;
00140         for (i = 0; i < 500; ++i)
00141         {
00142                 test *= 0.1;
00143                 for (j = 1; j < 10; ++j)
00144                         if ((test > (float)j) && (test <= (float)(j+1)))
00145                                 return((float)(j)*pow(10.0, -i));
00146         }*/
00147         return(1.0);
00148 }
00149 
00150 
00151 void GreyLabWindow::roundZ(double &zlo, double &zhi)
00152 {
00153         int i = 0;
00154         double range = zhi-zlo;
00155         if (range == 0.0)
00156                 return;
00157         double multiplier = 100/range;
00158         if (multiplier > 1.0)
00159         {
00160                 while (multiplier > 1.0)
00161                 {
00162                         multiplier *= 0.1;
00163                         ++i;
00164                 }
00165                 multiplier = pow(10, i);
00166 //std::cout << zlo << " -> ";
00167                 zlo *= multiplier;
00168                 if (zlo < 0.0)
00169                         zlo = (((int)zlo)+(zlo/fabs(zlo))*quantiseupZ((zlo-(int)zlo)))/multiplier;
00170                 else
00171                         zlo = (((int)zlo)+(zlo/fabs(zlo))*quantisedownZ((zlo-(int)zlo)))/multiplier;
00172 //std::cout << zlo << "\n";
00173 //std::cout << zhi << " -> ";
00174                 zhi *= multiplier;
00175                 if (zhi > 0.0)
00176                         zhi = (((int)zhi)+(zhi/fabs(zhi))*quantiseupZ((zhi-(int)zhi)))/multiplier;
00177                 else
00178                         zhi = (((int)zhi)+(zhi/fabs(zhi))*quantisedownZ((zhi-(int)zhi)))/multiplier;
00179 //std::cout << zhi << "\n";
00180         }
00181         else if (multiplier <= 1.0)
00182         {
00183                 while (multiplier < 1.0)
00184                 {
00185                         multiplier *= 10.0;
00186                         ++i;
00187                 }
00188                 multiplier = pow(10, 1-i);
00189 //std::cout << zlo << " -> ";
00190                 zlo *= multiplier;
00191                 if (zlo < 0.0)
00192                         zlo = (((int)zlo)+(zlo/fabs(zlo))*quantiseupZ((zlo-(int)zlo)))/multiplier;
00193                 else
00194                         zlo = (((int)zlo)+(zlo/fabs(zlo))*quantisedownZ((zlo-(int)zlo)))/multiplier;
00195 //std::cout << zlo << "\n";
00196 //std::cout << zhi << " -> ";
00197                 zhi *= multiplier;
00198                 if (zhi > 0.0)
00199                         zhi = (((int)zhi)+(zhi/fabs(zhi))*quantiseupZ((zhi-(int)zhi)))/multiplier;
00200                 else
00201                         zhi = (((int)zhi)+(zhi/fabs(zhi))*quantisedownZ((zhi-(int)zhi)))/multiplier;
00202 //std::cout << zhi << "\n";
00203         }
00204 }
00205 
00206 
00207 ///Processes the raw data into histogram data.
00208 /**
00209  * Processes the raw data into histogram data. All paramaters are unused.
00210  * @remarks Sets GreyLabWindow::pdata#validdata to true on success.
00211  */
00212 long GreyLabWindow::cmdDAProcess(FXObject*, FXSelector, void*)
00213 {
00214         if (rawdata == NULL)
00215                 return(1);
00216 
00217         if (gsDCwindow == NULL)
00218         {
00219                 gsDCwindow = new FXDCWindow((FXDrawable*)datawin->dataImageview);
00220                 gsDCwindow->end();
00221         }
00222         if (lsDCwindow == NULL)
00223         {
00224                 lsDCwindow = new FXDCWindow((FXDrawable*)linewin->lineImageview);
00225                 lsDCwindow->end();
00226         }
00227 
00228         lstracesIconlist->clearItems();
00229         lsinfo.newTrace = true;
00230 
00231         //Check functions
00232         if (onDAParseError(functions[0].InfixToRPN((char*)dafunctionText[0]->getText().text()), 0) == false) return(1);
00233         if (onDAParseError(functions[1].InfixToRPN((char*)dafunctionText[1]->getText().text()), 1) == false) return(1);
00234         if (onDAParseError(functions[2].InfixToRPN((char*)dafunctionText[2]->getText().text()), 2) == false) return(1);
00235 
00236         pdata.validdata = false;
00237 
00238         //Scatter?
00239         bool scatter = dascatterCheckbutton->getCheck();
00240         
00241         unsigned long i, j, k;
00242         //Clear any old data
00243         if (pdata.sweep != NULL) delete[] pdata.sweep;
00244         if (pdata.x != NULL) delete[] pdata.x;
00245         if (pdata.y != NULL) delete[] pdata.y;
00246         if (pdata.z != NULL)
00247         {
00248                 for (i = 0; i < pdata.ny; ++i)  //delete z data
00249                 {
00250                         if (pdata.z[i] != NULL) delete[] pdata.z[i];
00251                         pdata.z[i] = NULL;
00252                 }
00253                 delete[] pdata.z;               
00254         }
00255         if (pdata.scattery != NULL)
00256         {
00257                 for (i = 0; i < pdata.ny; ++i)  //delete z data
00258                 {
00259                         if (pdata.scattery[i] != NULL) delete[] pdata.scattery[i];
00260                         pdata.scattery[i] = NULL;
00261                 }
00262                 delete[] pdata.scattery;
00263                 pdata.scattery = NULL;
00264         }
00265         if (pdata.columns != NULL) delete[] pdata.columns;
00266         pdata.x = NULL;
00267         pdata.y = NULL;
00268         pdata.z = NULL;
00269         pdata.columns = NULL;
00270         
00271         //Finalise SD
00272         sdinfo.stride = FXIntVal(dastrideTextfield->getText());
00273         if (sdinfo.stride < 1) sdinfo.stride = 1;
00274         sdinfo.xcol = daxcolListbox->getCurrentItem();
00275         sdinfo.ycol = daysdListbox->getCurrentItem()-2; //-2: col N, -1: manual, 0.... SD
00276         sdinfo.zcol = dazcolListbox->getCurrentItem();
00277         sdinfo.yscattercol = dascatterListbox->getCurrentItem()-1;
00278         sdinfo.ssweep = FXIntVal(dassweepTextfield->getText());
00279         sdinfo.esweep = FXIntVal(daesweepTextfield->getText());
00280         if (sdinfo.ssweep < 0)
00281         {
00282                 sdinfo.ssweep = 0;
00283                 dassweepTextfield->setText("0");
00284         }
00285         if (sdinfo.esweep >= sdinfo.nsweeps)
00286         {
00287                 sdinfo.esweep = sdinfo.nsweeps-1;
00288                 daesweepTextfield->setText(FXStringVal(sdinfo.esweep));
00289         }
00290 
00291         if (dasweepselectCheckbutton->getCheck() == false)
00292         {
00293 //              sdinfo.nselected = (sdinfo.esweep-sdinfo.ssweep+1)/sdinfo.stride;               <-- This doesn't work properly when there are a non-stride multiple of sweeps that may still be valid (in terms of compatibility with the loop below) so replaced with a loop counter.
00294                 sdinfo.nselected = 0;
00295                 for (i = sdinfo.ssweep; i <= sdinfo.esweep; i += sdinfo.stride)
00296                         ++sdinfo.nselected;
00297                 pdata.sweep = new int[sdinfo.nselected];
00298                 for (i = sdinfo.ssweep; i <= sdinfo.esweep; i += sdinfo.stride)
00299                         pdata.sweep[(i-sdinfo.ssweep)/sdinfo.stride] = i;
00300                         
00301         }
00302         else
00303         {
00304                 sdinfo.nselected = 0;
00305                 for (i = sdinfo.ssweep; i <= sdinfo.esweep; i += sdinfo.stride)
00306                 {
00307                         if (sdIconlist->isItemSelected(i) == true) ++sdinfo.nselected;
00308                 }
00309                 pdata.sweep = new int[sdinfo.nselected];
00310                 int c = 0;
00311                 for (i = sdinfo.ssweep; i <= sdinfo.esweep; i += sdinfo.stride)
00312                 {
00313                         if (sdIconlist->isItemSelected(i) == true)
00314                         {
00315                                 pdata.sweep[c] = i;
00316                                 ++c;
00317                         }
00318                 }
00319         }
00320 
00321         double val;
00322         pdata.ny = sdinfo.nselected;
00323         double lo, hi;
00324         if (daxautoCheckbutton->getCheck() == true)
00325         {
00326                 lo = functions[0].Evaluate(FXDoubleVal(daxinminTextfield->getText()), FXDoubleVal(dayminTextfield->getText()), 0.0, 0, NULL);
00327                 hi = functions[0].Evaluate(FXDoubleVal(daxinmaxTextfield->getText()), FXDoubleVal(dayminTextfield->getText()), 0.0, 0, NULL);
00328                 daxtgtminTextfield->setText(FXStringVal(lo));
00329                 daxtgtmaxTextfield->setText(FXStringVal(hi));
00330         }
00331         else
00332         {
00333                 lo = FXDoubleVal(daxtgtminTextfield->getText());
00334                 hi = FXDoubleVal(daxtgtmaxTextfield->getText());
00335         }
00336         if (hi < lo)    //Swap?
00337         {
00338                 val = lo;
00339                 lo = hi;
00340                 hi = val;
00341         }
00342         if ((setautobinCheckbutton->getCheck() == true) && (setautoxscaleCheckbutton->getCheck() == true))      //added to redo bins when using functions - SJC 2007/11/26
00343                 daxtgtresTextfield->setText(FXStringVal((hi-lo)/((float)sd[sdinfo.ssweep].npoints/FXFloatVal(setbinsizeTextfield->getText()))));
00344         double delta = FXDoubleVal(daxtgtresTextfield->getText())/2.0;
00345         pdata.nx = 1+abs((int)((hi-lo)/(2.0*delta)));
00346 
00347 //Allocate arrays
00348         pdata.x = new double[pdata.nx];
00349         pdata.y = new double[pdata.ny];
00350         pdata.z = new point*[pdata.ny];
00351         if (scatter == true)
00352                 pdata.scattery = new double*[pdata.ny];
00353         pdata.columns = new double[pdata.nx*pdata.ny*sdinfo.ncols];
00354 
00355 //Generate x data
00356         for (i = 0; i < pdata.nx; ++i)
00357         {
00358                 pdata.x[i] = lo+((float)i)*(2.0*delta);
00359 //              std::cerr << pdata.x[i] << ',';
00360         }
00361         
00362 //      cerr << "ysd" << sdinfo.ycol << '\n';
00363         if (sdinfo.ycol == -2)                          //generate y data
00364         {
00365                 for (i = 0; i < pdata.ny; ++i)
00366                 {
00367                         pdata.y[i] = pdata.sweep[i];
00368                 }
00369         }
00370         else if (sdinfo.ycol == -1)
00371         {
00372                 double s = FXDoubleVal(dayminTextfield->getText());
00373                 double dy = (FXDoubleVal(daymaxTextfield->getText())-s)/((double)pdata.ny);
00374                 for (i = 0; i < pdata.ny; ++i)
00375                 {
00376                         pdata.y[i] = s+((double)i)*dy;
00377                 }
00378         }
00379         else
00380                 for (i = 0; i < pdata.ny; ++i)
00381                 {
00382                         pdata.y[i] = sd[pdata.sweep[i]].item[sdinfo.ycol];
00383 //                      pdata.y[i] = sd[i*sdinfo.stride+sdinfo.ssweep].item[sdinfo.ycol];
00384 //                      cerr << "sd" << sd[i*sdinfo.stride+sdinfo.ssweep].item[sdinfo.ycol] << 'y' << pdata.y[i] << '\n';
00385                 }
00386 
00387         unsigned long bin;
00388         unsigned long pt;
00389         double *row = new double[sdinfo.ncols];
00390         FXApp *a = getApp();
00391 
00392         statusProgressbar->setTotal(pdata.ny);
00393         for (i = 0; i < pdata.ny; ++i)  //transform and bin z data
00394         {
00395                 double *tempyscatter;
00396                 pdata.z[i] = new point[pdata.nx];       //allocate
00397                 for (j = 0; j < pdata.nx; ++j)                          //zero data
00398                 {
00399                         pdata.z[i][j].data = 0.0;
00400                         pdata.z[i][j].n = 0;
00401                 }
00402                 if (scatter == true)
00403                 {
00404                         tempyscatter = new double[sd[pdata.sweep[i]].npoints];
00405                         pdata.scattery[i] = new double[pdata.nx];       //allocate
00406                         for (j = 0; j < pdata.nx; ++j)                          //zero data
00407                                 pdata.scattery[i][j] = 0.0;
00408                         if (sdinfo.yscattercol == -1)
00409                         {
00410                                 for (j = 0; j < sd[pdata.sweep[i]].npoints; ++j)
00411                                         tempyscatter[j] = pdata.y[i];   //generate from a ysd
00412                         }
00413                         else
00414                         {
00415                                 for (j = 0; j < sd[pdata.sweep[i]].npoints; ++j)
00416                                         tempyscatter[j] = rawdata[sdinfo.yscattercol+sdinfo.ncols*pdata.sweep[i]][j];   //from a real column
00417                         }
00418                 }
00419                 for (j = 0; j < pdata.nx; ++j)          //zero array that stores other columns
00420                         for (k = 0; k < sdinfo.ncols; ++k)
00421                                 pdata.columns[i*pdata.nx*sdinfo.ncols+j*sdinfo.ncols+k] = 0.0;
00422                 for (j = 0; j < sd[pdata.sweep[i]].npoints; ++j)        //for each point in sweep
00423                 {
00424                         pt = sdinfo.ncols*pdata.sweep[i];       //current column
00425 //changed in 2.12.0 upgrade
00426 /*                      val = rawdata[sdinfo.xcol+pt][j];                                               //x value
00427                         bin = (unsigned long)(0.5+(val-lo)/(2.0*delta));        //calculate bin
00428                         if ((bin >= 0) && (bin < pdata.nx))
00429                         {
00430                                 for (k = 0; k < sdinfo.ncols; ++k)                              //collect data from row for evaluation
00431                                 {
00432                                         row[k] = rawdata[k+pt][j];
00433                                 }
00434                                 //Evaluate z point and store
00435                                 pdata.z[i][bin].data += functions[2].Evaluate(val, pdata.y[i], rawdata[sdinfo.zcol+pt][j], sdinfo.ncols, row);
00436                                 if (scatter == true)
00437                                         pdata.scattery[i][bin] += functions[1].Evaluate(val, rawdata[sdinfo.yscattercol+pt][j], rawdata[sdinfo.zcol+pt][j], sdinfo.ncols, row);
00438                                 for (k = 0; k < sdinfo.ncols; ++k)
00439                                         pdata.columns[i*pdata.nx*sdinfo.ncols+bin*sdinfo.ncols+k] += rawdata[k+pt][j];
00440                                 ++pdata.z[i][bin].n;
00441                         }*/
00442                         for (k = 0; k < sdinfo.ncols; ++k)                              //collect data from row for evaluation
00443                         {
00444                                 row[k] = rawdata[k+pt][j];
00445                         }
00446                         //calculate transformed x of point
00447                         if (scatter == false)
00448                                 val = functions[0].Evaluate(rawdata[sdinfo.xcol+pt][j], pdata.y[i], rawdata[sdinfo.zcol+pt][j], sdinfo.ncols, row);
00449                         else
00450                                 val = functions[0].Evaluate(rawdata[sdinfo.xcol+pt][j], tempyscatter[j], rawdata[sdinfo.zcol+pt][j], sdinfo.ncols, row);
00451                         if (j == 0)                     //if we are not scattering then just do it once
00452                         {
00453                                 pdata.y[i] = functions[1].Evaluate(val, pdata.y[i], rawdata[sdinfo.zcol+pt][j], sdinfo.ncols, row);
00454                         }
00455                         bin = (unsigned long)(0.5+(val-lo)/(2.0*delta));        //calculate bin
00456                         if ((bin >= 0) && (bin < pdata.nx))
00457                         {
00458                                 if (scatter == true)
00459                                 {
00460                                         //transform y
00461                                         tempyscatter[j] = functions[1].Evaluate(val, tempyscatter[j], rawdata[sdinfo.zcol+pt][j], sdinfo.ncols, row);
00462                                         pdata.scattery[i][bin] += tempyscatter[j];
00463                                         //Evaluate z point and store
00464                                         pdata.z[i][bin].data += functions[2].Evaluate(val, tempyscatter[j], rawdata[sdinfo.zcol+pt][j], sdinfo.ncols, row);
00465                                 }
00466                                 else
00467                                 {
00468                                         //Evaluate z point and store
00469                                         pdata.z[i][bin].data += functions[2].Evaluate(val, pdata.y[i], rawdata[sdinfo.zcol+pt][j], sdinfo.ncols, row);
00470                                 }
00471                                 for (k = 0; k < sdinfo.ncols; ++k)
00472                                         pdata.columns[i*pdata.nx*sdinfo.ncols+bin*sdinfo.ncols+k] += rawdata[k+pt][j];
00473                                 ++pdata.z[i][bin].n;
00474                         }
00475                 }
00476                 for (j = 0; j < pdata.nx; ++j)                          //average bins
00477                 {
00478                         pdata.z[i][j].data /= pdata.z[i][j].n;
00479                         for (k = 0; k < sdinfo.ncols; ++k)      //average array that stores other columns
00480                                 pdata.columns[i*pdata.nx*sdinfo.ncols+j*sdinfo.ncols+k] /= pdata.z[i][j].n;
00481 //                      cerr << 'z' << pdata.z[i][j].data;
00482                 }
00483                 if (scatter == true)
00484                 {
00485                         for (j = 0; j < pdata.nx; ++j)                          //average bins
00486                                 pdata.scattery[i][j] /= pdata.z[i][j].n;
00487                         delete[] tempyscatter;
00488                 }
00489 
00490                 statusProgressbar->setProgress(i+1);
00491                 a->forceRefresh();
00492                 a->repaint();
00493         }
00494         statusProgressbar->setProgress(0);
00495         delete[] row;
00496 
00497 //interpolate
00498         int m, n;
00499         int maxinterp = FXIntVal(setinterpTextfield->getText());
00500         if (setinterpCheckbutton->getCheck() == true)
00501         {
00502                 if (setinterpTogglebutton->getState() == 1)     //along X
00503                 {
00504                         for (i = 0; i < pdata.ny; ++i)  //each sweep
00505                         {
00506                                 for (j = 1; j < pdata.nx-1; ++j)        //each point in sweep
00507                                 {
00508                                         if (pdata.z[i][j].n == 0)       //if a point is missing
00509                                         {
00510                                                 if (pdata.z[i][j-1].n != 0)     //check that the one before is there
00511                                                 {
00512                                                         for (k = j+1; (k < pdata.nx) && (k < j+maxinterp); ++k) //for all points in sweep after the missing one up to the max
00513                                                         {
00514                                                                 if (pdata.z[i][k].n != 0)       //if a point is there
00515                                                                 {
00516                                                                         for (m = 0; m < k-j; ++m)       //interpolate all points in the missing range
00517                                                                         {
00518                                                                                 pdata.z[i][j+m].data = pdata.z[i][j-1].data+(pdata.z[i][k].data-pdata.z[i][j-1].data)*((float)(m+0.5)/(float)(k-j));
00519                                                                                 for (n = 0; n < sdinfo.ncols; ++n)      //interpolate array that stores other columns
00520                                                                                         pdata.columns[i*pdata.nx*sdinfo.ncols+(j+m)*sdinfo.ncols+n] = pdata.columns[i*pdata.nx*sdinfo.ncols+(j-1)*sdinfo.ncols+n]+(pdata.columns[i*pdata.nx*sdinfo.ncols+k*sdinfo.ncols+n]-pdata.columns[i*pdata.nx*sdinfo.ncols+(j-1)*sdinfo.ncols+n])*((float)(m+0.5)/(float)(k-j));;
00521                                                                                 if (scatter == true)
00522                                                                                         pdata.scattery[i][j+m] = pdata.scattery[i][j-1]+(pdata.scattery[i][k]-pdata.scattery[i][j-1])*((float)(m+0.5)/(float)(k-j));
00523                                                                                 pdata.z[i][j+m].n = 1;
00524                                                                         }
00525                                                                         j += m;
00526                                                                         break;
00527                                                                 }
00528                                                         }
00529                                                 }
00530                                                 else    //if one before is missing, no need to check next one as we can't fill the current one
00531                                                 {
00532                                                         ++j;
00533                                                 }
00534                                         }
00535                                 }
00536                         }
00537                 }
00538                 else    //along Y
00539                 {
00540                         for (j = 0; j < pdata.nx; ++j)  //each point in sweep
00541                         {
00542                                 for (i = 1; i < pdata.ny-1; ++i)        //each sweep
00543                                 {
00544                                         if (pdata.z[i][j].n == 0)       //if a point is missing
00545                                         {
00546                                                 if (pdata.z[i-1][j].n != 0)     //check that the one before is there
00547                                                 {
00548                                                         for (k = i+1; (k < pdata.ny) && (k < i+maxinterp); ++k) //for all points in sweep after the missing one up to the max
00549                                                         {
00550                                                                 if (pdata.z[k][j].n != 0)       //if a point is there
00551                                                                 {
00552                                                                         for (m = 0; m < k-i; ++m)       //interpolate all points in the missing range
00553                                                                         {
00554                                                                                 pdata.z[i+m][j].data = pdata.z[i-1][j].data+(pdata.z[k][j].data-pdata.z[i-1][j].data)*((float)(m+0.5)/(float)(k-i));
00555                                                                                 for (n = 0; n < sdinfo.ncols; ++n)      //interpolate array that stores other columns
00556                                                                                         pdata.columns[(i+m)*pdata.nx*sdinfo.ncols+j*sdinfo.ncols+n] = pdata.columns[(i-1)*pdata.nx*sdinfo.ncols+j*sdinfo.ncols+n]+(pdata.columns[k*pdata.nx*sdinfo.ncols+j*sdinfo.ncols+n]-pdata.columns[(i-1)*pdata.nx*sdinfo.ncols+j*sdinfo.ncols+n])*((float)(m+0.5)/(float)(k-j));;
00557                                                                                 if (scatter == true)
00558                                                                                         pdata.scattery[i+m][j] = pdata.scattery[i-1][j]+(pdata.scattery[k][j]-pdata.scattery[i-1][j])*((float)(m+0.5)/(float)(k-i));
00559                                                                                 pdata.z[i+m][j].n = 1;
00560                                                                         }
00561                                                                         i += m;
00562                                                                         break;
00563                                                                 }
00564                                                         }
00565                                                 }
00566                                                 else    //if one before is missing, no need to check next one as we can't fill the current one
00567                                                 {
00568                                                         ++i;
00569                                                 }
00570                                         }
00571                                 }
00572                         }
00573                 }
00574         }
00575 
00576 /* 01/02/2007 - moved transformation to before the Z happens and added ability to generate scatter data from non-scatter data for full x/y/z manipulation
00577         for (i = 0; i < pdata.nx; ++i)  //transform x data
00578         {
00579                 pdata.x[i] = functions[0].Evaluate(lo+(float)i*2.0*delta, 0.0, 0.0, 0, NULL);
00580 //              cerr << 'x' << pdata.x[i];
00581         }
00582         for (i = 0; i < pdata.ny; ++i)  //transform y data
00583                 pdata.y[i] = functions[1].Evaluate(0.0, pdata.y[i], 0.0, 0, NULL);
00584 */
00585 
00586 
00587         int o;
00588         for (o = 0; o < 2; ++o)         //loop to allow the order to be swapped
00589         {
00590                 //Differentiate
00591                 if ((dadiffCheckbutton->getCheck() == true)
00592                         && (((daorderCheckbutton->getCheck() == false) && (o == 0)) || ((daorderCheckbutton->getCheck() == true) && (o == 1))))
00593                 {
00594                         double *diffed;
00595 //                      if (dadiffTogglebutton->getState() == true)
00596                         int di = dadiffOptionmenu->getCurrentNo();
00597                         if (di == 0)
00598                         {
00599                                 diffed = new double[pdata.nx];
00600                                 if (setaltdifferentialCheckbutton->getCheck() == true)
00601                                 {       //2 point differential
00602                                         for (i = 0; i < pdata.ny; ++i)
00603                                         {
00604                                                 for (j = 0; j < pdata.nx-1; ++j)
00605                                                 {
00606                                                         diffed[j] = (pdata.z[i][j+1].data-pdata.z[i][j].data)/(pdata.x[j+1]-pdata.x[j]);
00607                                                 }
00608                                                 diffed[pdata.nx-1] = diffed[pdata.