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

kbssetiresultsplot.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 <qfont.h>
#include <qfontmetrics.h>
#include <qpainter.h>
#include <qpixmap.h>
#include <qsize.h>

#include <kiconloader.h>
#include <klocale.h>

#include <kbsboincmonitor.h>

#include <kbssetiprojectmonitor.h>

#include <kbssetiresultspanelnode.h>

#include "kbssetiresultsplot.h"

const QSize KBSSETIResultsPlotMinSize = QSize(150, 150);
const int KBSSETIResultsPlotMargin = 3;
const int KBSSETIResultsPlotFontSize = 9;
const int KBSSETIResultsPlotArrowLength = 30;
const QString KBSSETIResultsPlotValues = "-50 -10 -3 0 3 10 50";

KBSSETIResultsPlot::KBSSETIResultsPlot(QWidget *parent, const char *name)
                  : QWidget(parent, name), m_projectMonitor(NULL)
{
  setMinimumSize(KBSSETIResultsPlotMinSize);
}

QString KBSSETIResultsPlot::workunit() const
{
  return m_workunit;
}

void KBSSETIResultsPlot::setWorkunit(const QString &workunit)
{
  m_workunit = workunit;
}

QString KBSSETIResultsPlot::project() const
{
  return (NULL != m_projectMonitor) ? m_projectMonitor->project() : QString::null;
}

KBSBOINCMonitor *KBSSETIResultsPlot::monitor() const
{
  return (NULL != m_projectMonitor) ? m_projectMonitor->boincMonitor() : NULL;
}

KBSSETIProjectMonitor *KBSSETIResultsPlot::projectMonitor() const
{
  return m_projectMonitor;
}

void KBSSETIResultsPlot::setProjectMonitor(KBSSETIProjectMonitor *projectMonitor)
{
  m_projectMonitor = projectMonitor;
}

void KBSSETIResultsPlot::update()
{
  repaint();
}

void KBSSETIResultsPlot::paintEvent(QPaintEvent *)
{
  QFont font = this->font();
  font.setPointSize(KBSSETIResultsPlotFontSize);
  
  QFontMetrics metrics(font);
  const int lineHeight = metrics.lineSpacing();
  const int lineBase = metrics.height();

  QPainter painter(this);
  painter.setFont(font);

  painter.save();
  painter.translate(2 * lineHeight, 0);
  {
    const QRect r(0, 0, width() - 2 * lineHeight, lineHeight);

    painter.setPen(black);

    painter.drawText(r, AlignCenter, i18n("Signal Strength"));
  }
  painter.restore();

  painter.save();
  painter.translate(2 * lineHeight, height() - 2 * lineHeight);
  {
    const QRect r(0, 0, width() - 2 * lineHeight, 2 * lineHeight);
    
    painter.setPen(black);
    
    QStringList labels = QStringList::split(' ', KBSSETIResultsPlotValues);
    const unsigned labels_count = labels.count();
    for(unsigned i = 0; i < labels_count; i++)
      painter.drawText((r.width() - metrics.width(labels[i])) * i / (labels_count-1),
                       lineBase, labels[i]);
    
    painter.drawText(r, AlignHCenter | AlignBottom, i18n("Drift Rate (Hz/s)"));
  }
  painter.restore();
  
  painter.save();
  painter.translate(0, height() - 2 * lineHeight);
  painter.rotate(-90);
  {
    const QRect r(0, 0, height() - 3 * lineHeight, 2 * lineHeight);
    
    painter.setPen(black);

    painter.drawText(r, AlignHCenter | AlignTop, i18n("Strength"));
    
    const int arrowStart = (r.width() - KBSSETIResultsPlotArrowLength) / 2;
    const int arrowEnd = arrowStart + KBSSETIResultsPlotArrowLength;
    const int arrowY = lineHeight + lineHeight / 2;
    
    painter.drawLine(arrowStart, arrowY, arrowEnd, arrowY);
    painter.drawLine(arrowEnd, arrowY, arrowEnd - 3, arrowY - 3);
    painter.drawLine(arrowEnd, arrowY, arrowEnd - 3, arrowY + 3);
  }
  painter.restore();
  
  QPixmap plot(QSize(this->width() - 2 * lineHeight - 2 * KBSSETIResultsPlotMargin,
                     this->height() - 3 * lineHeight));
  
  {
    QPainter painter(&plot);
    painter.setFont(font);
    
    painter.fillRect(plot.rect(), black);
    painter.fillRect(0, 0, plot.width(), plot.height() / 2, darkBlue);
    
    painter.setPen(lightGray);
    
    const QRect textRect(3, 3, plot.width() - 2 * 3, plot.height() - 3 * 3);
    painter.drawText(textRect, AlignLeft | AlignTop, i18n("Returned"));
    painter.drawText(textRect, AlignRight | AlignBottom, i18n("Not returned"));
  }
  
  const SETIResult *setiResult = (NULL != m_projectMonitor) ? m_projectMonitor->result(m_workunit) : NULL;
  
  if(NULL != setiResult)
  {
    QPixmap line(1, 2 * plot.height());
    line.fill(red);
    
    paintResult(setiResult->state.cr, 0.5, line, &plot);
  }
  
  if(NULL != setiResult)
  {
    const SETIAnalysisCfg *analysis_cfg = &(setiResult->workunit_header.group_info.analysis_cfg);
    
    if(setiResult->state.best_spike.spike.time_jd > 0)
      paintResult(setiResult->state.best_spike.spike.chirp_rate,
                  power(analysis_cfg, setiResult->state.best_spike.spike),
                  KBSSETIResultsPanelNode::spike, &plot);
      
    if(setiResult->state.best_gaussian.gaussian.time_jd > 0)
      paintResult(setiResult->state.best_gaussian.gaussian.chirp_rate,
                  power(analysis_cfg, setiResult->state.best_gaussian.gaussian),
                  KBSSETIResultsPanelNode::gaussian, &plot);
    
    if(setiResult->state.best_pulse.pulse.time_jd > 0)
      paintResult(setiResult->state.best_pulse.pulse.chirp_rate,
                  power(analysis_cfg, setiResult->state.best_pulse.pulse),
                  KBSSETIResultsPanelNode::pulse, &plot);
    
    if(setiResult->state.best_triplet.triplet.time_jd > 0)
      paintResult(setiResult->state.best_triplet.triplet.chirp_rate,
                  power(analysis_cfg, setiResult->state.best_triplet.triplet),
                  KBSSETIResultsPanelNode::triplet, &plot);
      
    for(QValueList<SETISpike>::const_iterator spike = setiResult->spike.constBegin();
        spike != setiResult->spike.constEnd(); ++spike)
      paintResult((*spike).chirp_rate, power(analysis_cfg, *spike),
                  KBSSETIResultsPanelNode::spike, &plot);
    
    for(QValueList<SETIGaussian>::const_iterator gaussian = setiResult->gaussian.constBegin();
        gaussian != setiResult->gaussian.constEnd(); ++gaussian)
      paintResult((*gaussian).chirp_rate, power(analysis_cfg, *gaussian),
                  KBSSETIResultsPanelNode::gaussian, &plot);
      
    for(QValueList<SETIPulse>::const_iterator pulse = setiResult->pulse.constBegin();
        pulse != setiResult->pulse.constEnd(); ++pulse)
      paintResult((*pulse).chirp_rate, power(analysis_cfg, *pulse),
                  KBSSETIResultsPanelNode::pulse, &plot);
      
    for(QValueList<SETITriplet>::const_iterator triplet = setiResult->triplet.constBegin();
        triplet != setiResult->triplet.constEnd(); ++triplet)
      paintResult((*triplet).chirp_rate, power(analysis_cfg, *triplet),
                  KBSSETIResultsPanelNode::triplet, &plot);
  }
  
  painter.drawPixmap(2 * lineHeight + KBSSETIResultsPlotMargin, lineHeight + 3, plot);
}

