Signals | Public Member Functions | Static Public Attributes | Protected Member Functions
InversionThread Class Reference

Inversion thread with Neighbourhood tuning parameters. More...

#include <InversionThread.h>

Inheritance diagram for InversionThread:
QGpCoreTools::Thread QGpCoreTools::XMLClass

List of all members.

Signals

void started ()
void stopped ()

Public Member Functions

int activeModelCount () const
int bestModelCount () const
void checkImportModels ()
void clear ()
int expectedModelCount () const
AbstractForwardforward ()
double giveUp () const
int giveUpCount () const
bool hasModelsToImport () const
bool hasReportFile () const
void importModels (QString fileName, bool strict=true)
 InversionThread (QObject *parent=0)
bool isReportExists () const
void lock () const
double misfit (int modelIndex) const
int nr () const
int ns () const
int ns0 () const
int nw () const
bool operator!= (const InversionThread &o) const
bool operator== (const InversionThread &o) const
int rejectedCount () const
void removeReport ()
double reportBestMisfit () const
QDir reportDir () const
QString reportFileName () const
void setForward (AbstractForward *forward)
void setGiveUp (double giveUp)
void setImportOnly ()
void setNr (int nr)
void setNs (int ns)
void setNs0 (int ns0)
void setNw (int nw)
void setObjectName (QString name)
bool setReportDir (const QDir &d)
void setStorage ()
void setTuningParameters (InversionThread *t)
void start ()
void terminate ()
void unlock () const
int validModelCount () const
const ParametervariableParameter (int paramIndex) const
int variableParameterCount () const
double variableParameterValue (int modelIndex, int paramIndex) const
int visitedModelCount () const
virtual const QString & xml_tagName () const
 ~InversionThread ()

Static Public Attributes

static const QString xmlInversionThreadTag = "InversionThread"

Protected Member Functions

virtual void run ()
virtual XMLMember xml_member (XML_MEMBER_ARGS)
virtual void xml_polish (XML_POLISH_ARGS)
virtual bool xml_setProperty (XML_SETPROPERTY_ARGS)
virtual void xml_writeChildren (XML_WRITECHILDREN_ARGS) const
virtual void xml_writeProperties (XML_WRITEPROPERTIES_ARGS) const

Detailed Description

Inversion thread with Neighbourhood tuning parameters.


Constructor & Destructor Documentation

InversionThread::InversionThread ( QObject *  parent = 0)

References dinverGui, and TRACE.

   : Thread(parent)
{
  TRACE;
  // Create log stream for this thread
  dinverGui->logs()->addView(this, "unamed");

  _itmax=0; // Kept for compatibility
  _ns0=50;
  _ns=2500;
  _nr=50;
  _nw=2;
  _giveUp=0.9;
  _hasReportFile=false;
  _hasModelsToImport=false;
  _importOnly=false;
  _reportValidModelCount=0;
  _reportBestMisfit=0.0;
}

References dinverGui, and DinverCore::ModelRepository::forward().

{
  // Remove log stream for this thread
  dinverGui->logs()->removeView(this);
  delete _models.forward();
}

Member Function Documentation

int InversionThread::activeModelCount ( ) const [inline]
int InversionThread::bestModelCount ( ) const [inline]

Check if the run has an attached report and if models can be imported from it. Models will be imported only if the run is started.

References DinverCore::ModelRepository::importModels(), QGpCoreTools::tr(), and DinverCore::ModelRepository::validModelCount().

Referenced by DinverGui::open().

{
  StreamRedirection sr(&App::stream(this));
  QFileInfo fi(_reportFileName);
  if(_hasReportFile) {
    if(fi.exists()) {
      _hasModelsToImport=true;
    } else {
      // Try to translate the path
      QString fn= Application::instance()->translatePath(_reportFileName, tr("Loading reports ..."),
                                                            tr( "Report file (%1)" ));
      fi.setFile(fn);
      if( !fn.isEmpty() && fi.exists()) {
        _reportFileName=fn;
        _hasModelsToImport=true;
      } else {
        _hasReportFile=false;
      }
    }
  } else if(fi.exists()) { // Detected a report file with the same name...
    _models.importModels(_reportFileName, true);
    // Take ownership only if models are compatible
    if(_models.validModelCount()>0) _hasReportFile=true;
    _hasModelsToImport=false;
  }
}

