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

omgmodel.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 "omgmodel.h"
00021 #include "omgui.h"
00022 #include "omggraph.h"
00023 #include "omggdal.h"
00024 
00025 #include <QString>
00026 #include <QDir>
00027 #include <QFile>
00028 #include <QTextStream>
00029 #include <QFileInfo>
00030 #include <QDomDocument>
00031 #include <QDomElement>
00032 #include <QSettings>
00033 #include <QImage>
00034 
00035 #include <qgsrasterlayer.h>
00036 #include <qgsrasterbandstats.h>
00037 
00038 
00039 OmgModel::OmgModel() : QObject(), OmgSerialisable(), OmgGuid(),
00040   mCoordinateSystem(""),
00041   mCoordinateSystemName(QObject::tr("None Selected")),
00042   mSpeciesFile(""),
00043   mTaxonName(""),
00044   //OmgLayer mOutputFormatLayer,
00045   //OmgLayerSet mProjectionLayerSet,
00046   //OmgLayerSet mCreationLayerSet,
00047   //OmgAlgorithm mAlgorithm,
00048   mCompletedFlag(false),
00049   mErrorFlag(false),
00050   //OmgLocalities mLocalities,
00051   //QDateTime mStartDateTimeStamp,
00052   //QDateTime mEndDateTimeStamp,
00053   mThumbnailFileName(""),
00054   mPreviewFileName(""),
00055   mLegendFileName(""),
00056   mRawImageFileName(""),
00057   mShapefileName(""),
00058   mCsvFileName(""),
00059   mColouredImageFileName(""),
00060   mWorkDir(""),
00061   mModelDefinition(""),
00062   mNormalizationDefinition(""),
00063   mRocScore(0.0),
00064   mAccuracy(0.0),
00065   mOmission(0.0),
00066   mCommission(-1), //initialise to -1 to show its invalid until set
00067   mPercentCellsPresent(0.0),
00068   mTotalCells(0.0),
00069   mModelLog(""),
00070   mModelRasterFormat("GreyTiff"),
00071   mLocalitiesFilterType(NO_FILTER)
00072 {
00073 
00074 }
00075 
00076 OmgModel::~OmgModel()
00077 {
00078 
00079 }
00080 
00081 bool OmgModel::isValid() const
00082 {
00084   return true;
00085 }
00086 
00087 void OmgModel::reset()
00088 {
00089   mErrorFlag=false;
00090   mCompletedFlag=false;
00091 }
00092 
00093 QString OmgModel::toString() const
00094 {
00095   QString myModel("Model Description:\n---------------------\n");
00096   myModel += "Coordinate System:\n";
00097   myModel += mCoordinateSystem + "\n";
00098   myModel += "Coordinate System Name:\n";
00099   myModel += mCoordinateSystemName + "\n";
00100   myModel += "Species File:\n";
00101   myModel += mSpeciesFile + "\n";
00102   myModel += "Taxon Name:\n";
00103   myModel += mTaxonName + "\n";
00104   myModel += "Model creationing Mask:\n";
00105   myModel += mCreationLayerSet.maskName() + "\n";
00106   myModel += "Model Projecting Mask\n";
00107   myModel += mProjectionLayerSet.maskName() + "\n";
00108   myModel += "Output Format Layer:\n";
00109   myModel += mOutputFormatLayer.name() + "\n";
00110   myModel += "Layers used to create the model:\n";
00111   myModel += mCreationLayerSet.toString() + "\n";
00112   myModel += "Layers used to project the model:\n";
00113   myModel += mProjectionLayerSet.toString() + "\n";
00114   myModel += "Number of localities used to create the model:";
00115   myModel += QString::number(mLocalities.count()) + "\n";
00116   myModel += "Output preview image file:\n";
00117   myModel += mPreviewFileName+"\n";
00118   myModel += "Output legend file:\n";
00119   myModel += mLegendFileName+"\n";
00120   myModel += "Algorithm details:\n";
00121   //TODO implement toString in alg class
00122   myModel += mAlgorithm.toString() + "\n";
00123   return myModel;
00124 }
00125 
00126 bool OmgModel::fromXml(const QString theXml) 
00127 {
00128   QDomDocument myDocument("model");
00129   myDocument.setContent(theXml);
00130   QDomElement myRootElement = myDocument.firstChildElement("Model");
00131   if (myRootElement.isNull())
00132   {
00133     //TODO - just make this a warning
00134     //qDebug("top element could not be found!");
00135     return false;
00136   }
00137   mCompletedFlag = (myRootElement.attribute("Completed")=="true") ? true : false;
00138   mErrorFlag = (myRootElement.attribute("Error")=="true") ? true : false;
00139   //@TODO make guid a attribute of model rather
00140   QString myGuid= myRootElement.attribute("Guid");
00141   setGuid( myGuid );
00142   mTaxonName = myRootElement.firstChildElement("TaxonName").text();
00143   mSpeciesFile = myRootElement.firstChildElement("SpeciesFile").text();
00144   mWorkDir = myRootElement.firstChildElement("WorkingDirectory").text();
00145   //@TODO check if simply calling text gets back the mode def properly!
00146   mModelDefinition = myRootElement.firstChildElement("Definition").text();
00147   mNormalizationDefinition = myRootElement.firstChildElement("Normalization").text();
00148   mModelLog = myRootElement.firstChildElement("Log").text();
00149   QDomElement myStatsElement = myRootElement.firstChildElement("Stats");
00150   mRocScore = myStatsElement.attribute("RocScore").toDouble();
00151   mAccuracy = myStatsElement.attribute("Accuracy").toDouble();
00152   mOmission = myStatsElement.attribute("Omission").toDouble();
00153   mCommission = myStatsElement.attribute("Commission").toDouble();
00154   mPercentCellsPresent = myStatsElement.attribute("PercentCellsPresent").toDouble();
00155   mTotalCells = myStatsElement.attribute("TotalCells").toDouble();
00156   //loop through the roc points
00157   mRocPoints.clear();
00158   QDomElement myRocStatsElement = myStatsElement.firstChildElement("RocStats");
00159   QDomElement myRocPointElement = myRocStatsElement.firstChildElement("RocPoint");
00160   while(!myRocPointElement.isNull()) 
00161   {
00162     if (myRocPointElement.tagName()!="RocPoint")
00163     {
00164       myRocPointElement = myRocPointElement.nextSiblingElement();
00165       continue;
00166     }
00167     QPair<double,double> myPair;
00168     myPair.first  = myRocPointElement.attribute("x").toDouble();
00169     myPair.second = myRocPointElement.attribute("y").toDouble();
00170     addRocPoint(myPair);
00171     myRocPointElement = myRocPointElement.nextSiblingElement();
00172   }
00173   //get teh coord system info
00174   QDomElement myCoordinateSystemElement=myRootElement.firstChildElement("CoordinateSystem");
00175   //get teh localities filter if any
00176   QDomElement myOptionsElement=myRootElement.firstChildElement("Options");
00177   QDomElement myFilterElement=myOptionsElement.firstChildElement("OccurrencesFilter");
00178   QDomElement myFilterTypeElement=myOptionsElement.firstChildElement("SpatiallyUnigue");
00179   if (!myFilterTypeElement.isNull())
00180   {
00181     mLocalitiesFilterType=SPATIALLY_UNIQUE;
00182   }
00183   else
00184   {
00185     myFilterTypeElement=myOptionsElement.firstChildElement("EnvironmentallyUnigue");
00186     if (!myFilterTypeElement.isNull())
00187     {
00188       mLocalitiesFilterType=ENVIRONMENTALLY_UNIQUE;
00189     }
00190     else
00191     {
00192       mLocalitiesFilterType=NO_FILTER;
00193     }
00194   }
00195   //get teh coordinate system
00196   mCoordinateSystemName = myCoordinateSystemElement.firstChildElement("Name").text();
00197   mCoordinateSystem = myCoordinateSystemElement.firstChildElement("WKT").text();
00198   //get the timing data
00199   QDomElement myTimingElement = myRootElement.firstChildElement("Timing");
00200   mStartDateTimeStamp.setTime_t(myTimingElement.attribute("Start").toUInt());
00201   mEndDateTimeStamp.setTime_t(myTimingElement.attribute("End").toUInt());
00202   //get teh output images
00203   QDomElement myOutputImagesElement=myRootElement.firstChildElement("OutputImages");
00204   QDomElement myThumbnailElement=myOutputImagesElement.firstChildElement("ThumbnailImage");
00205   QDomElement myPreviewElement=myOutputImagesElement.firstChildElement("PreviewImage");
00206   QDomElement myLegendElement=myOutputImagesElement.firstChildElement("LegendImage");
00207   QDomElement myRawImageElement=myOutputImagesElement.firstChildElement("RawImage");
00208   QDomElement myModelRasterFormatElement=myOutputImagesElement.firstChildElement("ModelRasterFormat");
00209   QDomElement myColouredImageElement=myOutputImagesElement.firstChildElement("ColouredImage");
00210   setThumbnailFileName( myThumbnailElement.text() );
00211   setPreviewFileName( myPreviewElement.text() );
00212   setLegendFileName( myLegendElement.text() );
00213   setRawImageFileName( myRawImageElement.text() );
00214   setColouredImageFileName( myColouredImageElement.text() );
00215   if (!myModelRasterFormatElement.isNull())
00216   {
00217     setModelRasterFormat(myModelRasterFormatElement.text());
00218   }
00219 
00220   //
00221   //restore the algorithm section
00222   //
00223   QDomElement myAlgorithmElement= myRootElement.firstChildElement("Algorithm");
00224   if (!myAlgorithmElement.isNull())
00225   {
00226     OmgAlgorithm myAlgorithm;
00227     //get a textual xml representation of the param tag
00228     QDomDocument myAlgorithmDoc("algorithm");
00229     //note we need to do a deep copy here because the
00230     //element is shared otherwise and when we
00231     //reparent it the loop stops after the first node
00232     //as no more siblings are found!
00233     QDomElement myCopy = myAlgorithmElement.cloneNode().toElement();
00234     myAlgorithmDoc.appendChild(myCopy);
00235     QString myXml = myAlgorithmDoc.toString();
00236     //now hand over the xml snippet to the model class to be deserialised
00237     if (myAlgorithm.fromXml(myXml))
00238     {
00239       setAlgorithm(myAlgorithm);
00240     }
00241     else
00242     {
00243       //return false;
00244     }
00245   }
00246   //
00247   // restore the localities
00248   mShapefileName = myRootElement.firstChildElement("Localities").firstChildElement("ShapefileName").text();
00249   mCsvFileName= myRootElement.firstChildElement("Localities").firstChildElement("CsvFileName").text();
00250 
00251   // @NOTE this code is a near duplication of code in omgexperiment::parsemodel()
00252   // and the two implementations should be refactored into one function
00253 
00254   mLocalities.clear();
00255   QDomElement myLocalityElement = myRootElement.firstChildElement("Localities").firstChildElement();
00256   while(!myLocalityElement.isNull()) 
00257   {
00258     if (myLocalityElement.tagName()!="Point")
00259     {
00260       myLocalityElement = myLocalityElement.nextSiblingElement();
00261       continue;
00262     }
00263     //qDebug("Parser found a point");
00264     OmgLocality myLocality;
00265     QString myId=myLocalityElement.attribute("Id");
00266     myLocality.setId(myId);
00267     QString myX=myLocalityElement.attribute("X");
00268     myLocality.setLongitude(myX.toDouble());
00269     QString myY=myLocalityElement.attribute("Y");
00270     myLocality.setLatitude(myY.toDouble());
00271     // this should be ignored by the omlib
00272     // but is used for de/serialising 
00273     // localities in the desktop so dont remove it
00274     QString myAbundance=myLocalityElement.attribute("Abundance");
00275     myLocality.setAbundance(myAbundance.toDouble());
00276     QString mySample=myLocalityElement.attribute("Sample");
00277     //qDebug("Sample for point: " + mySample.toLocal8Bit());
00278     QStringList myList=mySample.split(" ");
00279     QStringListIterator myIterator(myList);
00280     OmgSampleVector mySamples;
00281     while (myIterator.hasNext())
00282     {
00283       double myDouble=myIterator.next().toDouble();
00284       mySamples.push_back(myDouble);
00285     }
00286     myLocality.setSamples(mySamples);
00287     mLocalities.push_back(myLocality);
00288     myLocalityElement = myLocalityElement.nextSiblingElement();
00289   }
00290   //
00291   // Restore the output layer format
00292   //
00293   QDomElement myOutputFormatElement = myRootElement.firstChildElement("OutputFormatLayer").firstChildElement("Map");
00294   OmgLayer myLayer;
00295   myLayer.setName(myOutputFormatElement.attribute("Id"));
00296   QString myCategoricalString = myOutputFormatElement.attribute("IsCategorical" );
00297   myLayer.setCategorical((myCategoricalString=="0")? false : true);
00298   mOutputFormatLayer=myLayer;
00299   //
00300   // Restore the creation layerset
00301   //
00302   QDomElement myLayerSetElement = myRootElement.firstChildElement("CreationLayerSet").firstChildElement();
00303   QDomDocument myLayerSetDoc("layerset");
00304   //note we need to do a deep copy here because the
00305   //element is shared otherwise and when we
00306   //reparent it the loop stops after the first node
00307   //as no more siblings are found!
00308   QDomElement myCopy1 = myLayerSetElement.cloneNode().toElement();
00309   myLayerSetDoc.appendChild(myCopy1);
00310   QString myXml1 = myLayerSetDoc.toString();
00311   OmgLayerSet myLayerSet;
00312   //now hand over the xml snippet to the layerset class to be deserialised
00313   if (myLayerSet.fromXml(myXml1))
00314   {
00315     mCreationLayerSet = myLayerSet;
00316   }
00317   else
00318   {
00319     //return false;
00320   }
00321   //
00322   // Restore the projections layerset
00323   //
00324   QDomElement myLayerSetElement2 = myRootElement.firstChildElement("ProjectionLayerSet").firstChildElement();
00325   QDomDocument myLayerSetDoc2("layerset");
00326   //note we need to do a deep copy here because the
00327   //element is shared otherwise and when we
00328   //reparent it the loop stops after the first node
00329   //as no more siblings are found!
00330   QDomElement myCopy2 = myLayerSetElement2.cloneNode().toElement();
00331   myLayerSetDoc2.appendChild(myCopy2);
00332   QString myXml2 = myLayerSetDoc2.toString();
00333   OmgLayerSet myLayerSet2;
00334   //now hand over the xml snippet to the layerset class to be deserialised
00335   if (myLayerSet2.fromXml(myXml2))
00336   {
00337     mProjectionLayerSet = myLayerSet2;
00338   }
00339   else
00340   {
00341     //return false;
00342   }
00343 
00344   return true;
00345 }
00346 
00347 QString OmgModel::toXml() const 
00348 {
00349   //
00350   // This does not follow the same schema as libopenmodeller
00351   // since for the gui we have to serialise the extra properties
00352   // of the OmgModel class. See toModelCreationXml() and 
00353   // toModelProjectionXml() fo libom compliant representations
00354   //
00355   // Also note that the xml produced below is pretty ugly and 
00356   // will be completely redesigned in a future release
00357   //
00358   QString mySampleCount=QString::number(mLocalities.count());
00359   QString myString;
00360   myString += "<Model Guid=\"" + guid() + "\" Completed=\"";
00361   mCompletedFlag ? myString +="true" : myString += "false";
00362   myString += "\" Error=\"";
00363   mErrorFlag ? myString += "true" : myString += "false";
00364   myString += "\">";
00365   myString += "<CoordinateSystem>";
00366   myString +=   "<Name>";
00367   myString +=     mCoordinateSystemName ;
00368   myString +=   "</Name>\n";
00369   myString +=   "<WKT>";
00370   myString +=     mCoordinateSystem ;
00371   myString +=   "</WKT>\n";
00372   myString += "</CoordinateSystem>\n";
00373   myString += "<Options>\n";
00374   myString += "  <OccurrencesFilter>\n";
00375   if (mLocalitiesFilterType==NO_FILTER)
00376   {
00377     //add nothing
00378   }
00379   else if(mLocalitiesFilterType==SPATIALLY_UNIQUE)
00380   {
00381     myString += "    <SpatiallyUnique/>\n";
00382   }
00383   else //environmentally unique
00384   {
00385     myString += "    <EnvironmentallyUnique/>\n";
00386   }
00387   myString += "  </OccurrencesFilter>\n";
00388   myString += "</Options>\n";
00389   myString += "<SpeciesFile>";
00390   myString +=   mSpeciesFile;
00391   myString += "</SpeciesFile>\n";
00392   myString += "<TaxonName>";
00393   myString +=   mTaxonName;
00394   myString += "</TaxonName>\n";
00395   myString += "<OutputFormatLayer>";
00396   myString +=   mOutputFormatLayer.toXml();
00397   myString += "</OutputFormatLayer>\n";
00398   myString += "<ProjectionLayerSet>";
00399   myString +=   mProjectionLayerSet.toXml();
00400   myString += "</ProjectionLayerSet>\n";
00401   myString += "<CreationLayerSet>";
00402   myString +=   mCreationLayerSet.toXml();
00403   myString += "</CreationLayerSet>\n";
00404   myString +=   mAlgorithm.toXml();
00405   //loop through all the localities
00406   myString += "<Localities>";
00407   for (int i=0;i<mLocalities.count();i++)
00408   {
00409     OmgLocality myLocality = mLocalities.at(i);
00410     myString+=myLocality.toXml();
00411   }
00412   myString +=   "<ShapefileName>" + mShapefileName + "</ShapefileName>";
00413   myString +=   "<CsvFileName>" + mCsvFileName + "</CsvFileName>";
00414   myString += "</Localities>\n";
00415   myString += "<Timing Start=\"" + QString::number(mStartDateTimeStamp.toTime_t()) + "\" "
00416            +  "End=\"" + QString::number(mEndDateTimeStamp.toTime_t()) + "\"/>\n";
00417   myString += "<OutputImages>";
00418   myString +=   "<ThumbnailImage>";
00419   myString +=     mThumbnailFileName;
00420   myString +=   "</ThumbnailImage>";
00421   myString +=   "<PreviewImage>";
00422   myString +=     mPreviewFileName;
00423   myString +=   "</PreviewImage>";
00424   myString +=   "<LegendImage>";
00425   myString +=     mLegendFileName;
00426   myString +=   "</LegendImage>";
00427   myString +=   "<RawImage>";
00428   myString +=     mRawImageFileName;
00429   myString +=   "</RawImage>";
00430   myString +=   "<ModelRasterFormat>";
00431   myString +=     mModelRasterFormat;
00432   myString +=   "</ModelRasterFormat>";
00433   myString +=   "<ColouredImage>";
00434   myString +=     mColouredImageFileName;
00435   myString +=   "</ColouredImage>";
00436   myString += "</OutputImages>";
00437   myString += "<WorkingDirectory>";
00438   myString +=   mWorkDir;
00439   myString += "</WorkingDirectory>";
00440   myString += "<Definition>";
00441   myString +=   mModelDefinition;
00442   myString += "</Definition>";
00443   myString += "<NormalizationDefinition>";
00444   myString +=   mNormalizationDefinition;
00445   myString += "</NormalizationDefinition>";
00446   myString += "<Stats ";
00447   myString +=   "RocScore=\"" + QString::number(mRocScore) + "\" " ;
00448   myString +=   "Accuracy=\"" + QString::number(mAccuracy) + "\" " ;
00449   myString +=   "Omission=\"" + QString::number(mOmission) + "\" " ;
00450   myString +=   "Commission=\"" + QString::number(mCommission) + "\" " ;
00451   myString +=   "PercentCellsPresent=\"" + QString::number(mPercentCellsPresent) + "\" " ;
00452   myString +=   "TotalCells=\"" + QString::number(mTotalCells) + "\">";
00453   myString += "  <RocStats>";
00454   QListIterator< QPair <double,double> > myIterator (mRocPoints);
00455   while (myIterator.hasNext())
00456   {
00457     QPair<double,double> myPair = myIterator.next();
00458     myString += "  <RocPoint x=\"" + QString::number(myPair.first) + "\" " + 
00459                             "y=\"" + QString::number(myPair.second) + "\"/>";
00460   }
00461   myString += "  </RocStats>";
00462   myString += "</Stats>";
00463   myString += "<Log>";
00464   myString +=   mModelLog;
00465   myString += "</Log>";
00466   myString += "</Model>\n";
00467   return myString;
00468 }
00469 QString OmgModel::toModelCreationXml() const 
00470 {
00471   //QString myString("<ModelParameters xmlns=\"http://openmodeller.cria.org.br/xml/1.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://openmodeller.cria.org.br/xml/1.0 http://openmodeller.cria.org.br/xml/1.0/openModeller.xsd\">\n");
00472   //
00473   // Options
00474   //
00475   QString myString = "<Options>\n";
00476   myString += "  <OccurrencesFilter>\n";
00477   if (mLocalitiesFilterType==NO_FILTER)
00478   {
00479     //add nothing
00480   }
00481   else if(mLocalitiesFilterType==SPATIALLY_UNIQUE)
00482   {
00483     myString += "      <SpatiallyUnique/>\n";
00484   }
00485   else //environmentally unique
00486   {
00487     myString += "      <EnvironmentallyUnique/>\n";
00488   }
00489   myString += "    </OccurrencesFilter>\n";
00490   myString += "  </Options>\n";
00491 
00492   //
00493   // Sampler
00494   // 
00495 
00496   myString += "  <Sampler>\n";
00497   myString+=mCreationLayerSet.toXml();
00498   
00499   //
00500   // Presences
00501   //
00502   
00503   myString+=QString("    <Presence Label=\""+mTaxonName+"\">\n");
00504   myString+=QString("      <CoordinateSystem>\n");
00505   myString+=QString("         "+mCoordinateSystem+"\n");
00506   myString+=QString("      </CoordinateSystem>\n");
00507   //loop through all the localities
00508   bool myHasAbsencesFlag=false;
00509   for (int i=0;i<mLocalities.count();i++)
00510   {
00511     OmgLocality myLocality = mLocalities.at(i);
00512     if ( myLocality.abundance() > 0 )
00513     {
00514       myString+=myLocality.toXml();
00515     }
00516     else
00517     {
00518       myHasAbsencesFlag=true;
00519     }
00520   }
00521   myString+=QString("      </Presence>\n");
00522   
00523   //
00524   // Absences
00525   //
00526   
00527   if (myHasAbsencesFlag)
00528   {
00529     myString+=QString("    <Absence Label=\""+mTaxonName+"\">\n");
00530     myString+=QString("      <CoordinateSystem>\n");
00531     myString+=QString("         "+mCoordinateSystem+"\n");
00532     myString+=QString("      </CoordinateSystem>\n");
00533     //loop through all the localities
00534     for (int i=0;i<mLocalities.count();i++)
00535     {
00536       OmgLocality myLocality = mLocalities.at(i);
00537       if (myLocality.abundance() <= 0)
00538       {
00539         myString+=myLocality.toXml();
00540       }
00541     }
00542     myString+=QString("      </Absence>\n");
00543   }
00544   //
00545   // finish up
00546   //
00547   
00548   myString+=QString("  </Sampler>\n");
00549   myString+=mAlgorithm.toModelCreationXml();
00550   //myString+=QString("</ModelParameters>\n");
00551   return myString;
00552 }
00553 QString OmgModel::toModelProjectionXml() const
00554 {
00555   /* We are trying to make something like this
00556    * the outer projectionparameters tag will be added by the soap
00557    * libary, or the local modeler plugin.
00558    *
00559   <ProjectionParameters
00560     xmlns="http://openmodeller.cria.org.br/xml/1.0">
00561     <Algorithm Id="Bioclim" Version="0.2">
00562     <Parameters>
00563     <Parameter Id="StandardDeviationCutoff" Value="0.7"/></Parameters>
00564     <Model>
00565     <Bioclim Mean="221.6 2375.984008789062" StdDev="93.9951700886806
00566     184.4701277015361" Minimum="90 1911.670043945312" Maximum="413
00567     2565.010009765625"/></Model></Algorithm>
00568     <Environment NumLayers="2">
00569     <Map
00570     Id="/home/renato/projects/openmodeller/examples/layers/rain_coolest"
00571     IsCategorical="0" Min="0" Max="2137"/>
00572     <Map Id="/home/renato/projects/openmodeller/examples/layers/temp_avg"
00573     IsCategorical="0" Min="-545.4199829101562" Max="3342.52001953125"/>
00574     <Mask
00575     Id="/home/renato/projects/openmodeller/examples/layers/rain_coolest"/>
00576     </Environment>
00577     <OutputParameters FileType="DoubleingTiff">
00578     <TemplateLayer
00579     Id="/home/renato/projects/openmodeller/examples/layers/rain_coolest"/>
00580     </OutputParameters>
00581    </ProjectionParameters>
00582    */
00583    QString myString=mAlgorithm.toModelProjectionXml(mModelDefinition,mNormalizationDefinition);
00584    myString+=mProjectionLayerSet.toXml();
00585    myString+="\n<OutputParameters FileType=\"" + mModelRasterFormat + "\">";
00586    myString+="\n<TemplateLayer Id=\"" + mOutputFormatLayer.name() + "\"/>";  
00587    myString+="\n</OutputParameters>";
00588    return myString;
00589 }  
00590 QString OmgModel::projectionLayersXml() 
00591 {
00592   return mProjectionLayerSet.toXml();
00593 }
00594 
00595 QString OmgModel::toHtml(bool theForceFlag) const
00596 {
00597   //make sure the working dir for the expreiment exists
00598   QDir myWorkDir(mWorkDir);
00599   //QString.replace() is destructive so make a copy first
00600   QString myTaxonName = mTaxonName;
00601   myTaxonName.replace(" ","_");
00602   QString myOutputFileName(mWorkDir + "/" + myTaxonName + "_report.html");
00603   if (!myWorkDir.exists())
00604   {
00605     qDebug(QObject::tr("Working directory does not exist...html not saved"));
00606     return "";
00607   }
00608   else //save it out to file
00609   {
00610     qDebug(QObject::tr("Saving experiment report as html"));
00611     if (QFile::exists(myOutputFileName) && !theForceFlag)
00612     return myOutputFileName;
00613   }
00614   QString myAlgorithmParameters = mAlgorithm.toHtml();
00615   QString myStatsString;
00616   myStatsString += "<p>" + QObject::tr("Area Under Curve (AUC): ") +
00617      QString::number( mRocScore,'f',2 ) + "<br />\n";
00618   myStatsString += QObject::tr("Accuracy : ") +
00619      QString::number( mAccuracy ) + QObject::tr("% (using 50% threshold)") + "<br />\n";
00620   myStatsString += QObject::tr("Omission error : ") +
00621      QString::number( mOmission ) + QObject::tr("% (using 50% threshold)") + "<br />\n";
00622   //only valid for models with absence data
00623   myStatsString += QString( "Commission error : ");
00624      QString::number( mCommission ) + QObject::tr("% (using 50% threshold)") + "<br />\n";
00625   myStatsString += QObject::tr("Percentage of cells predicted present : ") 
00626     + QString::number ( mPercentCellsPresent ) + "%<br />\n";
00627   myStatsString += QObject::tr("Total number of cells : ")
00628     + QString::number( mTotalCells ) + "</p>\n";
00629   //make an image of the roc curve
00630   myStatsString+= QString("<h3 align=\"center\" class=\"glossy\"><a name=\"roc_curve\"></a>" + QObject::tr("ROC Curve:") + "</h3>\n");
00631   createRocGraph(theForceFlag);
00632   myStatsString+=QString("<p><img src=\"" + myTaxonName + "_roc_curve.png\"></p>\n");
00633   //make a table of the roc curve
00634   myStatsString += "<table class=\"rocTable\">\n"; //qt 4.3 seems to ignore table css
00635   QString myCounterString("<tr>\n");
00636   myCounterString += "<th class=\"glossy\">" + QObject::tr("No.") + "\n";
00637   myCounterString += "</th>\n";
00638   QString myXString ("<tr>\n");
00639   myXString += "<th>X\n";
00640   myXString += "</th>\n";
00641   QString myYString ("<tr>\n");
00642   myYString += "<th>Y\n";
00643   myYString += "</th>\n";
00644   unsigned int myCounter = 1;
00645   bool myAlternateCell=false; //for highlighting every other row
00646   QListIterator< QPair <double,double> > myRocIterator (mRocPoints);
00647   while (myRocIterator.hasNext())
00648   {
00649     QPair<double,double> myPair = myRocIterator.next();
00650     myCounterString += "<td class=\"glossy\">" + QString::number(myCounter) + "</td>\n";
00651     QString myTd;
00652     if (myAlternateCell)
00653     {
00654       myTd = "<td>"; 
00655       myAlternateCell=false;
00656     }
00657     else
00658     {
00659       myTd = "<td class=\"alternateCell\">"; 
00660       myAlternateCell=true;
00661     }
00662     myXString += myTd + QString::number(myPair.first,'f',3) + " </td>\n";
00663     myYString += myTd + QString::number(myPair.second,'f',3) + " </td>\n";
00664 
00665     ++myCounter;
00666   }
00667   myCounterString += "</tr>\n";
00668   myXString += "</tr>\n";
00669   myYString += "</tr>\n";
00670   myStatsString += myCounterString; 
00671   myStatsString += myXString;
00672   myStatsString += myYString; 
00673   myStatsString += "</table>\n";
00674 
00675   //
00676   // make a histogram of the distribution of probabilities
00677   // 
00678   myStatsString+="<br/>\n";
00679   QFileInfo myRasterFileInfo(workDir() + rawImageFileName());
00680   if (!myRasterFileInfo.exists())
00681   {
00682     qDebug("Model projection does not exist, no raster related summary will be generated");
00683   }
00684   else if (100==1) //disable for now
00685   {
00686     myStatsString+=QString("  <h3 align=\"center\" class=\"glossy\"><a name=\"probability_dist\"></a>" + QObject::tr("Distribution of probabilities:") + "</h3>\n");
00687 
00688     QgsRasterLayer * mypRasterLayer = new QgsRasterLayer(myRasterFileInfo.filePath(), 
00689       myRasterFileInfo.completeBaseName());
00690     const int myBinCount=10;
00691     bool myIgnoreOutOfRangeFlag=true;
00692     bool myThoroughBandScanFlag=true;
00693     const int myCurrentBand=1; //base 1!
00694     const int myUpperThreshold=254; //we will ignore eny value over this
00695     const int myLowerThreshold=0; //we will ignore eny value under this
00696     OmgDataSeries myRasterSeries;
00697     myRasterSeries.setLabel("Probability");
00698 
00699     mypRasterLayer->populateHistogram(myCurrentBand,myBinCount,myIgnoreOutOfRangeFlag,myThoroughBandScanFlag); 
00700     QgsRasterBandStats myRasterBandStats = mypRasterLayer->getRasterBandStats(myCurrentBand);
00701     for (int myBin = 0; myBin < myBinCount; myBin++)
00702     {
00703       double myValue = static_cast<double> ( myRasterBandStats.histogramVector->at(myBin) );
00704       if (myValue <= myUpperThreshold && myValue >= myLowerThreshold)
00705       {
00706         //myValue = 0;
00707         continue;
00708       }
00709       myRasterSeries << myValue;
00710     }
00711     QImage myRasterImage = QImage( 400,400,QImage::Format_ARGB32 );
00712     myRasterImage.fill(Qt::white);
00713     QPainter myRasterPainter ( &myRasterImage );
00714     OmgGraph myRasterGraph(&myRasterPainter);
00715     myRasterSeries.setFillColor(Qt::red);
00716     myRasterSeries.setLineColor(Qt::darkGray);
00717     myRasterGraph.addSeries(myRasterSeries);
00718     myRasterGraph.setVerticesEnabled(false);
00719     myRasterGraph.setVertexLabelsEnabled(false);
00720     myRasterGraph.setAreaFillEnabled(true);
00721     myRasterGraph.setSpliningEnabled(false);
00722     myRasterGraph.setGridLinesEnabled(true);
00723     myRasterGraph.render();
00724     myRasterImage.save(mWorkDir + "/" + myTaxonName + "_probability_histogram.png");
00725     myStatsString+=QString("  <p><img src=\"" + myTaxonName + "_probability_histogram.png\"></p>\n");
00726     //show other raster stats
00727     myStatsString+=QString("  <h3 align=\"center\" class=\"glossy\"><a name=\"probability_dist\"></a>" + QObject::tr("Output Projection Raster Properties:") + "</h3>\n");
00728     myStatsString += "<p>" + mypRasterLayer->getMetadata() + "</p>";
00729     //continue on with the rest of the report now.
00730   }
00731 
00732   //
00733   // Main report starts here
00734   //
00735   QString myString;
00736   myString+=Omgui::getHtmlHeader();
00737   myString+=QString("  <br/>\n");
00738   myString+=QString("  <table border=\"0\">\n");
00739   myString+=QString("  <tr>\n");
00740   myString+=QString("    <td rowspan=\"9\"><img src=\""+mThumbnailFileName+"\"></td>\n");
00741   myString+=QString("    <td rowspan=\"9\">&nbsp;&nbsp;</td>\n");
00742   myString+=QString("    <td colspan=\"2\"><h1>" + 
00743       QObject::tr("openModeller Model Report") + "</h1>\n</td>\n");
00744   myString+=QString("  </tr>\n\n");
00745   myString+=QString("  <tr>\n");
00746   myString+=QString("    <td class=\"headerCell\"> " + QObject::tr("Taxon:") + "</td>\n");
00747   myString+=QString("    <td class=\"largeCell\"><i>"+mTaxonName+"</i></td>\n");
00748   myString+=QString("  </tr>\n\n");
00749   myString+=QString("  <tr>\n");
00750   myString+=QString("    <td class=\"headerCell\"> " + QObject::tr("Algorithm:") + "</td>\n");
00751   myString+=QString("    <td class=\"largeCell\">"+mAlgorithm.name()+"</td>\n");
00752   myString+=QString("  </tr>\n\n");  
00753   myString+=QString("  <tr>\b");
00754   myString+=QString("    <td class=\"headerCell\"> " + QObject::tr("Started: ") + "</td>\n");
00755   myString+=QString("    <td class=\"largeCell\">"+mStartDateTimeStamp.toString()+"</td>\n");
00756   myString+=QString("  </tr>\n\n");
00757   myString+=QString("  <tr>\b");
00758   myString+=QString("    <td class=\"headerCell\"> " + QObject::tr("Completed: ") + "</td>\n");
00759   myString+=QString("    <td class=\"largeCell\">"+mEndDateTimeStamp.toString()+"</td>\n");
00760   myString+=QString("  </tr>\n\n");
00761   myString+=QString("  <tr>\b");
00762   myString+=QString("    <td class=\"headerCell\"> " + QObject::tr("Processing time: ") + "</td>\n");
00763   myString+=QString("    <td class=\"largeCell\">"+
00764     Omgui::secondsToString <long> (mStartDateTimeStamp.secsTo(mEndDateTimeStamp),Omgui::longTimeForm) + 
00765       "</td>\n");
00766   myString+=QString("  </tr>\n\n");
00767   myString+=QString("  <tr>\n\n");
00768   myString+=QString("    <td class=\"headerCell\"> " + QObject::tr("Raster Format: ") + "</td>\n");
00769   myString+=QString("    <td class=\"largeCell\">" +
00770     Omgui::getOutputFormatNotes().value(mModelRasterFormat) +
00771       "</td>\n");
00772   myString+=QString("  </tr>\n\n");
00773 
00774 
00775   //
00776   // Occurrence filtering options
00777   //
00778   myString +="  <tr>\n\n";
00779   myString +="    <td class=\"headerCell\"> " + 
00780       QObject::tr("Occurrence filtering: ") + "</td>\n";
00781   myString +="    <td class=\"largeCell\">";
00782   if (mLocalitiesFilterType==NO_FILTER)
00783   {
00784     myString += QObject::tr("Unfiltered");
00785   }
00786   else if(mLocalitiesFilterType==SPATIALLY_UNIQUE)
00787   {
00788     myString += QObject::tr("Spatially Unique");
00789   }
00790   else //environmentally unique
00791   {
00792     myString += QObject::tr("Environmentally Unique");
00793   }
00794   myString += "   </td>\n";
00795   myString +="  </tr>\n\n";
00796   myString+=QString("  <tr>\n");
00797   myString+=QString("    <td class=\"headerCell\"> " + QObject::tr("Model Globally Unique Identifier:") + "</td>\n");
00798   myString+=QString("    <td class=\"largeCell\">"+guid()+"</td>\n");
00799   myString+=QString("  </tr>\n\n");  
00800   myString+=QString("  </table>\n");
00801   myString+=QString("  <table>\n");
00802   myString+=QString("  <tr valign=\"top\">\n"); 
00803   myString+=QString("    <td>\n");
00804   myString+=QString("      <ul>\n");
00805   myString+=QString("        <li><a href=\"#outputmap\" > " + QObject::tr("Output map") + "</a></li>\n");
00806   myString+=QString("        <li><a href=\"#modelstats\" > " + QObject::tr("Model statistics") + "</a></li>\n");
00807   myString+=QString("      </ul>\n");
00808   myString+=QString("    </td>\n");
00809   myString+=QString("    <td>\n");
00810   myString+=QString("      <ul>\n");
00811   myString+=QString("        <li><a href=\"#algparameters\" > " + QObject::tr("Algorithm parameters") + "</a></li>\n");
00812   myString+=QString("        <li><a href=\"#creationlayers\" > " + QObject::tr("Environmental layers") + "</a></li>\n");
00813   myString+=QString("      </ul>\n");
00814   myString+=QString("    </td>\n");
00815   myString+=QString("  </tr>\n");
00816   myString+=QString("  </table>\n");
00817   myString+=QString("  <a name=\"outputmap\"></a> ");
00818   myString+=QString("  <h3 align=\"center\" class=\"glossy\">" + QObject::tr("Output map:") + "</h3>\n");
00819   myString+=QString("  <p><img src=\""+mPreviewFileName+"\"></p>\n");
00820   myString+=QString("  <p><img src=\""+mLegendFileName+"\"></p>\n");
00821   myString+=QString("  <h3 align=\"center\" class=\"glossyh3\"><a name=\"modelstats\"></a> " + QObject::tr("Output statistics:") + "</h3>\n");
00822   myString+= myStatsString + "\n";
00823   //myString+=QString("  <h3 align=\"center\" class=\"glossy\"><a name=\"modeldef\"></a>Model definition:</h3>\n"); 
00824   //myString+=QString("  <p>"+mModelDefinition+"</p>\n");
00825   myString+=QString("  <a name=\"algparameters\"></a>\n");  
00826   myString+=QString("  <p>"+myAlgorithmParameters+"</p>\n");
00827   /*
00828   myString+=QString("  <h3 align=\"center\" class=\"glossy\"><a name=\"inputlocalities\"></a> " + QObject::tr("Input localities:") + "</h3>\n");  
00829   myString+=QString("  <table border=\"1\">\n"); 
00830   myString+=QString("    <tr>\n");
00831   myString+=QString("      <th>#</th><th> " + QObject::tr("Id") + "</th><th> " + QObject::tr("Lat") + "</th><th> " + QObject::tr("Long") + "</th>");
00832   QStringListIterator myIterator(creationLayerNames());
00833   while (myIterator.hasNext())
00834   {       
00835     QFileInfo myFileInfo(myIterator.next());
00836     myString+=QString("<th>"+myFileInfo.baseName()+"</th>");
00837   }
00838   myString+="\n";
00839   myString+=QString("    </tr>\n");
00840 
00841   for (int myRow = 0; myRow < localities().size(); ++myRow) 
00842   {
00843     myString+=QString("    <tr>\n");
00844     OmgLocality myLocality = localities().at(myRow);
00845     myString += "      <td>" + QString::number(myRow) + "</td>";
00846     myString += "<td>" + myLocality.id() + "</td>";
00847     myString += "<td>" + QString::number(myLocality.longitude()) + "</td>";
00848     myString += "<td>" + QString::number(myLocality.latitude()) + "</td>";
00849     for (int myCol = 0; myCol < myLocality.samples().size(); ++myCol) 
00850     {
00851       double mySample = myLocality.samples().at(myCol);
00852       myString += "<td>" + QString::number(mySample) + "</td>";
00853     }
00854     myString+=QString("\n    </tr>\n");
00855   }
00856   myString+=QString("  </table>\n"); 
00857   */
00858   myString+=QString("  <h3 align=\"center\" class=\"glossy\"><a name=\"creationlayers\"></a> " + QObject::tr("Model Creation Layers:") + "</h3>\n");  
00859   myString+=mCreationLayerSet.toHtml(); 
00860   myString+=QString("  <h3 align=\"center\" class=\"glossy\"><a name=\"projectionlayers\"></a> " + QObject::tr("Model Projection Layers:") + "</h3>\n");  
00861   myString+=mProjectionLayerSet.toHtml();
00862   myString+=QString("  <h3 align=\"center\" class=\"glossy\"><a name=\"formatlayer\"></a> " + QObject::tr("Format Layer:") + "</h3>\n");  
00863   myString += "<p>" + mOutputFormatLayer.name() + "</p>\n";
00864   myString+=QString("  <h3 align=\"center\" class=\"glossy\"><a name=\"modellog\"></a> " + QObject::tr("Model Log") + "</h3>\n");
00865   myString+=QString("<pre>" + mModelLog + "</pre>");
00866   myString+=Omgui::getHtmlFooter();
00867   Omgui::createTextFile(myOutputFileName , myString);
00868   return myOutputFileName;
00869 }
00870 
00871 QString OmgModel::toPrintHtml(bool theForceFlag) const
00872 {
00873   //QString.replace() is destructive so make a copy first
00874   QString myTaxonName = mTaxonName;
00875   myTaxonName.replace(" ","_");
00876   QString myAlgorithmParameters = mAlgorithm.toHtml();
00877   QString myStatsString;
00878   //make an image of the roc curve
00879   myStatsString+= QString("<h3 align=\"center\" class=\"glossy\"><a name=\"roc_curve\"></a>" + QObject::tr("ROC Curve:") + "</h3>\n");
00880   createRocGraph(theForceFlag);
00881   myStatsString+=QString("<p><img src=\"" + mWorkDir + QDir::separator() +
00882       myTaxonName + "_roc_curve.png\"></p>\n");
00883   //make a table of the roc curve
00884   myStatsString += "<table class=\"rocTable\">\n";
00885   QString myCounterString("<tr>\n");
00886   myCounterString += "<th>" + QObject::tr("No.") + "\n";
00887   myCounterString += "</th>\n";
00888   QString myXString ("<tr>\n");
00889   myXString += "<th>X\n";
00890   myXString += "</th>\n";
00891   QString myYString ("<tr>\n");
00892   myYString += "<th>Y\n";
00893   myYString += "</th>\n";
00894   unsigned int myCounter = 1;
00895   QListIterator< QPair <double,double> > myRocIterator (mRocPoints);
00896   while (myRocIterator.hasNext())
00897   {
00898     QPair<double,double> myPair = myRocIterator.next();
00899     myCounterString += "<td>" + QString::number(myCounter) + "</td>\n";
00900     myXString += "<td>" + QString::number(myPair.first) + "</td>\n";
00901     myYString += "<td>" + QString::number(myPair.second) + "</td>\n";
00902     ++myCounter;
00903   }
00904   myCounterString += "</tr>\n";
00905   myXString += "</tr>\n";
00906   myYString += "</tr>\n";
00907   myStatsString += myCounterString; 
00908   myStatsString += myXString;
00909   myStatsString += myYString; 
00910   myStatsString += "</table>\n";
00911 
00912   myStatsString+="<br/>\n";
00913 
00914   //
00915   // Main report starts here
00916   //
00917   QString myString;
00918   myString+=QString("  <br/>\n");
00919   myString+=QString("  <h3 align=\"center\" class=\"glossy\">" + mTaxonName + " - " + mAlgorithm.name() + "</h3>\n");
00920   myString+=QString("  <table width=\"100%\">\n");
00921   myString+=QString("  <tr>\n");
00922   myString+=QString("    <td class=\"headerCell\"> " + QObject::tr("Taxon :") + "</td>\n");
00923   myString+=QString("    <td class=\"largeCell\"><i>"+mTaxonName+"</i></td>\n");
00924   myString+=QString("  </tr>\n\n");
00925   myString+=QString("  <tr>\n");
00926   myString+=QString("    <td class=\"headerCell\"> " + QObject::tr("Algorithm :") + "</td>\n");
00927   myString+=QString("    <td class=\"largeCell\">"+mAlgorithm.name()+"</td>\n");
00928   myString+=QString("  </tr>\n\n");  
00929   myString+=QString("  <tr>\b");
00930   myString+=QString("    <td class=\"headerCell\"> " + QObject::tr("Started: ") + "</td>\n");
00931   myString+=QString("    <td class=\"largeCell\">"+mStartDateTimeStamp.toString()+"</td>\n");
00932   myString+=QString("  </tr>\n\n");
00933   myString+=QString("  <tr>\b");
00934   myString+=QString("    <td class=\"headerCell\"> " + QObject::tr("Completed : ") + "</td>\n");
00935   myString+=QString("    <td class=\"largeCell\">"+mEndDateTimeStamp.toString()+"</td>\n");
00936   myString+=QString("  </tr>\n\n");
00937   myString+=QString("  <tr>\b");
00938   myString+=QString("    <td class=\"headerCell\"> " + QObject::tr("Processing time : ") + "</td>\n");
00939   myString+=QString("    <td class=\"largeCell\">"+
00940     Omgui::secondsToString <long> (mStartDateTimeStamp.secsTo(mEndDateTimeStamp),Omgui::longTimeForm) + 
00941       "</td>\n");
00942   myString+=QString("  </tr>\n\n");
00943   myString+=QString("  <tr>\b");
00944   myString+=QString("    <td class=\"headerCell\"> " + QObject::tr("Raster Format: ") + "</td>\n");
00945   myString+=QString("    <td class=\"largeCell\">" +
00946     Omgui::getOutputFormatNotes().value(mModelRasterFormat) + 
00947       "</td>\n");
00948   myString+=QString("  </tr>\n\n");
00949 
00950   myString+=QString("  <tr>\b");
00951   myString+=QString("    <td class=\"headerCell\"> " + QObject::tr("Area Under Curve (AUC) : ") + "</td>\n");
00952   myString+=QString("    <td class=\"largeCell\">"+ QString::number( mRocScore,'f',2 )
00953       + "</td>\n");
00954   myString+=QString("  </tr>\n\n");
00955 
00956   myString+=QString("  <tr>\b");
00957   myString+=QString("    <td class=\"headerCell\"> " + QObject::tr("Accuracy : ") + "</td>\n");
00958   myString+=QString("    <td class=\"largeCell\">" + QString::number( mAccuracy ) + "%"
00959       + QObject::tr(" (using 50% threshold)")
00960       + "</td>\n");
00961   myString+=QString("  </tr>\n\n");
00962   
00963   myString+=QString("  <tr>\b");
00964   myString+=QString("    <td class=\"headerCell\"> " + QObject::tr("Omission error : ") + "</td>\n");
00965   myString+=QString("    <td class=\"largeCell\">" + QString::number( mOmission )
00966       + QObject::tr(" (using 50% threshold)")
00967       + "</td>\n");
00968   myString+=QString("  </tr>\n\n");
00969   
00970   myString+=QString("  <tr>\b");
00971   myString+=QString("    <td class=\"headerCell\"> " + QObject::tr("Commission error : ") + "</td>\n");
00972   myString+=QString("    <td class=\"largeCell\">" + QString::number( mCommission ) + "%" 
00973       + QObject::tr(" (using 50% threshold)")
00974       + "</td>\n");
00975   myString+=QString("  </tr>\n\n");
00976   
00977   myString+=QString("  <tr>\b");
00978   myString+=QString("    <td class=\"headerCell\"> " + QObject::tr("Cells predicted present : ") + "</td>\n");
00979   myString+=QString("    <td class=\"largeCell\">" + QString::number ( mPercentCellsPresent ) + "%"
00980       + "</td>\n");
00981   myString+=QString("  </tr>\n\n");
00982   
00983   myString+=QString("  <tr>\b");
00984   myString+=QString("    <td class=\"headerCell\"> " + QObject::tr("Total number of cells : ") + "</td>\n");
00985   myString+=QString("    <td class=\"largeCell\">" + QString::number( mTotalCells )
00986       + "</td>\n");
00987   myString+=QString("  </tr>\n\n");
00988   
00989   myString+=QString("  <tr>\b");
00990   myString+=QString("    <td class=\"headerCell\"> " + QObject::tr("Model Creation Layerset : ") + "</td>\n");
00991   myString+=QString("    <td class=\"largeCell\">" + mCreationLayerSet.name() + "</td>\n");
00992   myString+=QString("  </tr>\n\n");
00993   myString+=QString("  <tr>\b");
00994   myString+=QString("    <td class=\"headerCell\"> " + QObject::tr("Model Projection Layerset : ") + "</td>\n");
00995   myString+=QString("    <td class=\"largeCell\">" + mProjectionLayerSet.name() + "</td>\n");
00996   myString+=QString("  </tr>\n\n");
00997   myString+=QString("  <tr>\b");
00998   myString+=QString("    <td class=\"headerCell\"> " + QObject::tr("Format Layer : ") + "</td>\n");
00999   QString myName = mOutputFormatLayer.name();
01000   myName.replace("\\"," \\"); //for word wrapping in cell
01001   myName.replace("/"," /"); //for word wrapping in cell
01002   myString+=QString("    <td class=\"largeCell\">" + myName + "</td>\n");
01003   myString+=QString("  </tr>\n\n");
01004   myString+=QString("  </table>\n");
01005   myString+=QString("  <a name=\"outputmap\"></a> ");
01006   myString+=QString("  <h3 align=\"center\" class=\"glossy\">" + QObject::tr("Output map:") + "</h3>\n");
01007   myString+=QString("  <p><img src=\""+ mWorkDir + QDir::separator() +mPreviewFileName+"\"></p>\n");
01008   myString+=QString("  <p><img src=\""+ mWorkDir + QDir::separator() +mLegendFileName+"\"></p>\n");
01009   myString+=QString("  <h3 align=\"center\" class=\"glossy\">" + QObject::tr("Output statistics:") + "</h3>\n");
01010   myString+= myStatsString + "\n";
01011   return myString;
01012 }
01013 
01014 void OmgModel::createRocGraph(bool theForceFlag) const 
01015 {
01016   QImage myImage = QImage( 200,200,QImage::Format_ARGB32 );
01017   myImage.fill(Qt::white);
01018   QPainter myPainter ( &myImage );
01019   OmgGraph myGraph(&myPainter);
01020   OmgDataSeries mySeries = getRocPoints();
01021   mySeries.setLineColor(Qt::darkGray);
01022   mySeries.setFillColor(QColor("#3087d3"));
01023   myGraph.addSeries(mySeries);
01024   myGraph.setVerticesEnabled(false);
01025   myGraph.setVertexLabelsEnabled(false);
01026   myGraph.setAreaFillEnabled(true);
01027   myGraph.setSpliningEnabled(false);
01028   myGraph.setGridLinesEnabled(true);
01029   myGraph.setDiagonalEnabled();
01030   myGraph.render();
01031   QString myTaxonName = mTaxonName;
01032   myTaxonName.replace(" ","_");
01033   QString myFileName = mWorkDir + QDir::separator() + myTaxonName + "_roc_curve.png";
01034   qDebug ("Saving roc graph to " + myFileName.toLocal8Bit());
01035   myImage.save(myFileName,"PNG");
01036 }
01037 
01038 
01039 void OmgModel::addRocPoint( QPair <double,double> thePair )
01040 {
01041   mRocPoints << thePair;
01042 }
01043 
01044 void OmgModel::clearRocPoints()
01045 {
01046   mRocPoints.clear();
01047 }
01048 
01049 OmgDataSeries OmgModel::getRocPoints() const
01050 {
01051   OmgDataSeries mySeries;
01052   mySeries.setLabel( QObject::tr("Roc Curve") );
01053   QListIterator< QPair <double,double> > myIterator (mRocPoints);
01054   while (myIterator.hasNext())
01055   {
01056          QPair<double,double> myPair = myIterator.next();
01057          mySeries << myPair;
01058   }
01059   return mySeries;
01060 }
01061 
01062 void OmgModel::setModelRasterFormat(QString theFormat)
01063 {
01064   //check that its a valid format
01065   if (Omgui::getOutputFormats().contains(theFormat))
01066   {
01067     mModelRasterFormat=theFormat;
01068   }
01069   else
01070   {
01071     qDebug("Attempting to set model format to an invalid format"
01072         "...using default GreyTiff");
01073   }
01074 
01075 }
01076 QString OmgModel::modelRasterFormat() const
01077 {
01078   return mModelRasterFormat;
01079 }
01080 
01081 QString OmgModel::localitiesToCsv(QString theDelimiter) const
01082 {
01083   QString myString= "#Num,Lat,Long";
01084   QStringListIterator myIterator(creationLayerNames());
01085   while (myIterator.hasNext())
01086   {       
01087     QFileInfo myFileInfo(myIterator.next());
01088     myString+=QString(","+myFileInfo.baseName());
01089   }
01090   for (int myRow = 0; myRow < localities().size(); ++myRow) 
01091   {
01092     myString+="\n";
01093     OmgLocality myLocality = localities().at(myRow);
01094     myString += myLocality.id() + theDelimiter;
01095     myString += QString::number(myLocality.longitude()) + theDelimiter;
01096     myString += QString::number(myLocality.latitude()) ;
01097     for (int myCol = 0; myCol < myLocality.samples().size(); ++myCol) 
01098     {
01099       double mySample = myLocality.samples().at(myCol);
01100       myString += theDelimiter + QString::number(mySample);
01101     }
01102   }
01103   return myString;
01104 }
01105 
01106 bool OmgModel::toShapefile(QString theShapefileName) const
01107 {
01108   return Omgui::localitiesToShapefile(theShapefileName,mLocalities);
01109 }
01110 //mutators
01111 
01112 void OmgModel::setLocalities(OmgLocalities theLocalities)
01113 {
01114    mLocalities = theLocalities; 
01115 }
01116 
01117 void OmgModel::setCoordinateSystem(const QString theCoordinateSystem)
01118 {
01119   mCoordinateSystem = theCoordinateSystem;
01120 }
01121 void OmgModel::setCoordinateSystemName (const QString theName)
01122 {
01123   mCoordinateSystemName = theName;
01124 }
01125 
01126 void OmgModel::setSpeciesFile(const QString theSpeciesFile)
01127 {
01128   mSpeciesFile = theSpeciesFile;
01129 }
01130 void OmgModel::setShapefileName(const QString theShapefileName)
01131 {
01132   QFileInfo myFileInfo(theShapefileName);
01133   mShapefileName = myFileInfo.fileName();
01134 }
01135 void OmgModel::setCsvFileName(const QString theCsvFileName)
01136 {
01137   QFileInfo myFileInfo(theCsvFileName);
01138   mCsvFileName = myFileInfo.fileName();
01139 }
01140 void OmgModel::setLocalitiesFilterType(LocalitiesFilterType theFilterType)
01141 {
01142   mLocalitiesFilterType = theFilterType;
01143 }
01144 OmgModel::LocalitiesFilterType OmgModel::localitiesFilterType() const
01145 {
01146   return mLocalitiesFilterType;
01147 }
01148 
01149 unsigned int OmgModel::loadLocalities()
01150 {
01151   unsigned int myCounter=0;
01152   //
01153   // NOTE the code below deuplicates from a bunch of code in omgmodeldesigner
01154   // the logic should rather be moved into a shared place - perhaps omgspeciesfile
01155   //
01156 
01157   //
01158   // Now that we have the localities text file, we need to parse it and find
01159   //
01160   //first creation a regex to match text at the beginning of the line
01161   QRegExp myQRegExp( "^[^#][ a-zA-Z]*" ); //second caret means 'not'
01162   QFile myQFile( mSpeciesFile );
01163   if ( myQFile.open( QIODevice::ReadOnly ) )
01164   {
01165     mLocalities.clear();
01166     //now we parse the loc file, checking each line for its taxon
01167     QTextStream myQTextStream( &myQFile );
01168     QString myCurrentLine;
01169     while ( !myQTextStream.atEnd() )
01170     {
01171       myCurrentLine = myQTextStream.readLine(); // line of text excluding '\n'
01172       //split on word boundaries ignoring empty parts
01173       QStringList myList = myCurrentLine.split(QRegExp("[\t]"));
01174       //qDebug("Read line : " + myList.join(" -- ").toLocal8Bit());
01175       if (myCurrentLine.startsWith("#"))
01176       {
01177         continue;
01178       }
01179       if (myList.size() < 4)
01180       {
01181         continue;
01182       }
01183       else //new 'proper' format file that has #id \t species name \t lon \t lat
01184       {
01185         QString myId=myList.at(0).simplified();
01186         QString myTaxonName=myList.at(1).simplified();
01187         //make sure there are only single spaces separating words.
01188         myTaxonName=myTaxonName.replace( QRegExp(" {2,}"), " " );
01189         //if this taxon name matches, add its locality to the localites collection
01190         if (myTaxonName==mTaxonName)
01191         {
01192           OmgLocality myLocality;
01193           myLocality.setId(myId);
01194           myLocality.setLabel(myTaxonName);
01195           myLocality.setLongitude(myList.at(2).simplified().toDouble());
01196           myLocality.setLatitude(myList.at(3).simplified().toDouble());
01197           if (myList.size()>4) //abundance
01198           {
01199             myLocality.setAbundance(myList.at(4).simplified().toDouble());
01200           }
01201           if (myLocality.isValid())
01202           {
01203             ++myCounter;
01204             mLocalities.push_back(myLocality);
01205           }
01206         }
01207       }
01208     }
01209     myQFile.close();
01210   }
01211   else
01212   {
01213     //qDebug("An error occurred in OmgModel while trying to load the localities");
01214     return myCounter;
01215   }
01216   return myCounter;
01217 }
01218 
01219 void OmgModel::setTaxonName(const QString theName)
01220 {
01221   mTaxonName = theName;
01222 }
01223 
01224 void OmgModel::setCreationLayerSet(OmgLayerSet theLayerSet)
01225 {
01226   mCreationLayerSet=theLayerSet;
01227 }
01228 void OmgModel::setProjectionLayerSet(OmgLayerSet theLayerSet)
01229 {
01230   mProjectionLayerSet=theLayerSet;
01231 }
01232 void OmgModel::setcreationMaskLayerName(QString theName)
01233 {
01234   //qDebug("setcreationMaskLayerName " + theName.toLocal8Bit());
01235   OmgLayer myLayer;
01236   myLayer.setName(theName);
01237   myLayer.setCategorical(false);
01238   mCreationLayerSet.setMask(myLayer); 
01239 }
01240 void OmgModel::setProjectionMaskLayerName(QString theName)
01241 {
01242   //qDebug("setProjectMaskLayerName " + theName.toLocal8Bit());
01243   OmgLayer myLayer;
01244   myLayer.setName(theName);
01245   myLayer.setCategorical(false);
01246   mProjectionLayerSet.setMask(myLayer); 
01247 }
01248 void OmgModel::setOutputFormatLayerName(QString theName)
01249 {
01250   //qDebug("setOutputFormatLayerName " + theName.toLocal8Bit());
01251   mOutputFormatLayer.setName(theName);
01252   mOutputFormatLayer.setCategorical(false);
01253 }
01254 void OmgModel::setCreationLayerNames(QStringList theNames)
01255 {
01256   //qDebug("setCreationLayerNames " + theNames.join(",").toLocal8Bit());
01257   QStringListIterator myIterator(theNames);
01258   while (myIterator.hasNext())
01259   {
01260     QString myString = myIterator.next();
01261     OmgLayer myLayer;
01262     myLayer.setName(myString);
01263     myLayer.setCategorical(false);
01264     mCreationLayerSet.addLayer(myLayer);
01265   }
01266 }
01267 void OmgModel::setProjectionLayerNames(QStringList theNames)
01268 {
01269   //qDebug("setCreationLayerNames" + theNames.join(",").toLocal8Bit());
01270   QStringListIterator myIterator(theNames);
01271   while (myIterator.hasNext())
01272   {
01273     QString myString = myIterator.next();
01274     OmgLayer myLayer;
01275     myLayer.setName(myString);
01276     myLayer.setCategorical(false);
01277     mProjectionLayerSet.addLayer(myLayer);
01278   }
01279 }
01280 void OmgModel::setAlgorithm(OmgAlgorithm theAlgorithm)
01281 {
01282   //qDebug("setAlgorithm" + theAlgorithm.name().toLocal8Bit());
01283   mAlgorithm = theAlgorithm;
01284 }
01285 void OmgModel::setError(bool theFlag)
01286 {
01287   mErrorFlag=theFlag;
01288 }
01289 void OmgModel::setCompleted(bool theFlag)
01290 {
01291   mCompletedFlag=theFlag;
01292 }
01293 void OmgModel::setStartDateTimeStamp(QDateTime theDateTimeStamp)
01294 {
01295   mStartDateTimeStamp=theDateTimeStamp; 
01296 }
01297 void OmgModel::setEndDateTimeStamp(QDateTime theDateTimeStamp)
01298 {
01299   mEndDateTimeStamp=theDateTimeStamp; 
01300 }
01301 void OmgModel::setThumbnailFileName(QString theFileName)
01302 {
01303   QFileInfo myFileInfo(theFileName);
01304   mThumbnailFileName=myFileInfo.fileName();
01305 }
01306 void OmgModel::setPreviewFileName(QString theFileName)
01307 {
01308   QFileInfo myFileInfo(theFileName);
01309   mPreviewFileName=myFileInfo.fileName();
01310 }
01311 void OmgModel::setLegendFileName(QString theFileName)
01312 {
01313   QFileInfo myFileInfo(theFileName);
01314   mLegendFileName=myFileInfo.fileName();
01315 }
01316 void OmgModel::setRawImageFileName(QString theFileName)
01317 {
01318   QFileInfo myFileInfo(theFileName);
01319   mRawImageFileName=myFileInfo.fileName();
01320 }
01321 void OmgModel::setColouredImageFileName(QString theFileName)
01322 {
01323   QFileInfo myFileInfo(theFileName);
01324   mColouredImageFileName=myFileInfo.fileName();
01325 }
01326 
01327 void OmgModel::setWorkDir(QString theDir)
01328 {
01329   //ensure we have a dir and an ending slash
01330   QFileInfo myFileInfo(theDir);
01331   mWorkDir=myFileInfo.absoluteFilePath() + QDir::separator();
01332 }
01333 
01334 void OmgModel::setRocScore(double theRocScore)
01335 {
01336   mRocScore=theRocScore;
01337 }
01338 void OmgModel::setAccuracy(double theAccuracy)
01339 {
01340   mAccuracy=theAccuracy;
01341 }
01342 void OmgModel::setOmission(double theOmission)
01343 {
01344   mOmission=theOmission;
01345 }
01346 void OmgModel::setCommission(double theCommission)
01347 {
01348   mCommission=theCommission;
01349 }
01350 void OmgModel::setPercentCellsPresent(double thePercent )
01351 {
01352   mPercentCellsPresent=thePercent;
01353 }
01354 void OmgModel::setTotalCells(double theTotal)
01355 {
01356   mTotalCells=theTotal;
01357 }
01358 void OmgModel::setModelDefinition(QString theDefinition)
01359 {
01360   mModelDefinition = theDefinition;
01361 }
01362 
01363 void OmgModel::setNormalizationDefinition(QString theDefinition)
01364 {
01365   mNormalizationDefinition = theDefinition;
01366 }
01367 void OmgModel::appendToLog(QString theMessage)
01368 {
01369   mModelLog += theMessage + "\n";
01370 }
01371 
01372 void OmgModel::setLog(QString theLog)
01373 {
01374   mModelLog = theLog;
01375 }
01376 //accessors
01377 
01378 OmgLocalities OmgModel::localities() const
01379 {
01380   return mLocalities;
01381 }
01382 QString OmgModel::coordinateSystem() const
01383 {
01384   return mCoordinateSystem;
01385 }
01386 
01387 QString OmgModel::coordinateSystemName() const
01388 {
01389   return mCoordinateSystemName;
01390 }
01391 
01392 QString OmgModel::speciesFile() const
01393 {
01394   return mSpeciesFile;
01395 }
01396 
01397 QString OmgModel::shapefileName() const
01398 {
01399   QFileInfo myFileInfo(mShapefileName);
01400   QString myFileName=myFileInfo.fileName();
01401   return myFileName;
01402 }
01403 
01404 QString OmgModel::csvFileName() const
01405 {
01406   return mCsvFileName;
01407 }
01408 
01409 QString OmgModel::taxonName() const
01410 {
01411   return mTaxonName;
01412 }
01413 
01414 OmgLayerSet OmgModel::creationLayerSet() const
01415 {
01416   return mCreationLayerSet; 
01417 }
01418 OmgLayerSet OmgModel::projectionLayerSet() const
01419 {
01420   return mProjectionLayerSet;
01421 }
01422 QString OmgModel::creationMaskLayerName() const
01423 {
01424   return mCreationLayerSet.maskName();
01425 }
01426 QString OmgModel::projectionMaskLayerName() const
01427 {
01428   return mProjectionLayerSet.maskName();
01429 }
01430 QString OmgModel::outputFormatLayerName() const
01431 {
01432   return mOutputFormatLayer.name();
01433 }
01434 QStringList OmgModel::creationLayerNames() const
01435 {
01436   return mCreationLayerSet.nameList();
01437 }
01438 QStringList OmgModel::projectionLayerNames() const
01439 {
01440   return mProjectionLayerSet.nameList();
01441 }
01442 OmgAlgorithm OmgModel::algorithm() const
01443 {
01444   return mAlgorithm;
01445 }
01446 bool OmgModel::hasError() const
01447 {
01448   return mErrorFlag;
01449 }
01450 bool OmgModel::isCompleted() const
01451 {
01452   return mCompletedFlag;
01453 }
01454 QDateTime OmgModel::startDateTimeStamp() const
01455 {
01456   return mStartDateTimeStamp;
01457 }
01458 QDateTime OmgModel::endDateTimeStamp() const
01459 {
01460   return mEndDateTimeStamp;
01461 }
01462 QString OmgModel::thumbnailFileName() const
01463 {
01464   return mThumbnailFileName;
01465 }
01466 QString OmgModel::previewFileName() const
01467 {
01468   return mPreviewFileName;
01469 }
01470 QString OmgModel::legendFileName() const
01471 {
01472   return mLegendFileName;
01473 }
01474 QString OmgModel::rawImageFileName() const
01475 {
01476   // This if test seems refundant but I was
01477   // getting a crash before adding it
01478   if (!mRawImageFileName.isEmpty())
01479   {
01480     return mRawImageFileName;
01481   }
01482   else
01483   {
01484     return QString();
01485   }
01486 }
01487 QString OmgModel::colouredImageFileName() const
01488 {
01489   return mColouredImageFileName;
01490 }
01491 
01492 QString OmgModel::workDir() const
01493 {
01494   return mWorkDir;
01495 }
01496 double OmgModel::rocScore() const
01497 {
01498   return mRocScore; 
01499 }
01500 double OmgModel::accuracy() const
01501 {
01502   return mAccuracy; 
01503 }
01504 double OmgModel::omission() const
01505 {
01506   return mOmission; 
01507 }
01508 double OmgModel::commission() const
01509 {
01510   return mCommission; 
01511 }
01512 double OmgModel::percentCellsPresent() const
01513 {
01514  return mPercentCellsPresent; 
01515 }
01516 double OmgModel::totalCells() const
01517 {
01518  return mTotalCells; 
01519 }
01520 
01521 QString OmgModel::modelDefinition() const
01522 {
01523   return mModelDefinition;
01524 }
01525 
01526 QString OmgModel::normalizationDefinition() const
01527 {
01528   return mNormalizationDefinition;
01529 }
01530 
01531 QString OmgModel::modelLog() const
01532 {
01533   return mModelLog;
01534 }
01535 
01536 void OmgModel::createThumbnail()
01537 {
01538   //
01539   // now get a thumbnail of the projection image and paste it into our
01540   // painter
01541   QFileInfo myFileInfo(rawImageFileName());
01542   QString myBaseName = myFileInfo.baseName();
01543   QString myImageFileName = mWorkDir + 
01544     QDir::separator() + 
01545     myBaseName + "_preview.png";
01546   myFileInfo = QFileInfo(myImageFileName);
01547   if (!myFileInfo.exists())
01548   {
01549     //we will use a model failed or model not run icons
01550     //since the model image does not exist
01551     if (!isCompleted())
01552     {
01553       if (hasError())
01554       {
01555         myImageFileName = ":/status_aborted.png";
01556       }
01557       else
01558       {
01559         //show queued icon
01560         myImageFileName = ":/status_queued.png";
01561       }
01562     }
01563     else
01564     {
01565       // Image not found for some other reason - it should exist
01566       myImageFileName = ":/non_categorical.png";
01567     }
01568   }
01569   QString myThumbImageName = mWorkDir + QDir::separator() + 
01570     myBaseName + "_thumb.png";
01571   Omgui::createThumbnail(mTaxonName,
01572     mAlgorithm.name(),
01573     myImageFileName,
01574     myThumbImageName);
01575  
01576   setThumbnailFileName(myThumbImageName);
01577 }
01578 
01579 bool OmgModel::parseModelResult(QString theModelXml)
01580 {
01581   //qDebug("******** Parsing model result ***********");
01582   //Omgui::createTextFile("/tmp/model.xml",theModelXml);
01583   QDomDocument myDocument("mydocument");
01584   myDocument.setContent(theModelXml);
01585   QDomElement myTopElement = myDocument.firstChildElement("SerializedModel");
01586   if (myTopElement.isNull())
01587   {
01588     //qDebug("Top (SerializedModel) element could not be found!");
01589     return false;
01590   }
01591   QDomElement mySamplerElement = myTopElement.firstChildElement("Sampler");
01592   if (mySamplerElement.isNull())
01593   {
01594     //qDebug("Sampler element could not be found!");
01595     return false;
01596   }
01597   
01598   //
01599   // Parse for presence records
01600   //
01601   OmgLocalities myLocalities; //used by absence parser too...
01602   QDomElement myPresenceElement = mySamplerElement.firstChildElement("Presence");
01603   if (!myPresenceElement.isNull())
01604   {
01605     QDomElement myElement = myPresenceElement.firstChildElement();
01606     while(!myElement.isNull()) 
01607     {
01608       if (myElement.tagName()!="Point")
01609       {
01610         myElement = myElement.nextSiblingElement();
01611         continue;
01612       }
01613       //qDebug("Parser found a point");
01614       OmgLocality myLocality;
01615       QString myId=myElement.attribute("Id");
01616       myLocality.setId(myId);
01617       QString myX=myElement.attribute("X");
01618       myLocality.setLongitude(myX.toDouble());
01619       QString myY=myElement.attribute("Y");
01620       myLocality.setLatitude(myY.toDouble());
01621       QString mySample=myElement.attribute("Sample");
01622       //qDebug("Sample for point: " + mySample.toLocal8Bit());
01623       QStringList myList=mySample.split(" ");
01624       QStringListIterator myIterator(myList);
01625       OmgSampleVector mySamples;
01626       while (myIterator.hasNext())
01627       {
01628         double myDouble=myIterator.next().toDouble();
01629         mySamples.push_back(myDouble);
01630       }
01631       myLocality.setSamples(mySamples);
01632       myLocalities.push_back(myLocality);
01633       myElement = myElement.nextSiblingElement();
01634     }
01635   }
01636   //
01637   // Parse for absences
01638   //
01639   QDomElement myAbsenceElement = mySamplerElement.firstChildElement("Absence");
01640   if (!myAbsenceElement.isNull())
01641   {
01642     QDomElement myElement = myAbsenceElement.firstChildElement();
01643     while(!myElement.isNull()) 
01644     {
01645       if (myElement.tagName()!="Point")
01646       {
01647         myElement = myElement.nextSiblingElement();
01648         continue;
01649       }
01650       //qDebug("Parser found a point");
01651       OmgLocality myLocality;
01652       myLocality.setAbundance(0);
01653       QString myId=myElement.attribute("Id");
01654       myLocality.setId(myId);
01655       QString myX=myElement.attribute("X");
01656       myLocality.setLongitude(myX.toDouble());
01657       QString myY=myElement.attribute("Y");
01658       myLocality.setLatitude(myY.toDouble());
01659       QString mySample=myElement.attribute("Sample");
01660       //qDebug("Sample for point: " + mySample.toLocal8Bit());
01661       QStringList myList=mySample.split(" ");
01662       QStringListIterator myIterator(myList);
01663       OmgSampleVector mySamples;
01664       while (myIterator.hasNext())
01665       {
01666         double myDouble=myIterator.next().toDouble();
01667         mySamples.push_back(myDouble);
01668       }
01669       myLocality.setSamples(mySamples);
01670       myLocalities.push_back(myLocality);
01671       myElement = myElement.nextSiblingElement();
01672     }
01673   }
01674   setLocalities(myLocalities);
01675   //
01676   // Extract the serialised model tag if present
01677   //
01678   QDomElement myAlgorithmElement = myTopElement.firstChildElement("Algorithm");
01679   QDomElement mySerialisedModelElement = myAlgorithmElement.firstChildElement("Model");
01680   if (!mySerialisedModelElement.isNull())
01681   {
01682     QDomDocument myModelDoc("MyModel");
01683     myModelDoc.appendChild(mySerialisedModelElement);
01684     //set the (optional) normalisation def after stripping off the doctype tag
01685     setModelDefinition(myModelDoc.toString().remove("<!DOCTYPE MyModel>"));
01686   }
01687 
01688   //
01689   // Extract the serialised normalisation parameters if present
01690   //
01691   QDomElement mySerialisedNormalizationElement = myAlgorithmElement.firstChildElement("Normalization");
01692   if (mySerialisedNormalizationElement.isNull())
01693   {
01694     qDebug("Normalisation element could not be found!");
01695     //do nothing (its optional
01696   }
01697   else
01698   {
01699     QDomDocument myModelDoc("MyNormalization");
01700     myModelDoc.appendChild(mySerialisedNormalizationElement);
01701     //set the mode def after stripping off the doctype tag
01702     setNormalizationDefinition(myModelDoc.toString().remove("<!DOCTYPE MyNormalization>"));
01703   }
01704   return true;
01705 }
01706 
01707 bool OmgModel::postProcess()
01708 {
01709   if (QFile::exists(workDir() + rawImageFileName()))
01710   {
01711     appendToLog( tr("Processing model results for ") + taxonName() );
01712     //save a nice looking png of the image to disk
01713     OmgGdal myGdal;
01714     QFileInfo myFileInfo(rawImageFileName());
01715     //get the raw wild name but without its extension
01716     QString myBaseName=myFileInfo.baseName();
01717     QString myImageFileName = myBaseName+".png";
01718     //convert tif generated by om to pseudocolor png
01719     //qDebug("Calling omggdal::writeImage(" +  mypModel->rawImageFileName().toLocal8Bit() + ","
01720     //+ myImageFileName.toLocal8Bit()+")");
01721     //
01722     // Deprecated for now 
01723     //
01724     //myGdal.writeImage(mypModel->workDir() + mypModel->rawImageFileName(),
01725     //    mypModel->workDir() + myImageFileName);
01726     //mypModel->setColouredImageFileName(myImageFileName);
01727     //save the legend for this pseudocolour image
01728     QString myLegendName = myBaseName+"_legend.png";
01729     myGdal.makeLegend(workDir() + myLegendName, 600);
01730     setLegendFileName(myLegendName);
01731     // 
01732     // and a smaller version for this report
01733     // 
01734     QString myPreviewImageName = myBaseName+"_preview.png";
01735     myGdal.writeImage(workDir() + rawImageFileName(),
01736         workDir() + myPreviewImageName,
01737         600, //width
01738         400); //height
01739     setPreviewFileName(myPreviewImageName);
01740     //
01741     // Create ascii grid file - disabled as can result in rediculously
01742     // large files
01743     //
01744     //QString myAsciiFileName = myBaseName + ".asc";
01745     //if (!myGdal.gdal2Ascii(workDir() + rawImageFileName(),
01746     //      workDir() + myAsciiFileName))
01747     //{
01748     //  emit logMessage(tr("Failed to convert model raster to AsciiGrid"));
01749     //}
01750 
01751     //
01752     // Create a csv file of the samples
01753     //
01754     Omgui::createTextFile(workDir() + myBaseName + ".csv" , localitiesToCsv());
01755     setCsvFileName(myBaseName + ".csv");
01756     if (!QFile::exists(workDir() + rawImageFileName()))
01757     {
01758       appendToLog(tr("Model post processing failed"));
01759       setCompleted(false);
01760       setError(true);
01761       return false;
01762     }
01763     else
01764     {
01765       //now the model is done we can mark it as such
01766       appendToLog(tr("Model post processing successful"));           
01767       setCompleted(true);
01768       setError(false);
01769     }
01770   }
01771   else
01772   {
01773     appendToLog(tr("Model projection did not produce any output")); 
01774     setError(true);
01775     setCompleted(false);
01776     return false;
01777   }
01778   //set the end time
01779   setEndDateTimeStamp(QDateTime::currentDateTime());
01780   //
01781   // Create the thumbnail - the createThumbnail method
01782   // will gracefully handle aborted / not completed
01783   // models
01784   // 
01785   createThumbnail();
01786   //
01787   // Generate the model report in html format
01788   //
01789   toHtml(true);
01790   return true;
01791 }
01792 

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