Logo Search packages:      
Sourcecode: kboincspy version File versions  Download package

kbssetiprojectmonitor.cpp

/***************************************************************************
 *   Copyright (C) 2004 by Roberto Virga                                   *
 *   rvirga@users.sf.net                                                   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include <qregexp.h>

#include <kbsboincmonitor.h>

#include <kbssetigaussianlog.h>
#include <kbssetilogmanager.h>

#include "kbssetiprojectmonitor.h"

const QString SETIWorkunitOpenName = "work_unit.sah";
const QString SETIResultOpenName = "result.sah";

KBSSETIProjectMonitor::KBSSETIProjectMonitor(const QString &project, KBSBOINCMonitor *parent, const char *name)
                     : KBSProjectMonitor(project, parent, name)
{
  m_results.setAutoDelete(true);
  
  connect(parent, SIGNAL(workunitsRemoved(const QStringList &)),
          this, SLOT(removeWorkunits(const QStringList &)));  
  
  connect(parent, SIGNAL(resultsCompleted(const QStringList &)),
          this, SLOT(logResults(const QStringList &)));
  
  connect(this, SIGNAL(fileUpdated(const QString &)), this, SLOT(updateFile(const QString &)));
}

const SETIResult *KBSSETIProjectMonitor::result(const QString &workunit) const
{
  return validWorkunit(workunit) ? m_results.find(workunit) : NULL;
}

void KBSSETIProjectMonitor::setState(const QString &workunit, const SETIState &state)
{
  SETIResult *result = m_results.find(workunit);
  if(NULL == result) {
    result = new SETIResult();
    m_results.insert(workunit, result);
  }
  
  if(state.best_gaussian.gaussian.time_jd != result->state.best_gaussian.gaussian.time_jd
     || (result->state.best_gaussian.gaussian.time_jd > 0
         && state.best_gaussian.bg.score > result->state.best_gaussian.bg.score))
    KBSSETIGaussianLog::self()->logGaussian(KBSSETIGaussianLog::Best,
                                            result->workunit_header,
                                            state.best_gaussian.gaussian);
  
  result->state = state;
  
  emit updatedResult(workunit);
}

KBSLogManager *KBSSETIProjectMonitor::logManager() const
{
  return KBSSETILogManager::self();
}

bool KBSSETIProjectMonitor::parseable(const QString &openName) const
{
  return(openName == SETIWorkunitOpenName || openName == SETIResultOpenName);
}

bool KBSSETIProjectMonitor::parseFile(KBSFileInfo *file, const QString &fileName)
{
  qDebug("Parsing file %s...", file->fileName.latin1());
  
  if(!m_meta.contains(file->fileName)) return false;
  const KBSFileMetaInfo meta = m_meta[file->fileName];
    
  QDomDocument document(file->fileName);
  if(SETIWorkunitOpenName == meta.open_name)
  {
    // avoid reading the "garbage" that comes after the header
    QStringList lines;    
    if(!readFile(fileName, lines, "</workunit_header>")) return false;
    lines << "</workunit_header>";
    
    // some massaging to convert it to valid XML
    QString text = lines.join("\n");
    text.replace(QRegExp("length=[0-9]+"), "");
    text.remove("<workunit>");
    
    QString message;
    int line, column;
    if(!document.setContent(text, false, &message, &line, &column))
    {
      qDebug("Error at line %d, column %d: %s", line, column, message.latin1());
      return false;
    }
    
    SETIWorkunitHeader header;
    if(!parseWorkunitDocument(document, header)) return false;
    
    setHeader(header, meta.workunits);
    
    qDebug("... parse OK");
    return true;
  }
  else if(SETIResultOpenName == meta.open_name)
  {
    QString text;
    if(!readFile(fileName, text)) return false;    
    
    // some massaging to convert it to valid XML
    text.replace(QRegExp("length=[0-9]+"), "");
    if(!text.contains("</result>")) text.append("</result>");
    
    QString message;
    int line, column;
    if(!document.setContent(text, false, &message, &line, &column))
    {
      qDebug("Error at line %d, column %d: %s", line, column, message.latin1());
      return false;
    }
    
    SETIResult result;
    if(!parseResultDocument(document, result)) return false;
    
    setResult(result, meta.workunits);
    
    qDebug("... parse OK");
    return true;
  }
  else
    return false;
}

SETIResult *KBSSETIProjectMonitor::mkResult(const QString &workunit)
{
  SETIResult *result = m_results.find(workunit);
  if(NULL == result) {
    result = new SETIResult();
    
    result->state.best_spike.spike.time_jd = 0.0;
    result->state.best_gaussian.gaussian.time_jd = 0.0;
    result->state.best_pulse.pulse.time_jd = 0.0;
    result->state.best_triplet.triplet.time_jd = 0.0;
    
    m_results.insert(workunit, result);
  }
  
  return result;
}

bool KBSSETIProjectMonitor::parseWorkunitDocument(const QDomDocument &document, SETIWorkunitHeader &header)
{
  for(QDomNode child = document.firstChild(); !child.isNull(); child = child.nextSibling())
    if(child.isElement()) {
      QDomElement element = child.toElement();
      const QString elementName = element.nodeName().lower(); 
      
      if(elementName == "workunit_header") {
        if(!header.parse(element)) return false;
      }
    }
  
  return true;
}

bool KBSSETIProjectMonitor::parseResultDocument(const QDomDocument &document, SETIResult &result)
{
  result.spike.clear();
  result.gaussian.clear();
  result.pulse.clear();
  result.triplet.clear();
  
  for(QDomNode child = document.firstChild(); !child.isNull(); child = child.nextSibling())
    if(child.isElement()) {
      QDomElement element = child.toElement();
      const QString elementName = element.nodeName().lower(); 
      
      if(elementName == "result") {
        if(!result.parse(element)) return false;
      }     
    }
  
  return true;
}

void KBSSETIProjectMonitor::setHeader(const SETIWorkunitHeader &header, const QStringList &workunits)
{
  for(QStringList::const_iterator workunit = workunits.begin();
      workunit != workunits.end(); ++ workunit)
    mkResult(*workunit)->workunit_header = header;
}

void KBSSETIProjectMonitor::setResult(const SETIResult &result, const QStringList &workunits)
{
  for(QStringList::const_iterator workunit = workunits.begin();
      workunit != workunits.end(); ++ workunit)
    *mkResult(*workunit) = result;
}
        
void KBSSETIProjectMonitor::removeWorkunits(const QStringList &workunits)
{
  for(QStringList::const_iterator workunit = workunits.constBegin();
      workunit != workunits.constEnd(); ++workunit)
    m_results.remove(*workunit);
}

void KBSSETIProjectMonitor::logResults(const QStringList &results)
{
  const BOINCClientState *state = boincMonitor()->state();
  if(NULL == state) return;
  
  for(QStringList::const_iterator result = results.constBegin(); result != results.constEnd(); ++result)
  {
    if(boincMonitor()->project(state->result[*result]) != project()) continue;
    
    SETIResult *setiResult = m_results.find(state->result[*result].wu_name);
    if(NULL == setiResult) continue;
    
    for(QValueList<SETIGaussian>::const_iterator gaussian= setiResult->gaussian.constBegin();
        gaussian != setiResult->gaussian.constEnd(); ++gaussian)
      KBSSETIGaussianLog::self()->logGaussian(KBSSETIGaussianLog::Returned,
                                              setiResult->workunit_header,
                                              *gaussian);
  }
}

void KBSSETIProjectMonitor::updateFile(const QString &fileName)
{
  if(!m_meta.contains(fileName)) return;
  
  QStringList workunits = m_meta[fileName].workunits;
  for(QStringList::const_iterator workunit = workunits.begin();
      workunit != workunits.end(); ++ workunit)
    emit updatedResult(*workunit);
}

#include "kbssetiprojectmonitor.moc"

Generated by  Doxygen 1.6.0   Back to index