References DinverCore::ModelRepository::clear(), QGpCoreTools::endl(), removeReport(), terminate(), QGpCoreTools::tr(), and TRACE.

Referenced by DinverGui::clearThread().

{
  TRACE;
  if(isRunning()) terminate();
  if(_hasReportFile) removeReport();
  _hasReportFile=false;
  _models.clear();
  App::stream(this) << tr("Thread cleared.") << endl;
}
int InversionThread::expectedModelCount ( ) const [inline]

References DinverCore::ModelRepository::forward().

{return _models.forward();}
double InversionThread::giveUp ( ) const [inline]

Referenced by LaunchThreadItem::data(), setGiveUp(), and setTuningParameters().

{return _giveUp;}
int InversionThread::giveUpCount ( ) const [inline]
bool InversionThread::hasModelsToImport ( ) const [inline]
{return _hasModelsToImport;}
bool InversionThread::hasReportFile ( ) const [inline]

Referenced by DinverGui::open(), DinverGui::removeThread(), and setObjectName().

{return _hasReportFile;}
void InversionThread::importModels ( QString  fileName,
bool  strict = true 
) [inline]
bool InversionThread::isReportExists ( ) const [inline]

Check whether or not the report file exist.

Referenced by removeReport(), and setObjectName().

{QFileInfo fi(_reportFileName); return fi.exists();}
void InversionThread::lock ( ) const [inline]
double InversionThread::misfit ( int  modelIndex) const [inline]
int InversionThread::nr ( ) const [inline]

Referenced by LaunchThreadItem::data(), setNr(), and setTuningParameters().

{return _nr;}
int InversionThread::ns ( ) const [inline]

Referenced by LaunchThreadItem::data(), setNs(), and setTuningParameters().

{return _ns;}
int InversionThread::ns0 ( ) const [inline]

Referenced by LaunchThreadItem::data(), setNs0(), and setTuningParameters().

{return _ns0;}
int InversionThread::nw ( ) const [inline]

Referenced by LaunchThreadItem::data(), setNw(), and setTuningParameters().

{return _nw;}
bool InversionThread::operator!= ( const InversionThread o) const [inline]
{return !(_models==o._models);}
bool InversionThread::operator== ( const InversionThread o) const [inline]
{return _models==o._models;}
int InversionThread::rejectedCount ( ) const [inline]

Removes report file (and attached files) from disk if a report exists.

References QGpCoreTools::endl(), isReportExists(), QGpCoreTools::tr(), and TRACE.

Referenced by clear(), and DinverGui::removeThread().

{
  TRACE;
  if(isReportExists()) {
    QFileInfo fi(_reportFileName);
    QDir d(fi.path());
    QString fn;
    // Remove report file
    fn=objectName()+".report";
    App::stream() << tr("Removing %1").arg(fn) << endl;
    d.remove(fn);
    // Remove parameter file
    fn=objectName()+".param";
    App::stream() << tr("Removing %1").arg(fn) << endl;
    d.remove(fn);
    // Remove target file
    fn=objectName()+".target";
    App::stream() << tr("Removing %1").arg(fn) << endl;
    d.remove(fn);
  }
}
double InversionThread::reportBestMisfit ( ) const [inline]
{return _reportBestMisfit;}

References TRACE.

Referenced by DinverGui::save().

{
  TRACE;
  QFileInfo fi (_reportFileName);
  return fi.absoluteDir();
}
QString InversionThread::reportFileName ( ) const [inline]

Referenced by xml_writeProperties().

{return _reportFileName;}
void InversionThread::run ( ) [protected, virtual]

