Main Page | Modules | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages

omgclimatefilereader.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2005 by Tim Sutton   *
00003  *   tim@linfiniti.com   *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015  *   You should have received a copy of the GNU General Public License     *
00016  *   along with this program; if not, write to the                         *
00017  *   Free Software Foundation, Inc.,                                       *
00018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00019  ***************************************************************************/
00020 #include "omgclimatefilereader.h"
00021 
00022 
00023 #include <iostream>
00024 
00025 //qt includes
00026 #include <QTextStream>
00027 
00028 
00029 OmgClimateFileReader::OmgClimateFileReader() : QObject()
00030 {}
00031 
00032 OmgClimateFileReader::OmgClimateFileReader(QString theFileName, FileType theFileType) : QObject()
00033 {
00034   initialise(theFileName, theFileType);
00035 }
00036 
00037 
00038 
00039 OmgClimateFileReader::~OmgClimateFileReader()
00040 {
00041   if (mFileType==GDAL)
00042   {
00043     delete mGdalDataset;
00044   }
00045   else
00046   {
00047     mTextStream.close();
00048   }
00049 
00050 }
00051 
00052 bool OmgClimateFileReader::initialise(QString theFileName, FileType theFileType)
00053 {
00054 
00055   
00056   mFileName=theFileName;
00057   if (theFileType==GDAL) //read using gdal api
00058   {
00059     GDALAllRegister();
00060     mGdalDataset = (GDALDataset *) GDALOpen( theFileName.toLocal8Bit(), GA_ReadOnly );
00061     if( mGdalDataset == NULL )
00062     {
00063       emit error ("Error opening " + theFileName + " using GDAL driver");
00064       return false;
00065     }
00066   }
00067   else //all other formats are read using a text stream
00068   {
00069     mTextStream.open (theFileName.toLocal8Bit());
00070     if ( !mTextStream.is_open() || !mTextStream.good())
00071     {
00072       emit error ("Error opening " + theFileName);
00073       return false;
00074     }
00075   }
00076   setFileType(theFileType);
00077   mCurrentColumn=0;
00078   mCurrentRow=0;
00079   mCurrentElementNo=0;
00080   mEndOfMatrixFlag=false;
00081   getBlockMarkers();
00082   return true;
00083 }
00084 
00085 
00086 
00087 
00088 const long OmgClimateFileReader::xDim()
00089 {
00090   return mXDim;
00091 }
00092 
00093 
00096 const long OmgClimateFileReader::yDim()
00097 {
00098   return mYDim;
00099 }
00100 
00103 const OmgClimateFileReader::FileType OmgClimateFileReader::getFileType()
00104 {
00105   return mFileType;
00106 }
00107 
00110 bool OmgClimateFileReader::setFileType( const FileType theFileType)
00111 {
00112   try
00113   {
00114     mFileType = theFileType;
00115     //Set Hadley member variables
00116     if ((mFileType == HADLEY_SRES) || (mFileType == HADLEY_IS92))
00117     {
00118       mXDim = 96;
00119       mYDim = 73;
00120       mFileHeaderLines = 0;
00121       mBlockHeaderLines = 1;
00122     }
00123     else if (mFileType == HADLEY_SRES_MEAN)
00124     {
00125       mXDim = 96;
00126       mYDim = 73;
00127       mFileHeaderLines = 0;
00128       mBlockHeaderLines = 5;
00129     }
00130     //Set IPCC observed member variables
00131     else if (mFileType == IPCC_OBSERVED)
00132     {
00133       mXDim = 720;
00134       mYDim = 360;
00135       mFileHeaderLines = 2;
00136       mBlockHeaderLines = 0;
00137     }
00138     //Set ECHAM4 member variables
00139     else if (mFileType == ECHAM4)
00140     {
00141       mXDim = 128;
00142       mYDim = 64;
00143       mFileHeaderLines = 0;
00144       mBlockHeaderLines = 1;
00145     }
00146     //Set CCCma member variables
00147     else if (mFileType == CGCM2)
00148     {
00149       mXDim = 96;
00150       mYDim = 48;
00151       mFileHeaderLines = 0;
00152       mBlockHeaderLines = 1;
00153     }
00154     //Set CSIRO_Mk2 member variables
00155     else if (mFileType == CSIRO_MK2)
00156     {
00157       mXDim = 64;
00158       mYDim = 56;
00159       mFileHeaderLines = 0;
00160       mBlockHeaderLines = 1;
00161     }
00162     //Set NCAR member variables
00163     else if (mFileType == NCAR_CSM_PCM)
00164     {
00165       mXDim = 128;
00166       mYDim = 64;
00167       mFileHeaderLines = 0;
00168       mBlockHeaderLines = 1;
00169     }
00170     //Set GFDL member variables
00171     else if (mFileType == GFDL_R30)
00172     {
00173       mXDim = 96;
00174       mYDim = 80;
00175       mFileHeaderLines = 0;
00176       mBlockHeaderLines = 1;
00177     }
00178     //Set CCSRC member variables
00179     else if (mFileType == CCSR_AGCM_OGCM)
00180     {
00181       mXDim = 64;
00182       mYDim = 32;
00183       mFileHeaderLines = 0;
00184       mBlockHeaderLines = 1;
00185     }
00186     //Set CRU member variables
00187     else if (mFileType == CRU_CL1_MONTHLY)
00188     {
00189       mXDim = 720;
00190       mYDim = 360;
00191       mFileHeaderLines = 2;
00192       mBlockHeaderLines = 0;
00193     }
00194     //Set ArcInfo ASCII grid and CRES member variables
00195     else if (mFileType == GDAL)
00196     {
00197       //qDebug("OmgClimateFileReader::setFileType() - setting file type to GDAL") ;
00198       if (!mGdalDataset)
00199       {
00200         std::cout << "Error : Cant set file type before the file has been opened! " << std::endl;
00201       }
00202       mXDim = mGdalDataset->GetRasterXSize();
00203       mYDim = mGdalDataset->GetRasterYSize();
00204       mFileHeaderLines = 0;//not used
00205       mBlockHeaderLines = 0;//not  used
00206     }
00207     //Set Valdes member variables
00208     else if (mFileType == VALDES)
00209     {
00210       /* class user will need to specify rows and cols */
00211       //mXDim = frmCDPWizard.txtSpecifyNumCol;
00212       //mYDim = frmCDPWizard.txtSpecifyNumRow;
00213       //columnsPerRowLong = frmCDPWizard.txtSpecifyNumDataCols;
00214       mFileHeaderLines = 0;
00215       mBlockHeaderLines = 0;
00216     }//end of filetype handling
00217     return true;
00218   }
00219   catch (...)
00220   {
00221     return false;
00222   }
00223 }
00224 
00226 const QString  OmgClimateFileReader::filename()
00227 {
00228   return mFileName;
00229 }
00230 
00231 
00232 
00235 const bool OmgClimateFileReader::isAtMatrixEnd()
00236 {
00237   return mEndOfMatrixFlag;
00238 }
00239 
00241 const int OmgClimateFileReader::activeBlock()
00242 {
00243   return mActiveBlockNo;
00244 }
00245 
00247 bool OmgClimateFileReader::setActiveBlock( const unsigned int theBlockNo)
00248 {
00249   // sanity check first!
00250   if (!mTextStream.is_open() || !mTextStream.good())
00251   {
00252     emit error ("Error input file is not properly open!");
00253     return false;
00254   }
00255   if ( theBlockNo > static_cast<unsigned int>(mBlockMarkersVector.size()))
00256   {
00257     emit error ("Attempting to read beyond blocks boundary");
00258     return false;
00259   }
00260   mActiveBlockNo = theBlockNo;
00261   mBlockStartPos = mBlockMarkersVector[theBlockNo];
00262   qDebug ("Moving to block %i position in file %i",theBlockNo,mBlockStartPos);
00263   mTextStream.seekg(mBlockStartPos,std::ios::beg);
00264   int myPos = mTextStream.tellg();
00265   if (myPos != mBlockStartPos)
00266   {
00267     emit error ("Seek to datastart failed!");
00268     qDebug ("Seek to datastart failed!");
00269     return false;
00270   }
00271   mCurrentElementNo=0;
00272   mCurrentColumn = 0;
00273   mCurrentRow=1;
00274   mEndOfMatrixFlag=false;
00275   return true;
00276 }
00277 
00278 
00279 
00280 const int OmgClimateFileReader::headerLineCount()
00281 {
00282   return mFileHeaderLines;
00283 }
00284 
00285 
00286 const long OmgClimateFileReader::currentCol()
00287 {
00288   return mCurrentColumn;
00289 }
00290 
00291 
00292 
00293 const long OmgClimateFileReader::currentRow()
00294 {
00295   return mCurrentRow;
00296 }
00297 
00298 
00299 
00300 const long OmgClimateFileReader::currentElementNo()
00301 {
00302   return mCurrentElementNo;
00303 }
00304 
00305 
00306 const int OmgClimateFileReader::blockHeaderLineCount()
00307 {
00308   return mBlockHeaderLines;
00309 }
00310 
00311 const int OmgClimateFileReader::blockStartPos()
00312 {
00313   return mBlockStartPos;
00314 }
00315 
00316 
00317 
00318 
00319 QVector <int> OmgClimateFileReader::getBlockMarkers(bool theForceFlag)
00320 {
00321   //
00322   // Set up some vars
00323   //
00324   int myFileOffset=0; //store the current position in the file
00325   int myElementCount = mXDim * mYDim;
00326   //clear the vector
00327   mBlockMarkersVector.clear();
00328 
00329   //
00330   //see if we can retrieve the block markers from the .bmr file (if one exists)
00331   //
00332 
00333   QString myBmrFileName = mFileName;
00334   //replace the extension with .bmr - we assum the extension is last 3 chars
00335   myBmrFileName =  myBmrFileName.left(myBmrFileName.length()-3) + QString("bmr");
00336   if (QFile::exists(myBmrFileName) && !theForceFlag)
00337   {
00338     QFile myBmrFile( myBmrFileName );
00339     if ( !myBmrFile.open( QIODevice::ReadOnly ) )
00340     {
00341       emit error("Bmr file cant be opened!");
00342     }
00343     else if (theForceFlag)
00344     {
00345       emit message("Bmr file ignored - forceFlag is true ") ;
00346     }
00347     else
00348     {
00349       // now open the text stream on the filereader
00350       QTextStream mTextStream(&myBmrFile);
00351       while (!mTextStream.atEnd())
00352       {
00353         mTextStream >> myFileOffset ;
00354         mBlockMarkersVector.push_back(myFileOffset);
00355       }
00356       myBmrFile.close();
00357       return mBlockMarkersVector;
00358     }
00359   }
00360 
00361 
00362   //
00363   // Open the bmr file for writing seeing that it doesnt exists
00364   // or the calling fn has asked for forced parsing
00365   //
00366   QFile myBmrFile( myBmrFileName );
00367   QTextStream myOuputTextStream;
00368   if ( !myBmrFile.open( QIODevice::WriteOnly ) )
00369   {
00370     emit error("Cannot open file : " + myBmrFileName.toLocal8Bit() + " for writing") ;
00371     return mBlockMarkersVector;
00372   }
00373   else
00374   {
00375     //qDebug("Opened block marker file : " + myBmrFileName.toLocal8Bit() + " successfully.") ;
00376     // now open the text stream on the filereader
00377     myOuputTextStream.setDevice(&myBmrFile);
00378   }
00379 
00380   //if the datafile is a an arc/info grid file, there is only one data block
00381   if (mFileType==GDAL)
00382   {
00383     //no need to do anything as we'll be using gdal for data access
00384   }
00385 
00386   //
00387   // Start parsing the file
00388   //
00389   if (!mTextStream.is_open() || !mTextStream.good())
00390   {
00391     emit error ("File is not open, cannot generate block markers!");
00392     return mBlockMarkersVector;
00393   }
00394   //work out the file size
00395 
00397   //mTextStream.seekg(0,std::ios::end);
00398   //int myEndPos = mTextStream.tellg();
00399   //qDebug("File length is %i",myEndPos);
00400 
00401   //make sure were at the start of the file
00402   mTextStream.seekg(0,std::ios::beg);
00403   if (!mTextStream.tellg()==0)
00404   {
00405     emit error ("Failed to rewind to start of file!");
00406     return mBlockMarkersVector;
00407   }
00408   //skip header lines at the top of the file
00409   for (int i=0; i < mFileHeaderLines; i++)
00410   {
00411     mTextStream.getline(mBuffer,mMaxLineLength-1);
00412   }
00413   double myTempVal=0.0;
00414   bool myFirstFlag = true;
00415   //loop through the rest of the file getting the start pos for each datablock
00416   while (!mTextStream.eof() && myFileOffset >= 0)
00417   {
00418     //skip the datablock headers
00419     for (int i=0; i < mBlockHeaderLines; i++)
00420     {
00421       mTextStream.getline(mBuffer,mMaxLineLength-1);
00422       //qDebug("Header %i : %s",i,mBuffer);
00423     }
00424     myFileOffset=mTextStream.tellg();
00425     if (myFileOffset == -1)
00426     {
00427       //end of file encountered
00428       break;
00429     }
00430     mBlockMarkersVector.push_back(myFileOffset);
00431     //qDebug("Found new block start at %i",myFileOffset);
00432     //write this marker to our bmr file
00433     if (myFirstFlag)
00434     {
00435       myFirstFlag=false;
00436       myOuputTextStream << myFileOffset ;
00437     }
00438     else
00439     {
00440       myOuputTextStream << "\n" << myFileOffset ;
00441     }
00442     //now skip the data objects for this datablock
00443     //qDebug ("Skipping %i elements", myElementCount);
00444     for (int i=0; i < myElementCount; i++)
00445     {
00446       mTextStream >> myTempVal;
00447       myFileOffset=mTextStream.tellg();
00448     }
00449     //read on till the end of the current line so we can be sure to be at the start of the header!
00450     mTextStream.getline(mBuffer,mMaxLineLength-1);
00451   }
00452 
00453   myBmrFile.close();
00454   //make sure were at the start of the file
00455   mTextStream.close();
00456   mTextStream.clear();
00457 
00458 
00459   mTextStream.open (mFileName.toLocal8Bit());
00460   if ( !mTextStream.is_open() || !mTextStream.good())
00461   {
00462     emit error ("Error opening " + mFileName);
00463     return mBlockMarkersVector;
00464   }
00465   mCurrentColumn=1;
00466   mCurrentRow=1;
00467   mCurrentElementNo=0;
00468   return  mBlockMarkersVector;
00469 }
00470 
00471 float OmgClimateFileReader::getElement()
00472 {
00473   float myElementFloat=0;
00474   //see if it is ok to get another element
00475   if (!mEndOfMatrixFlag)
00476   {
00477     if (mFileType==GDAL)
00478     {
00479       //get the cell value for current col and row
00480       GDALRasterBand * myGdalBand = mGdalDataset->GetRasterBand(1);
00481       GDALDataType myType = myGdalBand->GetRasterDataType();
00482       int mySize = GDALGetDataTypeSize ( myType ) / 8;
00483       void *myData = CPLMalloc ( mySize );
00484       //-1 in row is to cater for different offset system used by non gdal readers
00485       CPLErr err = myGdalBand->RasterIO ( GF_Read, mCurrentColumn, mCurrentRow, 1, 1, myData, 1, 1, myType, 0, 0 );
00486       if (err==CE_Failure) 
00487       {
00488          qDebug("Error reading element from gdal!");
00489       }
00490       // CPLErr myResultCPLerr = myGdalBand->RasterIO(GF_Read, 0, 0, myXDimInt, myYDimInt, myGdalScanData, myXDimInt, myYDimInt, GDT_Float32, 0, 0 );
00491       myElementFloat = readValue ( myData, myType, 0 );
00492       //std::cout << "Gdal Driver retrieved : " << myElementFloat << " at " << currentColLong <<" , " << currentRowLong << " ... from... "<<  filenameString << std::endl;
00493       free (myData);
00494       mCurrentElementNo++;
00495     }
00496     else
00497     {
00498       //read a float from the file - this will advance the file pointer
00499       //int myPos = mTextStream.tellg();
00500       mTextStream >> myElementFloat;
00501       //qDebug ("Read element %f from position %i in file." ,myElementFloat,myPos);
00502       mCurrentElementNo++;
00503     }
00504     //check if we have now run to the end of the matrix
00505     if (mCurrentElementNo == ((mXDim*mYDim)))
00506     {
00507       mEndOfMatrixFlag=true;
00508     }
00509     else
00510     {
00511       mEndOfMatrixFlag=false;
00512     }
00513   }
00514   else
00515   {
00516     //you should not reach this code because you should stop any reading
00517     //when end of block has been detected.
00518     qDebug(" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ") ;
00519     qDebug(" OmgClimateFileReader Notice:         ") ;
00520     qDebug(" Error trying to get element beyond   ") ;
00521     qDebug(" end of block! A vector of zeros will ") ;
00522     qDebug(" be returned!                         ") ;
00523     qDebug(" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ") ;
00524     emit error ("Climate reader tried to read past end of block!");
00525   }
00526 
00527   //if we arnt at the end of the file we can update position markers...
00528   
00529   if (mFileType==GDAL)
00530   {
00531     if ((mCurrentColumn ) == mXDim-1)
00532     {
00533       mCurrentColumn=0;
00534       mCurrentRow++;
00535     }
00536     else
00537     {
00538       mCurrentColumn++;
00539     }
00540   }
00541   else
00542   {
00543     //increment the column and row counter and wrap them if needed
00544     if ((mCurrentColumn ) == mXDim)
00545     {
00546       mCurrentColumn=1;
00547       mCurrentRow++;
00548     }
00549     else
00550     {
00551       mCurrentColumn++;
00552     }
00553   }
00554   return myElementFloat;
00555 }
00556 // only aplicable to gdal!
00557 double OmgClimateFileReader::readValue ( void *theData, GDALDataType theType, int theIndex )
00558 {
00559   double myVal;
00560 
00561   switch ( theType )
00562   {
00563   case GDT_Byte:
00564     return (double) ((GByte *)theData)[theIndex];
00565     break;
00566   case GDT_UInt16:
00567     return (double) ((GUInt16 *)theData)[theIndex];
00568     break;
00569   case GDT_Int16:
00570     return (double) ((GInt16 *)theData)[theIndex];
00571     break;
00572   case GDT_UInt32:
00573     return (double) ((GUInt32 *)theData)[theIndex];
00574     break;
00575   case GDT_Int32:
00576     return (double) ((GInt32 *)theData)[theIndex];
00577     break;
00578   case GDT_Float32:
00579     return (double) ((float *)theData)[theIndex];
00580     break;
00581   case GDT_Float64:
00582     myVal = ((double *)theData)[theIndex];
00583     return (double) ((double *)theData)[theIndex];
00584     break;
00585   default:
00586     qWarning("Data type %d is not supported", theType);
00587   }
00588   return 0.0;
00589 }
00590 const int OmgClimateFileReader::blockCount()
00591 {
00592   return mBlockMarkersVector.size();
00593 }
00594 
00595 void OmgClimateFileReader::printFirstCellInEachBlock()
00596 {
00597   qDebug("Printing first cell in each block:");
00598   double myElementDouble=0;
00599   for (int i=0; i < mBlockMarkersVector.size();i++)
00600   {
00601     setActiveBlock(i);
00602     myElementDouble=getElement();
00603     qDebug ("First cell in block %i is %f \n",i,myElementDouble);
00604   }
00605 }
00606 void OmgClimateFileReader::printLastCellInEachBlock()
00607 {
00608   qDebug("Printing first cell in each block:");
00609   double myElementDouble=0;
00610   for (int i=0; i < mBlockMarkersVector.size();i++)
00611   {
00612     setActiveBlock(i);
00613     do
00614     {
00615       myElementDouble=getElement();
00616     }
00617     while (!isAtMatrixEnd());
00618     qDebug ("Last cell in block %i is %f \n",i,myElementDouble);
00619   }
00620 
00621 }
00622 void OmgClimateFileReader::printBlockMarkers()
00623 {
00624   qDebug("Printing block markers:");
00625   for (int i=0; i < mBlockMarkersVector.size(); i++ )
00626   {
00627     qDebug(QString::number(i).toLocal8Bit() + " -- " + QString::number(mBlockMarkersVector.at(i)).toLocal8Bit());
00628   }
00629 }
00630 
00631 void OmgClimateFileReader::printBlock(int theBlock)
00632 {
00633   qDebug("Printing block:%i",theBlock);
00634   setActiveBlock(theBlock);
00635   while (!isAtMatrixEnd())
00636   {
00637     printf("%f\n",getElement());
00638     if (currentCol()==1)
00639     {
00640       printf("\n");
00641     }
00642   }
00643 }

Generated on Mon Apr 28 15:08:14 2008 for openModellerDesktop by  doxygen 1.4.1-20050210