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

kbssetilogx.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 <math.h>

#include <qtextstream.h>
 
#include <setidata.h>
#include <boincdata.h>

#include <kbsboincmonitor.h>
#include <kbssetiprojectmonitor.h>

#include "kbssetilogx.h"

const QString KBSSETILogX::s_version = "1.11";
const QString KBSSETILogX::s_filename[] =
  {"sah_boinc.csv",
   "sah_boinc_spike.csv", "sah_boinc_gaussian.csv", "sah_boinc_pulse.csv", "sah_boinc_triplet.csv"};

KBSSETILogX::KBSSETILogX(const KURL &url, QObject *parent, const char *name)
           : KBSLogMonitor(url, parent, name)
{
  initKeys();
  
  for(unsigned i = Spike; i <= Triplet; ++i)
    m_count[i] = 0;
  
  for(unsigned i = SETIFile; i <= TripletFile; ++i)
    addLogFile(s_filename[i]);

  connect(this, SIGNAL(fileUpdated(const QString &)), this, SLOT(updateFile(const QString &)));
}

QStringList KBSSETILogX::keys() const
{
  return m_keys[SETIFile];
}

bool KBSSETILogX::hasResults() const
{
  return true;
}

bool KBSSETILogX::parseFile(KBSFileInfo *file, const QString &fileName)
{
  qDebug("Parsing file %s...", file->fileName.latin1());
  
  QStringList lines;
  if(!readFile(fileName, lines)) return false;
  
  if(s_filename[SETIFile] == file->fileName)
    return parseSETILogDocument(lines);
  else
    for(unsigned i = SpikeFile; i <= TripletFile; ++i)
      if(s_filename[i] == file->fileName)
        return parseResultsLogDocument(i-SpikeFile, lines);
        
  return false;
}