References DinverCore::ModelRepository::bestModelIndex(), DinverCore::ModelRepository::clear(), QGpCoreTools::endl(), DinverCore::ModelRepository::importModels(), DinverCore::ModelRepository::misfit(), DinverCore::ModelRepository::openReport(), DinverCore::ModelRepository::setBestModelCount(), DinverCore::ModelRepository::setGiveUp(), DinverCore::ModelRepository::setMaximumModelCount(), DinverCore::ModelRepository::setMaximumQueueLength(), DinverCore::ModelRepository::setWalkCount(), DinverCore::ModelRepository::start(), started(), stopped(), QGpCoreTools::tr(), TRACE, DinverCore::ModelRepository::validModelCount(), and DinverCore::ModelRepository::wait().

{
  TRACE;
  emit started();
  MessageContext();
  // Effectively import models if there available in my report
  if(_hasModelsToImport) {
    _models.importModels(_reportFileName, false);
    if(_importOnly) {
      _reportValidModelCount=_models.validModelCount();
      _reportBestMisfit=_models.misfit(_models.bestModelIndex());
      _models.clear();
    } else {
      _hasModelsToImport=false;
    }
  }
  if(_importOnly) {
    _importOnly=false;
    return; // Do not emit stop because process was not started through ThreadLauncher
  }
  if(!_reportFileName.isEmpty()) {
    if( !_models.openReport(_reportFileName) ) {
      emit stopped();
      return;
    }
    _hasReportFile=true; // Takes ownership of the report file
  }
  Application::instance()->setStreamPrefix(QString::null);
  App::stream() << tr("Initialization of parameter space...") << endl;
  _models.setBestModelCount(_nr);
  _models.setWalkCount(_nw);
  _models.setGiveUp(_giveUp);
  _models.setMaximumQueueLength(50);
  if(_ns0>0) {
    App::stream() << tr("Generating %1 models randomly...").arg(_ns0) << endl;
    _models.setMaximumModelCount(_models.validModelCount()+_ns0);
    _models.start(Thread::idealThreadCount(), Generator::MonteCarlo);
    _models.wait();
    App::stream() << tr("Generated %1 models randomly").arg(_ns0) << endl;
  }
  if(_ns>0) {
    Application::instance()->setStreamPrefix(QString::null);
    App::stream() << tr("Generating %1 models with Neighborhood...").arg(_ns) << endl;
    _models.setMaximumModelCount(_models.validModelCount()+_ns);
    _models.start(Thread::idealThreadCount(), Generator::Neighborhood);
    _models.wait();
    App::stream() << tr("Generated %1 models with Neighborhood").arg(_ns) << endl;
  }
  Application::instance()->setStreamPrefix(QString::null);
  //printBestModels();
  emit stopped();
}
void InversionThread::setGiveUp ( double  giveUp) [inline]

References giveUp().

Referenced by LaunchThreadItem::setData(), and setTuningParameters().

{_giveUp=giveUp;}
void InversionThread::setImportOnly ( ) [inline]

Referenced by DinverGui::open().

{_importOnly=true;}
void InversionThread::setNr ( int  nr) [inline]

References nr().

Referenced by LaunchThreadItem::setData(), and setTuningParameters().

{_nr=nr;}
void InversionThread::setNs ( int  ns) [inline]

References ns().

Referenced by LaunchThreadItem::setData(), and setTuningParameters().

{_ns=ns;}
void InversionThread::setNs0 ( int  ns0) [inline]

References ns0().

Referenced by LaunchThreadItem::setData(), and setTuningParameters().

{_ns0=ns0;}
void InversionThread::setNw ( int  nw) [inline]

References nw().

Referenced by LaunchThreadItem::setData(), and setTuningParameters().

{_nw=nw;}
void InversionThread::setObjectName ( QString  name)

References dinverGui, QGpCoreTools::endl(), hasReportFile(), isReportExists(), QGpCoreTools::tr(), and TRACE.

Referenced by ThreadLauncher::newThread(), LaunchThreadItem::setData(), and xml_setProperty().

