00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
00045
00046
00047
00048 mCompletedFlag(false),
00049 mErrorFlag(false),
00050
00051
00052
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),
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
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
00134
00135 return false;
00136 }
00137 mCompletedFlag = (myRootElement.attribute("Completed")=="true") ? true : false;
00138 mErrorFlag = (myRootElement.attribute("Error")=="true") ? true : false;
00139
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
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
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
00174 QDomElement myCoordinateSystemElement=myRootElement.firstChildElement("CoordinateSystem");
00175
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
00196 mCoordinateSystemName = myCoordinateSystemElement.firstChildElement("Name").text();
00197 mCoordinateSystem = myCoordinateSystemElement.firstChildElement("WKT").text();
00198
00199 QDomElement myTimingElement = myRootElement.firstChildElement("Timing");
00200 mStartDateTimeStamp.setTime_t(myTimingElement.attribute("Start").toUInt());
00201 mEndDateTimeStamp.setTime_t(myTimingElement.attribute("End").toUInt());
00202
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
00222
00223 QDomElement myAlgorithmElement= myRootElement.firstChildElement("Algorithm");
00224 if (!myAlgorithmElement.isNull())
00225 {
00226 OmgAlgorithm myAlgorithm;
00227
00228 QDomDocument myAlgorithmDoc("algorithm");
00229
00230
00231
00232
00233 QDomElement myCopy = myAlgorithmElement.cloneNode().toElement();
00234 myAlgorithmDoc.appendChild(myCopy);
00235 QString myXml = myAlgorithmDoc.toString();
00236
00237 if (myAlgorithm.fromXml(myXml))
00238 {
00239 setAlgorithm(myAlgorithm);
00240 }
00241 else
00242 {
00243
00244 }
00245 }
00246
00247
00248 mShapefileName = myRootElement.firstChildElement("Localities").firstChildElement("ShapefileName").text();
00249 mCsvFileName= myRootElement.firstChildElement("Localities").firstChildElement("CsvFileName").text();
00250
00251
00252
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
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
00272
00273
00274 QString myAbundance=myLocalityElement.attribute("Abundance");
00275 myLocality.setAbundance(myAbundance.toDouble());
00276 QString mySample=myLocalityElement.attribute("Sample");
00277
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
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
00301
00302 QDomElement myLayerSetElement = myRootElement.firstChildElement("CreationLayerSet").firstChildElement();
00303 QDomDocument myLayerSetDoc("layerset");
00304
00305
00306
00307
00308 QDomElement myCopy1 = myLayerSetElement.cloneNode().toElement();
00309 myLayerSetDoc.appendChild(myCopy1);
00310 QString myXml1 = myLayerSetDoc.toString();
00311 OmgLayerSet myLayerSet;
00312
00313 if (myLayerSet.fromXml(myXml1))
00314 {
00315 mCreationLayerSet = myLayerSet;
00316 }
00317 else
00318 {
00319
00320 }
00321
00322
00323
00324 QDomElement myLayerSetElement2 = myRootElement.firstChildElement("ProjectionLayerSet").firstChildElement();
00325 QDomDocument myLayerSetDoc2("layerset");
00326
00327
00328
00329
00330 QDomElement myCopy2 = myLayerSetElement2.cloneNode().toElement();
00331 myLayerSetDoc2.appendChild(myCopy2);
00332 QString myXml2 = myLayerSetDoc2.toString();
00333 OmgLayerSet myLayerSet2;
00334
00335 if (myLayerSet2.fromXml(myXml2))
00336 {
00337 mProjectionLayerSet = myLayerSet2;
00338 }
00339 else
00340 {
00341
00342 }
00343
00344 return true;
00345 }
00346
00347 QString OmgModel::toXml() const
00348 {
00349
00350
00351
00352
00353
00354
00355
00356
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
00378 }
00379 else if(mLocalitiesFilterType==SPATIALLY_UNIQUE)
00380 {
00381 myString += " <SpatiallyUnique/>\n";
00382 }
00383 else
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
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
00472
00473
00474
00475 QString myString = "<Options>\n";
00476 myString += " <OccurrencesFilter>\n";
00477 if (mLocalitiesFilterType==NO_FILTER)
00478 {
00479
00480 }
00481 else if(mLocalitiesFilterType==SPATIALLY_UNIQUE)
00482 {
00483 myString += " <SpatiallyUnique/>\n";
00484 }
00485 else
00486 {
00487 myString += " <EnvironmentallyUnique/>\n";
00488 }
00489 myString += " </OccurrencesFilter>\n";
00490 myString += " </Options>\n";
00491
00492
00493
00494
00495
00496 myString += " <Sampler>\n";
00497 myString+=mCreationLayerSet.toXml();
00498
00499
00500
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
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
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
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
00546
00547
00548 myString+=QString(" </Sampler>\n");
00549 myString+=mAlgorithm.toModelCreationXml();
00550
00551 return myString;
00552 }
00553 QString OmgModel::toModelProjectionXml() const
00554 {
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
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
00598 QDir myWorkDir(mWorkDir);
00599
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
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
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
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
00634 myStatsString += "<table class=\"rocTable\">\n";
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;
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
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)
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;
00694 const int myUpperThreshold=254;
00695 const int myLowerThreshold=0;
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
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
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
00730 }
00731
00732
00733
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\"> </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
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
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
00824
00825 myString+=QString(" <a name=\"algparameters\"></a>\n");
00826 myString+=QString(" <p>"+myAlgorithmParameters+"</p>\n");
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
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
00874 QString myTaxonName = mTaxonName;
00875 myTaxonName.replace(" ","_");
00876 QString myAlgorithmParameters = mAlgorithm.toHtml();
00877 QString myStatsString;
00878
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
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
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("\\"," \\");
01001 myName.replace("/"," /");
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
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
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
01154
01155
01156
01157
01158
01159
01160
01161 QRegExp myQRegExp( "^[^#][ a-zA-Z]*" );
01162 QFile myQFile( mSpeciesFile );
01163 if ( myQFile.open( QIODevice::ReadOnly ) )
01164 {
01165 mLocalities.clear();
01166
01167 QTextStream myQTextStream( &myQFile );
01168 QString myCurrentLine;
01169 while ( !myQTextStream.atEnd() )
01170 {
01171 myCurrentLine = myQTextStream.readLine();
01172
01173 QStringList myList = myCurrentLine.split(QRegExp("[\t]"));
01174
01175 if (myCurrentLine.startsWith("#"))
01176 {
01177 continue;
01178 }
01179 if (myList.size() < 4)
01180 {
01181 continue;
01182 }
01183 else
01184 {
01185 QString myId=myList.at(0).simplified();
01186 QString myTaxonName=myList.at(1).simplified();
01187
01188 myTaxonName=myTaxonName.replace( QRegExp(" {2,}"), " " );
01189
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)
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
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
01235 OmgLayer myLayer;
01236 myLayer.setName(theName);
01237 myLayer.setCategorical(false);
01238 mCreationLayerSet.setMask(myLayer);
01239 }
01240 void OmgModel::setProjectionMaskLayerName(QString theName)
01241 {
01242
01243 OmgLayer myLayer;
01244 myLayer.setName(theName);
01245 myLayer.setCategorical(false);
01246 mProjectionLayerSet.setMask(myLayer);
01247 }
01248 void OmgModel::setOutputFormatLayerName(QString theName)
01249 {
01250
01251 mOutputFormatLayer.setName(theName);
01252 mOutputFormatLayer.setCategorical(false);
01253 }
01254 void OmgModel::setCreationLayerNames(QStringList theNames)
01255 {
01256
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
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
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
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
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
01477
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
01540
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
01550
01551 if (!isCompleted())
01552 {
01553 if (hasError())
01554 {
01555 myImageFileName = ":/status_aborted.png";
01556 }
01557 else
01558 {
01559
01560 myImageFileName = ":/status_queued.png";
01561 }
01562 }
01563 else
01564 {
01565
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
01582
01583 QDomDocument myDocument("mydocument");
01584 myDocument.setContent(theModelXml);
01585 QDomElement myTopElement = myDocument.firstChildElement("SerializedModel");
01586 if (myTopElement.isNull())
01587 {
01588
01589 return false;
01590 }
01591 QDomElement mySamplerElement = myTopElement.firstChildElement("Sampler");
01592 if (mySamplerElement.isNull())
01593 {
01594
01595 return false;
01596 }
01597
01598
01599
01600
01601 OmgLocalities myLocalities;
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
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
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
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
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
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
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
01685 setModelDefinition(myModelDoc.toString().remove("<!DOCTYPE MyModel>"));
01686 }
01687
01688
01689
01690
01691 QDomElement mySerialisedNormalizationElement = myAlgorithmElement.firstChildElement("Normalization");
01692 if (mySerialisedNormalizationElement.isNull())
01693 {
01694 qDebug("Normalisation element could not be found!");
01695
01696 }
01697 else
01698 {
01699 QDomDocument myModelDoc("MyNormalization");
01700 myModelDoc.appendChild(mySerialisedNormalizationElement);
01701
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
01713 OmgGdal myGdal;
01714 QFileInfo myFileInfo(rawImageFileName());
01715
01716 QString myBaseName=myFileInfo.baseName();
01717 QString myImageFileName = myBaseName+".png";
01718
01719
01720
01721
01722
01723
01724
01725
01726
01727
01728 QString myLegendName = myBaseName+"_legend.png";
01729 myGdal.makeLegend(workDir() + myLegendName, 600);
01730 setLegendFileName(myLegendName);
01731
01732
01733
01734 QString myPreviewImageName = myBaseName+"_preview.png";
01735 myGdal.writeImage(workDir() + rawImageFileName(),
01736 workDir() + myPreviewImageName,
01737 600,
01738 400);
01739 setPreviewFileName(myPreviewImageName);
01740
01741
01742
01743
01744
01745
01746
01747
01748
01749
01750
01751
01752
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
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
01779 setEndDateTimeStamp(QDateTime::currentDateTime());
01780
01781
01782
01783
01784
01785 createThumbnail();
01786
01787
01788
01789 toHtml(true);
01790 return true;
01791 }
01792