KBSLogDatum KBSSETILogX::formatWorkunitDatum(KBSSETIProjectMonitor *projectMonitor,
                                             const QString &workunit) const
{
  const QString project = projectMonitor->project();
  const KBSBOINCMonitor *boincMonitor =  projectMonitor->boincMonitor();
  const BOINCClientState *state = boincMonitor->state();
  if(NULL == state) return KBSLogDatum();
  
  const QString result = state->workunit[workunit].result_name;
  
  const SETIResult *datum = projectMonitor->result(workunit);
  if(NULL == datum) return KBSLogDatum();
  
  KBSLogDatum out;
  
  out["date"] = formatLogEntryDate(QDateTime::currentDateTime());
  out["project_name"] = state->project[project].project_name;
  out["app_name"] = state->workunit[workunit].app_name;
  out["domain_name"] = state->host_info.domain_name;
  out["p_ncpus"] = state->host_info.p.ncpus;
  out["p_vendor"] = state->host_info.p.vendor;
  out["p_model"] = state->host_info.p.model;
  out["p_fpops"] = state->host_info.p.fpops;
  out["p_iops"] = state->host_info.p.iops;
  out["p_membw"] = state->host_info.p.membw;
  out["p_calculated"] = state->host_info.p.calculated;
  out["os_name"] = state->host_info.os.name;
  out["os_version"] = state->host_info.os.version;
  out["m_nbytes"] = state->host_info.m.nbytes;
  out["m_cache"] = state->host_info.m.cache;
  out["m_swap"] = state->host_info.m.swap;
  out["d_total"] = state->host_info.d.total;
  out["d_free"] = state->host_info.d.free;
  out["on_frac"] = state->time_stats.on_frac;
  out["connected_frac"] = state->time_stats.connected_frac;
  out["active_frac"] = state->time_stats.active_frac;
  out["last_update"] = formatUNIXDate(state->time_stats.last_update);
  out["bwup"] = state->net_stats.bwup;
  out["bwdown"] = state->net_stats.bwdown;
  out["user_name"] = state->project[project].user_name;
  out["team_name"] = state->project[project].team_name;
  out["user_total_credit"] = state->project[project].user.total_credit;
  out["user_expavg_credit"] = state->project[project].user.expavg_credit;
  out["user_create_time"] = formatUNIXDate(state->project[project].user.create_time);
  out["rpc_seqno"] = state->project[project].rpc_seqno;
  out["hostid"] = state->project[project].hostid;
  out["host_total_credit"] = state->project[project].host.total_credit;
  out["host_expavg_credit"] = state->project[project].host.expavg_credit;
  out["host_create_time"] = formatUNIXDate(state->project[project].host.create_time);
  out["exp_avg_cpu"] = state->project[project].exp_avg.cpu;
  out["exp_avg_mod_time"] = state->project[project].exp_avg.mod_time;
  out["host_venue"] = state->host_venue;
  out["boinc_version"] = formatVersion(state->core_client.major_version, state->core_client.minor_version);
  out["logX_version"] = s_version;
  out["app_version"] = formatVersion(state->workunit[workunit].version_num);
  out["sah_version"] = formatVersion(state->workunit[workunit].version_num);
  out["wu_name"] = workunit;
  if(state->result[result].file_ref.count() > 0)
    out["result_name"] = state->result[result].file_ref.first().file_name;
  else
    out["result_name"] = result;
  out["start_ra"] = datum->workunit_header.group_info.data_desc.start.ra;
  out["start_dec"] = datum->workunit_header.group_info.data_desc.start.dec;
  out["end_ra"] = datum->workunit_header.group_info.data_desc.end.ra;
  out["end_dec"] = datum->workunit_header.group_info.data_desc.end.dec;
  out["angle_range"] = datum->workunit_header.group_info.data_desc.true_angle_range;
  out["time_recorded"] = formatJulianDate(datum->workunit_header.group_info.data_desc.time_recorded);
  out["subband_center"] = datum->workunit_header.subband_desc.center;
  out["subband_base"] = datum->workunit_header.subband_desc.base;
  out["subband_sample_rate"] = datum->workunit_header.subband_desc.sample_rate;
  out["fft_len"] = datum->workunit_header.group_info.splitter_cfg.fft_len;
  out["ifft_len"] = datum->workunit_header.group_info.splitter_cfg.ifft_len;
  out["subband_number"] = datum->workunit_header.subband_desc.number;
  out["cpu"] = state->result[result].final_cpu_time;
  out["fpops_est"] = state->workunit[workunit].rsc.fpops_est;
  out["error"] = "false";
  if(datum->state.best_spike.spike.time_jd > 0) {
    out["bs_score"] = datum->state.best_spike.bs.score;
    out["bs_power"] = datum->state.best_spike.spike.peak_power;
    out["bs_bin"] = datum->state.best_spike.bs.bin;
    out["bs_fft_ind"] = datum->state.best_spike.bs.fft_ind;
    out["bs_chirp_rate"] = datum->state.best_spike.spike.chirp_rate;
    out["bs_fft_len"] = datum->state.best_spike.spike.fft_len;
  }
  out["spike_count"] = unsigned(datum->spike.count());
  if(datum->state.best_gaussian.gaussian.time_jd > 0) {
    out["bg_score"] = datum->state.best_gaussian.bg.score;
    out["bg_power"] = datum->state.best_gaussian.gaussian.peak_power;
    out["bg_chisq"] = datum->state.best_gaussian.gaussian.chisqr;
    out["bg_bin"] = datum->state.best_gaussian.bg.bin;
    out["bg_fft_ind"] = datum->state.best_gaussian.bg.fft_ind;
    out["bg_chirp_rate"] = datum->state.best_gaussian.gaussian.chirp_rate;
    out["bg_fft_len"] = datum->state.best_gaussian.gaussian.fft_len;
    out["bg_sigma"] = datum->state.best_gaussian.gaussian.sigma;
    out["bg_true_mean"] = datum->state.best_gaussian.gaussian.mean_power;
  }
  out["gaussian_count"] = unsigned(datum->gaussian.count());
  if(datum->state.best_pulse.pulse.time_jd > 0) {
    out["bp_score"] = datum->state.best_pulse.bp.score;
    out["bp_power"] = datum->state.best_pulse.pulse.peak_power;
    out["bp_mean"] = datum->state.best_pulse.pulse.mean_power;
    out["bp_period"] = datum->state.best_pulse.pulse.period;
    out["bp_chirp_rate"] = datum->state.best_pulse.pulse.chirp_rate;
    out["bp_fft_len"] = datum->state.best_pulse.pulse.fft_len;
    out["bp_snr"] = datum->state.best_pulse.pulse.snr;
    out["bp_thresh"] = datum->state.best_pulse.pulse.thresh;
  }
  out["pulse_count"] = unsigned(datum->pulse.count());
  if(datum->state.best_triplet.triplet.time_jd > 0) {
    out["bt_score"] = datum->state.best_triplet.bt.score;
    out["bt_power"] = datum->state.best_triplet.triplet.peak_power;
    out["bt_mean"] = datum->state.best_triplet.triplet.mean_power;
    out["bt_period"] = datum->state.best_triplet.triplet.period;
    out["bt_bperiod"] = datum->state.best_triplet.bt.bperiod;
    out["bt_chirp_rate"] = datum->state.best_triplet.triplet.chirp_rate;
    out["bt_scale"] = datum->state.best_triplet.bt.scale;
    out["bt_fft_len"] = datum->state.best_triplet.triplet.fft_len;
  }
  out["triplet_count"] = unsigned(datum->triplet.count());
  
  return out;
}

