00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "omgclimatefilereader.h"
00021
00022
00023 #include <iostream>
00024
00025
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)
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
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
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
00131 else if (mFileType == IPCC_OBSERVED)
00132 {
00133 mXDim = 720;
00134 mYDim = 360;
00135 mFileHeaderLines = 2;
00136 mBlockHeaderLines = 0;
00137 }
00138
00139 else if (mFileType == ECHAM4)
00140 {
00141 mXDim = 128;
00142 mYDim = 64;
00143 mFileHeaderLines = 0;
00144 mBlockHeaderLines = 1;
00145 }
00146
00147 else if (mFileType == CGCM2)
00148 {
00149 mXDim = 96;
00150 mYDim = 48;
00151 mFileHeaderLines = 0;
00152 mBlockHeaderLines = 1;
00153 }
00154
00155 else if (mFileType == CSIRO_MK2)
00156 {
00157 mXDim = 64;
00158 mYDim = 56;
00159 mFileHeaderLines = 0;
00160 mBlockHeaderLines = 1;
00161 }
00162
00163 else if (mFileType == NCAR_CSM_PCM)
00164 {
00165 mXDim = 128;
00166 mYDim = 64;
00167 mFileHeaderLines = 0;
00168 mBlockHeaderLines = 1;
00169 }
00170
00171 else if (mFileType == GFDL_R30)
00172 {
00173 mXDim = 96;
00174 mYDim = 80;
00175 mFileHeaderLines = 0;
00176 mBlockHeaderLines = 1;
00177 }
00178
00179 else if (mFileType == CCSR_AGCM_OGCM)
00180 {
00181 mXDim = 64;
00182 mYDim = 32;
00183 mFileHeaderLines = 0;
00184 mBlockHeaderLines = 1;
00185 }
00186
00187 else if (mFileType == CRU_CL1_MONTHLY)
00188 {
00189 mXDim = 720;
00190 mYDim = 360;
00191 mFileHeaderLines = 2;
00192 mBlockHeaderLines = 0;
00193 }
00194
00195 else if (mFileType == GDAL)
00196 {
00197
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;
00205 mBlockHeaderLines = 0;
00206 }
00207
00208 else if (mFileType == VALDES)
00209 {
00210
00211
00212
00213
00214 mFileHeaderLines = 0;
00215 mBlockHeaderLines = 0;
00216 }
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
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
00323
00324 int myFileOffset=0;
00325 int myElementCount = mXDim * mYDim;
00326
00327 mBlockMarkersVector.clear();
00328
00329
00330
00331
00332
00333 QString myBmrFileName = mFileName;
00334
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
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
00364
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
00376
00377 myOuputTextStream.setDevice(&myBmrFile);
00378 }
00379
00380
00381 if (mFileType==GDAL)
00382 {
00383
00384 }
00385
00386
00387
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
00395
00397
00398
00399
00400
00401
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
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
00416 while (!mTextStream.eof() && myFileOffset >= 0)
00417 {
00418
00419 for (int i=0; i < mBlockHeaderLines; i++)
00420 {
00421 mTextStream.getline(mBuffer,mMaxLineLength-1);
00422
00423 }
00424 myFileOffset=mTextStream.tellg();
00425 if (myFileOffset == -1)
00426 {
00427
00428 break;
00429 }
00430 mBlockMarkersVector.push_back(myFileOffset);
00431
00432
00433 if (myFirstFlag)
00434 {
00435 myFirstFlag=false;
00436 myOuputTextStream << myFileOffset ;
00437 }
00438 else
00439 {
00440 myOuputTextStream << "\n" << myFileOffset ;
00441 }
00442
00443
00444 for (int i=0; i < myElementCount; i++)
00445 {
00446 mTextStream >> myTempVal;
00447 myFileOffset=mTextStream.tellg();
00448 }
00449
00450 mTextStream.getline(mBuffer,mMaxLineLength-1);
00451 }
00452
00453 myBmrFile.close();
00454
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
00475 if (!mEndOfMatrixFlag)
00476 {
00477 if (mFileType==GDAL)
00478 {
00479
00480 GDALRasterBand * myGdalBand = mGdalDataset->GetRasterBand(1);
00481 GDALDataType myType = myGdalBand->GetRasterDataType();
00482 int mySize = GDALGetDataTypeSize ( myType ) / 8;
00483 void *myData = CPLMalloc ( mySize );
00484
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
00491 myElementFloat = readValue ( myData, myType, 0 );
00492
00493 free (myData);
00494 mCurrentElementNo++;
00495 }
00496 else
00497 {
00498
00499
00500 mTextStream >> myElementFloat;
00501
00502 mCurrentElementNo++;
00503 }
00504
00505 if (mCurrentElementNo == ((mXDim*mYDim)))
00506 {
00507 mEndOfMatrixFlag=true;
00508 }
00509 else
00510 {
00511 mEndOfMatrixFlag=false;
00512 }
00513 }
00514 else
00515 {
00516
00517
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
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
00544 if ((mCurrentColumn ) == mXDim)
00545 {
00546 mCurrentColumn=1;
00547 mCurrentRow++;
00548 }
00549 else
00550 {
00551 mCurrentColumn++;
00552 }
00553 }
00554 return myElementFloat;
00555 }
00556
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 }