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

omgclimateimporter.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 
00021 #include "omgclimateimporter.h"
00022 #include "omgclimatefilereader.h"
00023 #include "omgmeridianswitcher.h"
00024 
00025 //qt includes
00026 #include <QString>
00027 #include <QStringList>
00028 #include <QFile>
00029 #include <QFileInfo>
00030 #include <QTextStream>
00031 
00032 OmgClimateImporter::OmgClimateImporter() : QObject()
00033 {}
00034 
00035 OmgClimateImporter::~OmgClimateImporter()
00036 {}
00037 
00038 QStringList OmgClimateImporter::import(QString theInputFile, QString theOutputDir, QString theFileType)
00039 {
00040 
00041   // I should take a moment to explain before we start reading the data that
00042   // hadley cells are rectangular (3.75deg x 2.5deg). In order to make them square
00043   // we need to multiply the number of cells in each direction to get them to the
00044   // lowest common denominator. That means x cells are multiplied by 15
00045   // and y cells are multiplied by 10. We then end up with a block of 15x10 cells representing
00046   // the original rectangular cell. The hadley matrix originally was 96x73, but now
00047   // it will be 1440 x 730. Then lastly we discard the5 top rows and 5 bottom rows
00048   // to end up with a final resolution of 1440x720 (0.25 x 0.25 cells)
00049   float myInputCellSizeX = 0;
00050   int myXMultiplier = 0;
00051   int myYMultiplier = 0;
00052   int myEndRowMultiplier = 0;
00053   bool myDoMeridianShiftFlag = false;
00054 
00055   OmgClimateFileReader myReader;
00056   if (theFileType=="CRU")
00057   {
00058     myReader.initialise(theInputFile,OmgClimateFileReader::CRU_CL1_MONTHLY);
00059 
00060     myInputCellSizeX = 0.5;
00061     myXMultiplier = 2;
00062     myYMultiplier = 2;
00063     myEndRowMultiplier = 2;
00064     myDoMeridianShiftFlag = true;
00065   }
00066   else if (theFileType=="Hadley")
00067   {
00068     myReader.initialise(theInputFile,OmgClimateFileReader::HADLEY_SRES_MEAN);
00069     myInputCellSizeX = 3.75;
00070     myXMultiplier = 15;
00071     myYMultiplier = 10;
00072     myEndRowMultiplier = 5;
00073     myDoMeridianShiftFlag = true;
00074   }
00075   else // Invalid filetype
00076   {
00077     emit error("Invalid file type");
00078     return QStringList ();
00079   }
00080   connect(&myReader, SIGNAL(error(QString)), this, SLOT(propogateError(QString)));
00081   connect(&myReader, SIGNAL(message(QString)), this, SLOT(propogateMessage(QString)));
00082 
00083   //calculate the base name of the file without its extension of path
00084   QFileInfo myFileInfo(theInputFile);
00085   QString myBaseName = myFileInfo.baseName();
00086 
00087   int myXDim = myReader.xDim();
00088   int myYDim = myReader.yDim();
00089   int myBlockCount = myReader.blockCount();
00090 
00091   QStringList myOutputFileList;
00092 
00093   // shameless hardcoding taking place here....
00094   QString myHeader;
00095   myHeader += "ncols         " + QString::number(myXDim*myXMultiplier ) + "\r\n";
00096   myHeader += "nrows         " + QString::number(((myYDim-2)*(myYMultiplier))+(myEndRowMultiplier*2) ) + "\r\n";
00097   myHeader += "xllcorner     -180\r\n";
00098   myHeader += "yllcorner     -90\r\n";
00099   myHeader += "cellsize       " + QString::number(1.0/(static_cast<float>(myXDim*myXMultiplier)/360) ) + "\r\n";
00100   //note hdaley seen to use +9999 for no data....
00101   myHeader += "NODATA_value  -9999\r\n";
00102 
00103   //make a meridian shift object
00104   OmgMeridianSwitcher mySwitcher;
00105   connect(&mySwitcher, SIGNAL(error(QString)), this, SLOT(propogateError(QString)));
00106   connect(&mySwitcher, SIGNAL(message(QString)), this, SLOT(propogateMessage(QString)));
00107 
00108   //for debugging....to be removed...
00109   //myReader.printBlockMarkers();
00110   //myReader.printFirstCellInEachBlock();
00111   //myReader.printLastCellInEachBlock();
00112 
00113   for (int i=0; i<myBlockCount;i++)
00114   {
00115     if (!myReader.setActiveBlock(i))
00116     {
00117       break;
00118     }
00119     //note filereader use base 1 not base 0!
00120     emit message("Processing block " + QString::number(i+1));
00121     QString myOutputFileName;
00122     //months are base1 !
00123     int myMonthNo = i+1;
00124     if (myMonthNo<10)
00125     {
00126       myOutputFileName = theOutputDir + "/" + myBaseName + "_0" + QString::number(myMonthNo).toLocal8Bit() + ".asc";
00127     }
00128     else
00129     {
00130       myOutputFileName = theOutputDir + "/" + myBaseName + "_" + QString::number(myMonthNo).toLocal8Bit() + ".asc";
00131     }
00132     QFile myOutputFile (myOutputFileName);
00133     //note file is not appended to but overwritten!
00134     if ( myOutputFile.open( QIODevice::WriteOnly ) )
00135     {
00136       myOutputFileList.append(myOutputFileName);
00137       QTextStream myOutputTextStream( &myOutputFile );
00138       myOutputTextStream << myHeader.toLocal8Bit();
00139       int myCurrentCount=0;
00140       QString myCurrentLine;
00141       while (!myReader.isAtMatrixEnd())
00142       {
00143         float myFloat = myReader.getElement();
00144         //repeat in the x direction the prescribed amount of times
00145         for (int x=1 ; x <= myXMultiplier; x++)
00146         {
00147           myCurrentLine +=  QString::number(myFloat);
00148           if (x < myXMultiplier)
00149           {
00150             myCurrentLine += " ";
00151           }
00152         }
00153         //if we are at rows' end we must repeat in the y direction too....
00154         //(simply by writing the same line several times)
00155         if (myReader.currentCol()==myXDim)
00156         {
00157           myCurrentLine += "\r\n";
00158           int myCurrentRowNo = myReader.currentRow();
00159           if (myCurrentRowNo==1 || myCurrentRowNo == myYDim)
00160           {
00161             //qDebug(myCurrentLine.toLocal8Bit());
00162             for (int y=0; y < myEndRowMultiplier; y++)
00163             {
00164               myOutputTextStream << myCurrentLine.toLocal8Bit();
00165             }
00166           }
00167           else
00168           {
00169             for (int y=0; y < myYMultiplier; y++)
00170             {
00171               myOutputTextStream << myCurrentLine.toLocal8Bit();
00172             }
00173           }
00174           myCurrentLine="";
00175         }
00176         else
00177         {
00178           myCurrentLine += " ";
00179         }
00180         myCurrentCount++;
00181       }
00182       myOutputFile.close();
00183     }
00184     else
00185     {
00186       emit error ("Could not open output file " + myOutputFileName.toLocal8Bit() + " for writing.");
00187       break;
00188     }
00189 
00190     if (myDoMeridianShiftFlag)
00191     {
00192       QString myMeridianShiftOutputFileName;
00193       if (myMonthNo<10)
00194       {
00195         myMeridianShiftOutputFileName = theOutputDir + "/" + myBaseName + "_shift_0" + QString::number(myMonthNo).toLocal8Bit() + ".asc";
00196       }
00197       else
00198       {
00199         myMeridianShiftOutputFileName = theOutputDir + "/" + myBaseName + "_shift_" + QString::number(myMonthNo).toLocal8Bit() + ".asc";
00200       }
00201       emit message("Shifting meridian");
00202       mySwitcher.doSwitch(myOutputFileName, myMeridianShiftOutputFileName);
00203     }
00204     emit updateProgress (i,myBlockCount);
00205 
00206 
00207   }
00208   emit message("Conversion Complete, " + QString::number(myBlockCount) + " blocks processed succssfully.");
00209   return myOutputFileList;
00210 }
00211 
00212 
00213 void OmgClimateImporter::propogateError (QString theError)
00214 {
00215   //just pass it on up the food chain
00216   emit error(theError);
00217 }
00218 
00219 void OmgClimateImporter::propogateMessage (QString theMessage)
00220 {
00221   //just pass it on up the food chain
00222   emit message(theMessage);
00223 }

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