KBSLogData KBSSETILogX::formatSpikeData(KBSSETIProjectMonitor *projectMonitor,
                                        const QString &workunit) const
{
  const BOINCClientState *state = projectMonitor->boincMonitor()->state();
  if(NULL == state) return KBSLogData();
  
  const QString result = state->workunit[workunit].result_name;
  
  const SETIResult *datum = projectMonitor->result(workunit);
  if(NULL == datum) return KBSLogData();
  
  KBSLogData out;
  for(QValueList<SETISpike>::const_iterator it = datum->spike.constBegin();
      it != datum->spike.constEnd(); ++it)
  {
    KBSLogDatum spike;
    
    if(state->result[result].file_ref.count() > 0)
      spike["result_name"] = state->result[result].file_ref.first().file_name;
    else
      spike["result_name"] = result;
    spike["power"]  = (*it).peak_power;
    spike["ra"] = (*it).ra;
    spike["dec"] = (*it).decl;
    spike["time"] = formatJulianDate((*it).time);
    spike["freq"] = (*it).freq;
    spike["fft_len"] = (*it).fft_len;
    spike["chirp_rate"] = (*it).chirp_rate;
    
    out << spike;
  }
  
  return out;
}

KBSLogData KBSSETILogX::formatGaussianData(KBSSETIProjectMonitor *projectMonitor,
                                           const QString &workunit) const
{
  const BOINCClientState *state = projectMonitor->boincMonitor()->state();
  if(NULL == state) return KBSLogData();
  
  const QString result = state->workunit[workunit].result_name;
  
  const SETIResult *datum = projectMonitor->result(workunit);
  if(NULL == datum) return KBSLogData();
  
  KBSLogData out;
  for(QValueList<SETIGaussian>::const_iterator it = datum->gaussian.constBegin();
      it != datum->gaussian.constEnd(); ++it)
  {
    KBSLogDatum gaussian;
    
    if(state->result[result].file_ref.count() > 0)
      gaussian["result_name"] = state->result[result].file_ref.first().file_name;
    else
      gaussian["result_name"] = result;
    gaussian["score"]  = (*it).score();
    gaussian["peak"] = (*it).peak_power;
    gaussian["chisqr"] = (*it).chisqr;
    gaussian["mean"] = (*it).mean_power;
    gaussian["ra"] = (*it).ra;
    gaussian["dec"] = (*it).decl;
    gaussian["time"] = formatJulianDate((*it).time);
    gaussian["freq"] = (*it).freq;
    gaussian["sigma"] = (*it).sigma;
    gaussian["fft_len"] = (*it).fft_len;
    gaussian["chirp_rate"] = (*it).chirp_rate;
    gaussian["maxpow"] = (*it).max_power;
    gaussian["pot"] = formatPotData((*it).pot);
    
    out << gaussian;
  }
  
  return out;
}

