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

omgmodellerlocalplugin.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 "omgmodellerlocalplugin.h"
00021 #include "omgalgorithm.h"
00022 #include "omgomlogcallback.h"
00023 #include "omgui.h" //ancilliary helper methods
00024 #include <omggdal.h>
00025 //qt includes
00026 #include <QStringList>
00027 #include <QFile>
00028 #include <QDir>
00029 #include <QDomDocument>
00030 #include <QDomElement>
00031 #include <QDomText>
00032 #include <QTimer>
00033 //needed for Q_EXPORT_PLUGIN macro at the end of this file
00034 #include <QtPlugin>
00035 
00036 
00037 //om includes
00038 #include <openmodeller/om.hh>
00039 #include <openmodeller/Configuration.hh>
00040 #include <openmodeller/Exceptions.hh>
00041 
00042 //
00043 //Standard includes
00044 #include <istream>
00045 #include <stdlib.h>
00046 #include <stdio.h>
00047 #include <iostream>  // I/O 
00048 #include <fstream>   // file I/O
00049 #include <sstream>     // treat string as a stream
00050 #include <string>
00051 
00052 #include <stdexcept>
00053 
00054 //
00055 // A global variable needed to set up the call back for loggin from openModeller
00056 //
00057 QTextStream* output;
00058 bool OmgModellerLocalPlugin::mAlgFactoryStartedFlag=false;
00059 
00060 OmgModellerLocalPlugin::OmgModellerLocalPlugin( QObject * parent) : 
00061       QObject (parent),
00062       OmgModellerPluginInterface(), 
00063       mpOpenModeller(new OpenModeller()),
00064       mpLogCallBack (new OmgOmLogCallback(*(output)))
00065 {
00066   qDebug("Creating modeller local plugin");
00067   initialise();
00068 }
00069 
00070 OmgModellerLocalPlugin::~OmgModellerLocalPlugin()
00071 {
00072     disconnect (mpLogCallBack);
00074     g_log.setCallback( 0 );
00075     delete mpOpenModeller;
00076     qDebug("Destroying modeller local plugin");
00077 }
00078 
00079 bool OmgModellerLocalPlugin::initialise()
00080 {
00081   qDebug(tr("-------Modeller Plugin Initialising---------").toLocal8Bit());
00082   // Note this function searches for om plugins - and should only
00083   // ever be run once in the life of the openModeller desktop application session
00084   //
00085   if (!OmgModellerLocalPlugin::mAlgFactoryStartedFlag)
00086   {
00087     qDebug("Initialising openmodeller local plugin...calling AlgorithmFactory::searchDefaultDirs()");
00088     AlgorithmFactory::searchDefaultDirs();
00089     OmgModellerLocalPlugin::mAlgFactoryStartedFlag=true;
00090   }
00091   else
00092   {
00093     qDebug("Initialising openmodeller local plugin...NOT calling AlgorithmFactory::searchDefaultDirs()");
00094     //do nothing
00095   }
00096   //set up callbacks
00097   g_log.setLevel( Log::Debug );
00098   g_log.setCallback(mpLogCallBack );
00099 
00100   //connect up our messenger class which delegates signals
00101   //since a plugin in Qt cannot directly inherit from qobject
00102   connect(mpLogCallBack, SIGNAL(omLogMessage(QString,QString)),
00103       &mMessenger, SLOT(emitModelMessage(QString,QString)));
00104   connect(mpLogCallBack, SIGNAL(omLogError(QString,QString)),
00105       &mMessenger, SLOT(emitModelError(QString,QString)));
00106   //connect to this class's logger too so we can insert logs into OmgModel
00107   //when create and project are called
00108   connect(mpLogCallBack, SIGNAL(omLogMessage(QString,QString)),
00109       this, SLOT(appendToLog(QString,QString)));
00110   connect(mpLogCallBack, SIGNAL(omLogError(QString,QString)),
00111       this, SLOT(appendToLog(QString,QString)));
00112   mpOpenModeller->setModelCallback( modelCallback, this );
00113   mpOpenModeller->setMapCallback( mapCallback, this );
00114   return true;
00115 
00116 }
00117 
00118 QString OmgModellerLocalPlugin::createModel(OmgModel * thepModel)
00119 {
00120   thepModel->setError(false);
00121   mModelLog="";
00122   QString myModelResult;
00123   QString myFileName = thepModel->taxonName();
00124   mModelGuid = thepModel->guid();
00125   mpLogCallBack->setModelGuid(thepModel->guid());
00126   myFileName = myFileName.replace(" ","_");
00127   mMessenger.emitModelMessage(mModelGuid,tr("Running model for : ") + myFileName.toLocal8Bit());
00128   //get the file path in the format of the host OS as we will be passing this
00129   //over to om which wont automatically convert (qt classes do)
00130   QString myWorkDir = QDir::convertSeparators(thepModel->workDir());
00131   //std::string myFileNameString(myFileName.toLocal8Bit());
00132   // now use the local om lib to run the model
00133   try 
00134   {
00135     std::ostringstream myOutputStream ;
00136     QString myModelXml = thepModel->toModelCreationXml().trimmed();
00137     //for local models we need to append the modelparameters outer tag
00138     myModelXml = "<ModelParameters>\n"+ myModelXml + "\n</ModelParameters>";
00139     //first write the model xml to a file - this is just for user reference / debugging
00140     if (!Omgui::createTextFile(myWorkDir + myFileName+"_create.xml",myModelXml))
00141     {
00142       QString myWarning(tr("Unable to open ") + myFileName.toLocal8Bit() + tr(" for writing!"));
00143       mMessenger.emitModelError(mModelGuid,myWarning);
00144     }
00145     std::string myXml(myModelXml.toLocal8Bit().data());
00146     std::istringstream myStream;
00147     myStream.str(myXml);
00148     ConfigurationPtr c = Configuration::readXml( myStream );
00149     mpOpenModeller->setModelConfiguration(c);
00150     mpOpenModeller->createModel();
00151     ConfigurationPtr myConfiguration = mpOpenModeller->getModelConfiguration();
00152     Configuration::writeXml( myConfiguration, myOutputStream);
00153     mMessenger.emitModelDone(mModelGuid);
00154     myModelResult=QString::fromStdString(myOutputStream.str());
00155     //qDebug( myModelResult.toLocal8Bit());
00156     mModelProgress=0;
00157     mMessenger.emitModelCreationProgress(mModelGuid,100);
00158     thepModel->setLog(mModelLog);
00159     return myModelResult;
00160   }
00161   catch( std::exception& e ) 
00162   {
00163     mMessenger.emitModelError(mModelGuid,tr("Exception caught!\n"));
00164     mMessenger.emitModelError(mModelGuid,QString::fromStdString(e.what()));
00165     thepModel->setLog(mModelLog);
00166     thepModel->setError(true);
00167     return QString("");
00168   }
00169 }
00170 
00171 void  OmgModellerLocalPlugin::projectModel(OmgModel * thepModel)
00172 {
00173   mModelLog="";
00174   QString myFileName = thepModel->taxonName();
00175   mModelGuid = thepModel->guid();
00176   mpLogCallBack->setModelGuid(thepModel->guid());
00177   myFileName = myFileName.replace(" ","_");
00178   mMessenger.emitModelMessage(mModelGuid,tr("Projecting model for : ") + myFileName.toLocal8Bit());
00179   //get the file path in the format of the host OS as we will be passing this
00180   //over to om which wont automatically convert (qt classes do)
00181   QString myWorkDir = QDir::convertSeparators(thepModel->workDir());
00182   //std::string myFileNameString(myFileName.toLocal8Bit());
00183   // now use the local om lib to run the model
00184   try 
00185   {
00186     std::ostringstream myOutputStream ;
00187     QString myModelXml = thepModel->toModelProjectionXml().trimmed();
00188     //for local models we need to append the modelparameters outer tag
00189     myModelXml = "<ProjectionParameters xmlns=\"http://openmodeller.cria.org.br/xml/1.0\">\n"
00190       + myModelXml + "\n</ProjectionParameters>";
00191     //first write the model xml to a file - this is just for user reference / debugging
00192     if (!Omgui::createTextFile(myWorkDir + myFileName+"_project.xml",myModelXml))
00193     {
00194       QString myWarning(tr("Unable to open ") + myFileName.toLocal8Bit() + tr(" for writing!"));
00195       mMessenger.emitModelError(mModelGuid,myWarning);
00196     }
00197     std::string myXml(myModelXml.toLocal8Bit().data());
00198     std::istringstream myModelStream;
00199     myModelStream.str(myXml);
00200     ConfigurationPtr mypConfiguration = Configuration::readXml( myModelStream );
00201     mpOpenModeller->setProjectionConfiguration(mypConfiguration);
00202     //this next line seems counterintuitive but its needed for deserialisation before projection
00203     mpOpenModeller->createModel();
00204     //cout << "Loading Projection Environment " << theEnvironment << endl;
00205     std::string myEnvironmentXml = thepModel->projectionLayersXml().toLocal8Bit().data();
00206     std::istringstream myEnvironmentStream;
00207     myEnvironmentStream.str(myEnvironmentXml);
00208     mypConfiguration =  Configuration::readXml( myEnvironmentStream );
00209     EnvironmentPtr mypEnvironment = createEnvironment( mypConfiguration );
00210     //cout << "Projecting to file " << theOutput << endl;
00211     QString myRawImageFileName =  myWorkDir + myFileName+"_projection."  + Omgui::getOutputFormatExtension();
00212     mpOpenModeller->createMap( mypEnvironment, myRawImageFileName.toLocal8Bit().data() );
00213     //store the model image file name in the model object
00214     thepModel->setRawImageFileName(myRawImageFileName);
00215 
00216     //ConfusionMatrix matrix;
00217     ConfusionMatrix * mypMatrix = mpOpenModeller->getConfusionMatrix();
00218 
00219     AreaStats * mypStats = mpOpenModeller->getActualAreaStats();
00220     QString myStatsString = tr("\nModel statistics\n" );
00221     myStatsString +=tr("Accuracy                              : ") 
00222       + QString::number( mypMatrix->getAccuracy() * 100 )
00223       + QString("%\n");
00224     myStatsString +=tr("Omission error                        : ") 
00225       + QString::number( mypMatrix->getOmissionError() * 100 )
00226       + QString("%\n");
00227     //why was this commented out in om_console?
00228     //myStatsString += QString( "Commission error:  %7.2f\%\n", matrix.getCommissionError() * 100 );
00229     myStatsString +=tr("Percentage of cells predicted present : ") 
00230       + QString::number (
00231           mypStats->getAreaPredictedPresent() / (double) mypStats->getTotalArea() * 100)
00232       + QString("%\n");
00233     myStatsString +=tr("Total number of cells                 : ")
00234       + QString::number( mypStats->getTotalArea() )
00235       + QString("\n");
00236 
00237     delete mypMatrix;
00238     delete mypStats;
00239     mMessenger.emitModelMessage(mModelGuid,myStatsString);
00240     thepModel->setModelStats(myStatsString);
00241     mModelProgress=0;
00242     mMessenger.emitModelProjectionProgress(mModelGuid,100);
00243     thepModel->appendToLog(mModelLog);
00244   }
00245   catch( std::exception& e ) 
00246   {
00247     mMessenger.emitModelError(mModelGuid,tr("Exception caught!\n"));
00248     mMessenger.emitModelError(mModelGuid,QString::fromStdString(e.what()));
00249     thepModel->appendToLog(mModelLog);
00250     thepModel->setError(true);
00251     return;
00252   }
00253 }
00254 
00255 const QStringList OmgModellerLocalPlugin::getAlgorithmList()
00256 { 
00257   qDebug("OmgModellerLocalPlugin::getAlgorithmList() called");
00258   const AlgMetadata **mypAlgorithmMetadataArray = mpOpenModeller->availableAlgorithms();
00259   const AlgMetadata *mypAlgorithmMetadata = *mypAlgorithmMetadataArray;
00260   QStringList myAlgList;
00261 
00262   while ( mypAlgorithmMetadata  )
00263   {
00264     myAlgList.append(mypAlgorithmMetadata->name);
00265     *mypAlgorithmMetadataArray++;
00266     mypAlgorithmMetadata = *mypAlgorithmMetadataArray;
00267   }
00268   myAlgList.sort();
00269   return myAlgList;
00270 }
00271 
00272 const OmgAlgorithmSet OmgModellerLocalPlugin::getAlgorithmSet()
00273 {
00274   const AlgMetadata **mypAlgorithmMetadataArray = mpOpenModeller->availableAlgorithms();
00275   const AlgMetadata *mypAlgorithmMetadata = *mypAlgorithmMetadataArray;
00276 
00277   OmgAlgorithmSet myAlgorithmSet;
00278   myAlgorithmSet.setName("Local Plugin Algorithms");
00279   myAlgorithmSet.setDescription("These are the algorithms available on your local machine ");
00280   
00281   while ( mypAlgorithmMetadata  )
00282   {
00283     QString myName(mypAlgorithmMetadata->name);
00284     QString myId(mypAlgorithmMetadata->id);
00285     OmgAlgorithm myAlgorithm = getAlgorithm(myId);
00286     myAlgorithmSet.addAlgorithm(myAlgorithm);
00287     *mypAlgorithmMetadataArray++;
00288     mypAlgorithmMetadata = *mypAlgorithmMetadataArray;
00289   }
00290   return myAlgorithmSet; 
00291 }
00292 
00293 const OmgAlgorithm OmgModellerLocalPlugin::getAlgorithm( QString theId )
00294 {       
00295   const AlgMetadata **mypAlgorithmMetadataArray = mpOpenModeller->availableAlgorithms();
00296   const AlgMetadata *mypAlgorithmMetadata = *mypAlgorithmMetadataArray;
00297 
00298   while ( mypAlgorithmMetadata  )
00299   {
00300     QString myId(mypAlgorithmMetadata->id);
00301     if (myId==theId)
00302     {
00303       OmgAlgorithm myAlgorithm;
00304       myAlgorithm.setId( QString( mypAlgorithmMetadata->id ));
00305       myAlgorithm.setName( QString(  mypAlgorithmMetadata->name ));
00306       myAlgorithm.setVersion(  QString( mypAlgorithmMetadata->version));
00307       myAlgorithm.setGuid();
00308       myAlgorithm.setCategorical(  mypAlgorithmMetadata->categorical);
00309       myAlgorithm.setAbsence( mypAlgorithmMetadata->absence);
00310       myAlgorithm.setAuthor(  QString( mypAlgorithmMetadata->author));
00311       myAlgorithm.setCodeAuthor(  QString( mypAlgorithmMetadata->code_author));
00312       myAlgorithm.setContact(  QString( mypAlgorithmMetadata->contact));
00313       myAlgorithm.setOverview(  QString( mypAlgorithmMetadata->overview));
00314       myAlgorithm.setDescription(  QString( mypAlgorithmMetadata->description));
00315       myAlgorithm.setBibliography(  QString( mypAlgorithmMetadata->biblio));
00316 
00317       //qDebug ("getting algorithm parameters from metadata");
00318       int myParameterCountInt = mypAlgorithmMetadata->nparam;
00319       AlgParamMetadata * myParameter = mypAlgorithmMetadata->param;
00320       //interate through parameters adding the correct control type
00321       for ( int i = 0; i < myParameterCountInt; i++, myParameter++ )
00322       {
00323         //qDebug("Getting next parameter");
00324         OmgAlgorithmParameter myOmgParameter;
00325 
00327         //  moment thats because is is. In a future cleanup Il deal with real nos etc.
00328 
00329         myOmgParameter.setType( QString (myParameter->type ));
00330         myOmgParameter.setName( QString (myParameter->name ));
00331         myOmgParameter.setId( QString (myParameter->id ));
00332         if (!myParameter->has_min==0)
00333         {
00334           myOmgParameter.setMinimum( QString::number (myParameter->min_val ));
00335         }
00336         else
00337         {
00339           myOmgParameter.setMinimum( QString::number(INT_MIN) );
00340         }
00341         if (!myParameter->has_max==0)
00342         {
00343           myOmgParameter.setMaximum( QString::number (myParameter->max_val ));
00344         }
00345         else
00346         {
00348           myOmgParameter.setMaximum( QString::number(INT_MAX ));
00349         }
00350         myOmgParameter.setDefault(QString ( myParameter->typical ));
00351         myOmgParameter.setOverview(QString ( myParameter->overview ));
00352         myOmgParameter.setDescription(QString ( myParameter->description ));
00353         myAlgorithm.addParameter(myOmgParameter);
00354         //qDebug(myOmgParameter.toString().toLocal8Bit());
00355       }
00356       //define the origin of the algorithm - this is used by e.g. the algmanager
00357       //in the gui to differentiate between user profiles and profiles 
00358       //obtained from the plugin
00359       myAlgorithm.setOrigin(OmgAlgorithm::ADAPTERPROFILE);
00360       //Exit loop because we have found the correct algorithm
00361       return myAlgorithm;
00362     }
00363     *mypAlgorithmMetadataArray++;
00364     mypAlgorithmMetadata = *mypAlgorithmMetadataArray;
00365   }
00366   //not found
00367   qDebug("Algorithm not found for id"+theId.toLocal8Bit());
00368   return OmgAlgorithm();
00369 }//getAlgorithm( QString theId )
00370 
00371 void OmgModellerLocalPlugin::setCreationProgress (int theProgress)
00372 {
00373   //qDebug("setCreationProgress: " + mModelGuid.toLocal8Bit() + " " + QString::number(theProgress).toLocal8Bit());
00374   if (mModelProgress != theProgress)
00375   {
00376     mModelProgress=theProgress;
00377     mMessenger.emitModelCreationProgress(mModelGuid,theProgress);
00378   }
00379 }
00380 void OmgModellerLocalPlugin::setProjectionProgress (int theProgress)
00381 {
00382   //qDebug("setProjectionProgress: " + mModelGuid.toLocal8Bit() + " " +  QString::number(theProgress).toLocal8Bit());
00383   if (mModelProgress != theProgress)
00384   {
00385     mMapProgress=theProgress;
00386     mMessenger.emitModelProjectionProgress(mModelGuid,theProgress);
00387   }
00388 }
00389 
00390 void OmgModellerLocalPlugin::appendToLog( QString theGuid, QString theMessage)
00391 {
00392   mModelLog += "\n" + theMessage;
00393 }
00394  
00395 const QString OmgModellerLocalPlugin::getLayers(QString theBaseDir)
00396 {
00397   QTimer *mypTimer = new QTimer(this);
00398   connect(mypTimer, SIGNAL(timeout()), &mMessenger, SLOT(refresh()));
00399   mypTimer->start(1000);
00400   QString myLayers = Omgui::getLayers(theBaseDir);
00401   mypTimer->stop();
00402   delete mypTimer;
00403   return myLayers;
00404 }
00405 
00406 
00407 //
00408 // non member callback functions
00409 //
00410 void modelCallback( float theProgress, void *thepPlugin )
00411 {
00412  //cast the plugin to a local plugin
00413  //qDebug("modelCallBack: " + QString::number(theProgress).toLocal8Bit());
00414  OmgModellerLocalPlugin * mypPlugin = (OmgModellerLocalPlugin *) thepPlugin;
00415  mypPlugin->setCreationProgress(static_cast<int>(theProgress*100));
00416 }
00417 void mapCallback( float theProgress, void *thepPlugin )
00418 {
00419  //qDebug("mapCallBack: " + QString::number(theProgress).toLocal8Bit());
00420  //cast the plugin to a local plugin
00421  OmgModellerLocalPlugin * mypPlugin = (OmgModellerLocalPlugin *) thepPlugin;
00422  mypPlugin->setProjectionProgress(static_cast<int>(theProgress*100));
00423 }
00424     
00425 // Entry point for the Qt plugin:
00426 Q_EXPORT_PLUGIN2(local_modeller_plugin, OmgModellerLocalPlugin);

Generated on Mon Apr 28 15:07:55 2008 for openModellerDesktop by  doxygen 1.4.1-20050210