void KBSSETIResultsPlot::paintResult(double chirp_rate, double power, const QPixmap& target, QPixmap *plot)
{
  chirp_rate = (chirp_rate > 50.0) ? 50.0 : chirp_rate;
  chirp_rate = (chirp_rate < -50.0) ? -50.0 : chirp_rate;

  const double d1 = log10((chirp_rate > 0) ? chirp_rate + 1.0 : 1.0 - chirp_rate);
  const double d2 =  (0.03131 * d1 + 0.23888) * d1;

  const int xpos = (chirp_rate > 0) ? int(plot->width() * (0.5 + d2)) : int(plot->width() * (0.5 - d2));

  if(power > 1.0) power = 1.0;
  else if(power < 0.0) power = 0.0;

  const int ypos = int(plot->height() * (1.0 - power));

  QPainter(plot).drawPixmap(xpos - target.width() / 2, ypos - target.height() / 2, target);
}

double KBSSETIResultsPlot::power(const SETIAnalysisCfg *analysis_cfg, const SETISpike &spike)
{
  const double ratio = spike.peak_power / analysis_cfg->spike_thresh;
  return(0.5 + 1.0 * log10(ratio)); // coefficient to be determined later
}

double KBSSETIResultsPlot::power(const SETIAnalysisCfg *analysis_cfg, const SETIGaussian &gaussian)
{
  double ratio;
  
  ratio = analysis_cfg->gauss.null_chi_sq_thresh / gaussian.null_chisqr;
  if(ratio > 1.0) return(0.5 - 0.3 * log10(ratio)); // coefficient to be determined later
  
  ratio = gaussian.chisqr / analysis_cfg->gauss.chi_sq_thresh;
  if(ratio > 1.0) return(0.5 - 0.3 * log10(ratio)); // coefficient to be determined later
  
  ratio = (gaussian.peak_power / gaussian.mean_power) / analysis_cfg->gauss.peak_power_thresh;
  return(0.5 + 1.0 * log10(ratio)); // coefficient to be determined later
}
    
double KBSSETIResultsPlot::power(const SETIAnalysisCfg *, const SETIPulse &pulse)
{
  const double ratio = pulse.snr / pulse.thresh;
  return(0.5 + 1.0 * log10(ratio)); // coefficient to be determined later
}

double KBSSETIResultsPlot::power(const SETIAnalysisCfg *analysis_cfg, const SETITriplet &triplet)
{
  const double ratio = triplet.peak_power / analysis_cfg->triplet.thresh;
  return(0.5 + 1.0 * log10(ratio)); // coefficient to be determined later
}

#include "kbssetiresultsplot.moc"

Generated by  Doxygen 1.6.0   Back to index