KBSLogData KBSSETILogX::formatPulseData(KBSSETIProjectMonitor *projectMonitor,
                                        const QString &workunit) const
{
  const BOINCClientState *state = projectMonitor->boincMonitor()->state();
  if(NULL == state) return KBSLogData();
  
  const QString result = state->workunit[workunit].result_name;
  
  const SETIResult *datum = projectMonitor->result(workunit);
  if(NULL == datum) return KBSLogData();
  
  KBSLogData out;
  for(QValueList<SETIPulse>::const_iterator it = datum->pulse.constBegin();
      it != datum->pulse.constEnd(); ++it)
  {
    KBSLogDatum pulse;
    
    if(state->result[result].file_ref.count() > 0)
      pulse["result_name"] = state->result[result].file_ref.first().file_name;
    else
      pulse["result_name"] = result;
    pulse["score"]  = (*it).score();
    pulse["power"]  = (*it).peak_power;
    pulse["mean"]  = (*it).mean_power;
    pulse["period"]  = (*it).period;
    pulse["ra"] = (*it).ra;
    pulse["dec"] = (*it).decl;
    pulse["time"] = formatJulianDate((*it).time);
    pulse["freq"] = (*it).freq;
    pulse["fft_len"] = (*it).fft_len;
    pulse["chirp_rate"] = (*it).chirp_rate;
    pulse["snr"] = (*it).snr;
    pulse["thresh"] = (*it).thresh;
    pulse["len_prof"] = unsigned((*it).pot.count());
    pulse["prof"] = formatPotData((*it).pot);
    
    out << pulse;
  }
  
  return out;
}

KBSLogData KBSSETILogX::formatTripletData(KBSSETIProjectMonitor *projectMonitor,
                                          const QString &workunit) const
{
  const BOINCClientState *state = projectMonitor->boincMonitor()->state();
  if(NULL == state) return KBSLogData();
  
  const QString result = state->workunit[workunit].result_name;
  
  const SETIResult *datum = projectMonitor->result(workunit);
  if(NULL == datum) return KBSLogData();
  
  KBSLogData out;
  for(QValueList<SETITriplet>::const_iterator it = datum->triplet.constBegin();
      it != datum->triplet.constEnd(); ++it)
  {
    KBSLogDatum triplet;
    
    if(state->result[result].file_ref.count() > 0)
      triplet["result_name"] = state->result[result].file_ref.first().file_name;
    else
      triplet["result_name"] = result;
    triplet["power"]  = (*it).peak_power;
    triplet["mean"]  = (*it).mean_power;
    triplet["period"]  = (*it).period;
    triplet["ra"] = (*it).ra;
    triplet["dec"] = (*it).decl;
    triplet["time"] = formatJulianDate((*it).time);
    triplet["freq"] = (*it).freq;
    triplet["fft_len"] = (*it).fft_len;
    triplet["chirp_rate"] = (*it).chirp_rate;
    
    out << triplet;
  }
  
  return out;
}

QMap<QString,KBSLogData> KBSSETILogX::formatWorkunit(KBSProjectMonitor *monitor,
                                                     const QString &workunit) const
{
  KBSSETIProjectMonitor *projectMonitor = static_cast<KBSSETIProjectMonitor*>(monitor);
  QMap<QString,KBSLogData> out;
  
  out[s_filename[SETIFile]] << formatWorkunitDatum(projectMonitor, workunit);
  
  out[s_filename[SpikeFile]] = formatSpikeData(projectMonitor, workunit);
  out[s_filename[GaussianFile]] = formatGaussianData(projectMonitor, workunit);
  out[s_filename[PulseFile]] = formatPulseData(projectMonitor, workunit);
  out[s_filename[TripletFile]] = formatTripletData(projectMonitor, workunit);
  
  return out;
}