{
  TRACE;
  if(name==objectName()) return;
  if(isRunning()) {
    App::stream() << tr("run %1: cannot change the name of a running inversion.")
                     .arg(objectName()) << endl;
    return;
  }
  // Check if name is unique
  const ThreadList threads=dinverGui->threads();
  for(ThreadList::const_iterator it=threads.begin(); it<threads.end(); it++ ) {
    if((*it)->objectName()==name) {
      App::stream() << tr("The new name for run %1 is not unique, nothing changed.").arg(objectName()) << endl;
      return;
    }
  }
  QObject::setObjectName(name);
  QFileInfo fi(_reportFileName);
  QDir d(fi.path());
  QString oldName =objectName();
  bool oldReportExist=isReportExists();
  _reportFileName=d.absoluteFilePath(name+".report");
  if(oldReportExist && hasReportFile()) {
    renameReport(oldName);
  }
}
bool InversionThread::setReportDir ( const QDir &  d)

References QGpCoreTools::endl(), QGpCoreTools::tr(), and TRACE.

Referenced by ThreadLauncher::newThread(), DinverGui::open(), and DinverGui::save().

{
  TRACE;
  if(isRunning()) {
    App::stream() << tr("run %1 is runnnig cannot copy report to %2.")
                .arg(objectName()).arg(d.absolutePath()) << endl;
    return false;
  } else {
    QString newFileName=d.absoluteFilePath(objectName()+".report");
    if(!_reportFileName.isEmpty()) {
      QFileInfo fi(_reportFileName);
      if(fi.exists()) {
        QDir oldDir(fi.path());
        if(oldDir!=d) {
          QFile::copy(_reportFileName, newFileName);
        }
      }
    }
    _reportFileName=newFileName;
    return true;
  }
}

References giveUp(), nr(), ns(), ns0(), nw(), setGiveUp(), setNr(), setNs(), setNs0(), setNw(), and TRACE.

Referenced by ThreadLauncher::newThread().

{
  TRACE;
  setNs0(t->ns0());
  setNs(t->ns());
  setNr(t->nr());
  setNw(t->nw());
  setGiveUp(t->giveUp());
}

References DinverCore::ModelRepository::checksum(), QGpCoreTools::endl(), DinverCore::ModelRepository::expectedModelCount(), DinverCore::ModelRepository::init(), stopped(), QGpCoreTools::tr(), TRACE, and DinverCore::ModelRepository::variableParameterCount().

Referenced by DinverGui::open().

{
  TRACE;
  if(_importOnly) {
    App::stream(this) << tr("\n---------------------- Getting information at ")
                      << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss") << "\n\n"
                      << tr(" Dimension of parameter space        =%1\n").arg(_models.variableParameterCount())
                      << tr(" Model file                          =%1\n").arg(_reportFileName) << endl;
  } else {
    App::stream(this) << tr("\n---------------------- Starting at ")
                      << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss") << "\n\n"
                      << tr(" Num samples Monte-Carlo             =%1\n").arg(_ns0)
                      << tr(" Num samples Neighborhood            =%1\n").arg(_ns)
                      << tr(" Num cells to resample               =%1\n").arg(_nr)
                      << tr(" Num of walks before accepting model =%1\n").arg(_nw)
                      << tr(" Max reject ratio before cell give up=%1\n").arg(_giveUp)
                      << tr(" Dimension of parameter space        =%1\n").arg(_models.variableParameterCount())
                      << tr(" Parameterization checksum           =%1\n").arg(_models.checksum())
                      << tr(" Total number of models              =%1\n").arg(_models.expectedModelCount())
                      << tr(" Model file                          =%1\n").arg(_reportFileName) << endl;
    if(_models.variableParameterCount()==0) {
      App::stream(this) << tr("Number of variable parameters is null, nothing to optimize, aborting.") << endl;
      emit stopped();
      return;
    }
  }
  _models.init();
  QThread::start();
  //run();
}
void InversionThread::started ( ) [signal]

Referenced by run().