void KBSSETILogX::appendHeader(const KBSFileInfo *info, QIODevice *io)
{
  QTextStream text(io);
  for(unsigned i = SETIFile; i <= TripletFile; ++i)
    if(info->fileName == s_filename[i]) {
      text << formatCSVKeys(m_keys[i]) << "\r\n";
      break;
    }
}

void KBSSETILogX::appendWorkunit(const KBSFileInfo *info, QIODevice *io, const KBSLogDatum &datum)
{
  QTextStream text(io);
  
  if(info->fileName == s_filename[SETIFile])
    text << formatCSVDatum(datum, m_keys[SETIFile]) << "\r\n";
  else if(info->fileName == s_filename[SpikeFile])
    text << formatCSVDatum(datum, m_keys[SpikeFile]) << "\r\n";
  else if(info->fileName == s_filename[GaussianFile])
    text << formatCSVDatum(datum, m_keys[GaussianFile]) << "\r\n";
  else if(info->fileName == s_filename[PulseFile])
    text << formatCSVDatum(datum, m_keys[PulseFile]) << "\r\n";
  else if(info->fileName == s_filename[TripletFile])
    text << formatCSVDatum(datum, m_keys[TripletFile]) << "\r\n";
}

void KBSSETILogX::initKeys()
{
  m_keys[SETIFile].clear(); m_keys[SETIFile]
    << "date" << "domain_name" << "p_ncpus" << "p_vendor" << "p_model" << "p_fpops" 
    << "p_iops" << "p_membw" << "p_calculated" << "os_name" << "os_version"
    << "m_nbytes" << "m_cache" << "m_swap" << "d_total" << "d_free" << "on_frac"
    << "connected_frac" << "active_frac" << "last_update" << "bwup" << "bwdown"
    << "user_name" << "team_name" << "user_total_credit"
    << "user_expavg_credit" << "user_create_time" << "rpc_seqno" << "hostid"
    << "host_total_credit" << "host_expavg_credit" << "host_create_time"
    << "exp_avg_cpu" << "exp_avg_mod_time" << "host_venue" << "boinc_version"
    << "logX_version" << "sah_version" << "wu_name" << "result_name"
    << "start_ra" << "start_dec" << "end_ra" << "end_dec" << "angle_range"
    << "time_recorded" << "subband_center" << "subband_base"
    << "subband_sample_rate" << "fft_len" << "ifft_len" << "subband_number"
    << "cpu" << "error" << "fpops_est" << "bs_score" << "bs_power" << "bs_bin"
    << "bs_fft_ind" << "bs_chirp_rate" << "bs_fft_len" << "spike_count"
    << "bg_score" << "bg_power" << "bg_chisq" << "bg_bin" << "bg_fft_ind"
    << "bg_chirp_rate" << "bg_fft_len" << "bg_sigma" << "bg_true_mean"
    << "gaussian_count" << "bp_score" << "bp_power" << "bp_mean" << "bp_period"
    << "bp_chirp_rate" << "bp_fft_len" << "bp_snr" << "bp_thresh"
    << "pulse_count" << "bt_score" << "bt_power" << "bt_mean" << "bt_period"
    << "bt_bperiod" << "bt_chirp_rate" << "bt_scale" << "bt_fft_len"
    << "triplet_count";
            
  m_keys[SpikeFile].clear(); m_keys[SpikeFile]
    << "result_name" << "power" << "ra" << "dec" << "time" << "freq" << "fft_len"
    << "chirp_rate";
  
  m_keys[GaussianFile].clear(); m_keys[GaussianFile]
    << "result_name" << "score" << "peak" << "chisqr" << "mean" << "ra" << "dec"
    << "time" << "freq" << "sigma" << "fft_len" << "chirp_rate" << "maxpow" << "pot";
  
  m_keys[PulseFile].clear(); m_keys[PulseFile]
    << "result_name" << "score" << "power" << "mean" << "period" << "ra" << "dec"
    << "time" << "freq" << "fft_len" << "chirp_rate" << "snr" << "thresh"
    << "len_prof" << "prof";
  
  m_keys[TripletFile].clear(); m_keys[TripletFile]
    << "result_name" << "power" << "mean" << "period" << "ra" << "dec" << "time"
    << "freq" << "fft_len" << "chirp_rate";
}

QString KBSSETILogX::workunitName(const QString &result)
{
  const int pos = result.find('_');
  return (pos >= 0) ? result.left(pos) : result;
}
 
bool KBSSETILogX::parseSETILogDocument(const QStringList &lines)
{
  QStringList::const_iterator line = lines.begin();
  
  if(lines.end() == line) return true;
  const unsigned keys = m_keys[SETIFile].count();
  m_keys[SETIFile] = parseCSVKeys(*line);
  if(keys > m_keys[SETIFile].count()) return false;
  ++line;
  
  for(unsigned i = 0; i < m_workunits.count(); ++i)
    if(lines.end() != line) ++line;
    else return true;
    
  while(lines.end() != line) {
    KBSLogDatum datum = parseCSVDatum(*line, m_keys[SETIFile]);
    ++line;
    
    datum["date"] = parseLogEntryDate(datum["date"].toString());
    datum["last_update"] = parseUNIXDate(datum["last_update"].toDouble());
    datum["user_create_time"] = parseUNIXDate(datum["user_create_time"].toDouble());
    datum["host_create_time"] = parseUNIXDate(datum["host_create_time"].toDouble());
    datum["time_recorded"] = parseJulianDate(datum["time_recorded"].toDouble());
    
    m_workunits << datum;
  }
  
  qDebug("... parse OK");
  
  return true;
}

bool KBSSETILogX::parseResultsLogDocument(unsigned type, const QStringList &lines)
{
  QStringList::const_iterator line = lines.begin();
  
  if(lines.end() == line) return true;
  const unsigned keys = m_keys[SpikeFile+type].count();
  m_keys[SpikeFile+type] = parseCSVKeys(*line);
  if(keys > m_keys[SpikeFile+type].count()) return false;
  ++line;
  
  for(unsigned i = 0; i < m_count[type]; ++i)
    if(lines.end() != line) ++line;
    else return true;
    
  while(lines.end() != line) {
    KBSLogDatum datum = parseCSVDatum(*line, m_keys[SpikeFile+type]);
    ++line;
    
    QString workunit = workunitName(datum["result_name"].toString());
    if(!workunit.isEmpty()) continue;
    
    datum["time"] = parseJulianDate(datum["time"].toDouble());
    switch(type) {
      case Spike:
        datum["type"] = SETISpike::type;
        break;
      case Gaussian:
        datum["type"] = SETIGaussian::type;
        datum["pot"] = parsePotData(datum["pot"].toString());
        break;
      case Pulse:
        datum["type"] = SETIPulse::type;
        datum["prof"] = parsePotData(datum["prof"].toString());
        break;
      case Triplet:
        datum["type"] = SETITriplet::type;
    }
    
    m_results[workunit] << datum;
    ++m_count[type];
  }
  
  qDebug("... parse OK");
  
  return true;
}

void KBSSETILogX::updateFile(const QString &fileName)
{
  if(s_filename[SETIFile] == fileName)
    emit workunitsUpdated();
  else if(s_filename[SpikeFile] == fileName)
    emit resultsUpdated();
  else if(s_filename[GaussianFile] == fileName)
    emit resultsUpdated();
  else if(s_filename[PulseFile] == fileName)
    emit resultsUpdated();
  else if(s_filename[TripletFile] == fileName)
    emit resultsUpdated();
}

#include "kbssetilogx.moc"

Generated by  Doxygen 1.6.0   Back to index