void InversionThread::stopped ( ) [signal]

Referenced by run(), and start().

References QGpCoreTools::endl(), DinverCore::ModelRepository::stop(), QGpCoreTools::tr(), and TRACE.

Referenced by clear(), ThreadLauncher::remove(), and ThreadLauncher::stop().

{
  TRACE;
  if(isRunning()) {
    _models.stop();
    wait();
    App::stream(this) << tr("Thread manually stopped.") << endl;
  } else App::stream(this) << tr("WARNING: Trying to stop it but thread is not running") << endl;
}
void InversionThread::unlock ( ) const [inline]

References DinverCore::ModelRepository::validModelCount().

Referenced by ProcessStatus::synchronize().

{
  if(_hasModelsToImport) {
    return _reportValidModelCount;
  } else {
    return _models.validModelCount();
  }
}
const Parameter* InversionThread::variableParameter ( int  paramIndex) const [inline]
double InversionThread::variableParameterValue ( int  modelIndex,
int  paramIndex 
) const [inline]
int InversionThread::visitedModelCount ( ) const [inline]

Re-implement this function to offer XML restore (children and properties) support to your class.

From tag and map (with contains the attibute value) return a unique identifier under the format of a XMLMember. XMLMember is initialized with 3 types of contructors:

  • An integer: id number of a property
  • A XMLClass * : a child of this object identified by tag
  • Default constructor: error, unknow child or property

Map of attributes can be inspected in this way (can be achived also in xml_setProperty()):

    static const QString tmp("childrenName");
    XMLRestoreAttributeIterator it=map.find(tmp);
    if(it!=map.end()) {
      // found attribute "childrenName"
    }

If the map of attributes is not used:

    Q_UNUSED(attributes);
    if(tag=="x1") return XMLMember(0);
    else if(tag=="y1") return XMLMember(1);
    else if(tag=="x2") return XMLMember(2);
    else if(tag=="y2") return XMLMember(3);
    else return XMLMember(XMLMember::Unknown);

Arithmetic operations + and - apply to XMLMember to avoid confusion of property id numbers between inherited objects. Offset 3 corresponds to the number of properties defined in this object.

    if(tag=="anInteger") return XMLMember(0);
    else if(tag=="aString") return XMLMember(1);
    else if(tag=="aDouble") return XMLMember(2);
    return AbstractLine::xml_member(tag, attributes, context)+3;

For the arguments of this function use Macro XML_MEMBER_ARGS.

Reimplemented from QGpCoreTools::XMLClass.

References DinverCore::ModelRepository::forward(), TRACE, and DinverCore::AbstractForward::xml_member().

{
  TRACE;
  if(tag=="ns0" ) return XMLMember(1);
  else if(tag=="ns" ) return XMLMember(2);
  else if(tag=="nr" ) return XMLMember(3);
  else if(tag=="nw" ) return XMLMember(4);
  else if(tag=="giveUp" ) return XMLMember(5);
  else if(tag=="report" ) return XMLMember(7);
  else if(tag=="checksum" ) return XMLMember(9);
  else if(tag=="hasReportFile" ) return XMLMember(10);
  else if(tag=="itmax" ) return XMLMember(0);            // Kept for compatibility
  else if(tag=="seed" ) return XMLMember(8);             // Kept for compatibility
  else if(tag=="runType" ) return XMLMember(8);          // Kept for compatibility
  else if(tag=="jointRun" ) return XMLMember(8);         // Kept for compatibility
  else if(tag=="acceptableMisfit" ) return XMLMember(8); // Kept for compatibility
  else if(tag=="scaling" ) return XMLMember(8);          // Kept for compatibility
  else if(tag=="dynScale" ) return XMLMember(8);         // Kept for compatibility
  else if(tag=="cellDist" ) return XMLMember(8);         // Kept for compatibility
  else {
    return _models.forward()->xml_member(tag, attributes, context)+15;
  }
}
void InversionThread::xml_polish ( XML_POLISH_ARGS  ) [protected, virtual]

Reimplemented from QGpCoreTools::XMLClass.

References DinverCore::ModelRepository::forward(), DinverCore::ModelRepository::setStorage(), TRACE, and DinverCore::AbstractForward::xml_polish().

{
  TRACE;
  if(_itmax>0) {  // Kept for compatibility
    _ns*=_itmax;
    _itmax=0;
  }
  StreamRedirection sr(&App::stream(this));
  _models.forward()->xml_polish(context);
  _models.setStorage();
}
bool InversionThread::xml_setProperty ( XML_SETPROPERTY_ARGS  ) [protected, virtual]

Re-implement this function to offer XML restore properties support to your class.

From memberID set the corresponding property with value content. The map of attributes is given as a supplementary information (not useful in all cases).

For a general case:

  Q_UNUSED(attributes);
  double val=content.toDouble();
  switch (memberID) {
  case 0:
    _x1=val;
    return true;
  case 1:
    _y1=val;
    return true;
  case 2:
    _x2=val;
    return true;
  case 3:
    _y2=val;
    return true;
  default:
    return false;
  }

For classes inheriting other classes (see also xml_member())

  switch (memberID) {
  case 0:
    _anInteger=content.toString();
    return true;
  case 1:
    _aString=content.toInt();
    return true;
  case 2:
    _aDouble=content.toDouble();
    return true;
  default:
    return AbstractLine::xml_setProperty(memberID-3, map, content);

For the arguments of this function use Macro XML_SETPROPERTY_ARGS.

Reimplemented from QGpCoreTools::XMLClass.

References dinverGui, DinverCore::ModelRepository::forward(), setObjectName(), TRACE, and DinverCore::AbstractForward::xml_setProperty().

{
  TRACE;
  switch (memberID) {
  case 0:
    _itmax=content.toInt(); // Kept for compatibility
    return true;
  case 1:
    _ns0=content.toInt();
    return true;
  case 2:
    _ns=content.toInt();
    return true;
  case 3:
    _nr=content.toInt();
    return true;
  case 4:
    _nw=content.toInt();
    return true;
  case 5:
    _giveUp=content.toDouble();
    return true;
  case 7: {
      _reportFileName=content.toString();
      QFileInfo fi(_reportFileName);
      QObject::setObjectName(fi.baseName());
      dinverGui->logs()->setViewName(this, fi.baseName());
      _hasReportFile=true; // set a default value (compatibility)
    }
    return true;
  case 8:   // Kept for compatibility
    return true;
  case 9:
    // Checksum not read from file
    return true;
  case 10:
    _hasReportFile=content.toBool();
    return true;
  default:
    return _models.forward()->xml_setProperty(memberID-15, tag, attributes, content, context);
  }
}
virtual const QString& InversionThread::xml_tagName ( ) const [inline, virtual]
void InversionThread::xml_writeChildren ( XML_WRITECHILDREN_ARGS  ) const [protected, virtual]
void InversionThread::xml_writeProperties ( XML_WRITEPROPERTIES_ARGS  ) const [protected, virtual]

Reimplemented from QGpCoreTools::XMLClass.

References DinverCore::ModelRepository::checksum(), DinverCore::ModelRepository::forward(), reportFileName(), TRACE, QGpCoreTools::XMLClass::writeProperty(), and DinverCore::AbstractForward::xml_writeProperties().

{
  TRACE;
  writeProperty(s, "ns0",_ns0);
  writeProperty(s, "ns",_ns);
  writeProperty(s, "nr",_nr);
  writeProperty(s, "nw",_nw);
  writeProperty(s, "giveUp",_giveUp);
  writeProperty(s, "report",reportFileName());
  writeProperty(s, "checksum",(int)_models.checksum());
  writeProperty(s, "hasReportFile",_hasReportFile);
  _models.forward()->xml_writeProperties(s, context);
}

Member Data Documentation

const QString InversionThread::xmlInversionThreadTag = "InversionThread" [static]

Referenced by xml_tagName().


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines