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

kbssetiskymapwindow.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 <qmovie.h>
#include <qpixmap.h>
#include <qpopupmenu.h>
#include <qscrollview.h>
#include <qtooltip.h>

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

#include <kbsboincmonitor.h>
#include <kbstaskmonitor.h>

#include <kbsseticalibrator.h>
#include <kbssetilogmanager.h>
#include <kbssetiprojectmonitor.h>

#include <kbssetiskymaplegend.h>

#include "kbssetiskymapwindow.h"

KBSSETISkyMapTarget::KBSSETISkyMapTarget(const QString &workunit, QWidget *parent)
                   : QLabel(parent), m_workunit(workunit)
{
}

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

void KBSSETISkyMapTarget::addProjectMonitor(KBSSETIProjectMonitor *projectMonitor)
{
  if(m_projectMonitors.containsRef(projectMonitor)) return;
  
  m_projectMonitors.append(projectMonitor);
  
  if(m_projectMonitors.count() == 1) {
    connectProjectMonitor(projectMonitor);
    update();
  }
}

void KBSSETISkyMapTarget::removeProjectMonitor(KBSSETIProjectMonitor *projectMonitor)
{
  if(!m_projectMonitors.containsRef(projectMonitor)) return;
  
  bool disconnected = false;
  if(projectMonitor == m_projectMonitors.first()) {
    disconnectProjectMonitor(projectMonitor);
    disconnected = true;
  }
  
  m_projectMonitors.removeRef(projectMonitor);
  
  if(disconnected)
  {
    projectMonitor = m_projectMonitors.first();
    
    if(NULL != projectMonitor) {
      connectProjectMonitor(projectMonitor);
      update();
    } else
      KBSSETISkyMapWindow::self()->m_targets.remove(m_workunit);
  }
}

void KBSSETISkyMapTarget::connectProjectMonitor(KBSSETIProjectMonitor *projectMonitor)
{
  KBSBOINCMonitor *boincMonitor = m_boincMonitors.find(projectMonitor);
  if(NULL != boincMonitor) return;
  
  connect(projectMonitor, SIGNAL(updatedResult(const QString &)), this, SLOT(update(const QString &)));
  
  boincMonitor = projectMonitor->boincMonitor();
  m_boincMonitors.insert(projectMonitor, boincMonitor);
  
  connect(boincMonitor, SIGNAL(stateUpdated()), this, SLOT(update()));
}

void KBSSETISkyMapTarget::disconnectProjectMonitor(KBSSETIProjectMonitor *projectMonitor)
{
  KBSBOINCMonitor *boincMonitor = m_boincMonitors.find(projectMonitor);
  if(NULL == boincMonitor) return;

  m_boincMonitors.remove(projectMonitor);
  
  disconnect(boincMonitor, SIGNAL(stateUpdated()), this, SLOT(update()));
}

void KBSSETISkyMapTarget::update()
{
  KBSSETIProjectMonitor *projectMonitor = m_projectMonitors.first();
  
  if(NULL != projectMonitor)
  {
    const SETIResult *setiResult = projectMonitor->result(m_workunit);
    
    KBSBOINCMonitor *boincMonitor = projectMonitor->boincMonitor();
    const BOINCClientState *state = boincMonitor->state();
    QString result = (NULL != state) ? state->workunit[m_workunit].result_name : QString::null;
    const int task = !result.isEmpty() ? state->active_task_set.index(result) : -1;
    
    if(NULL != setiResult)
    {
      KLocale *locale = KGlobal::locale();
      
      const SETIGroupInfo *group_info = &(setiResult->workunit_header.group_info);
      const double ra = group_info->data_desc.start.ra;
      const double dec = group_info->data_desc.start.dec;
      const double ar = group_info->data_desc.true_angle_range;
      const double teraFLOPs = group_info->data_desc.teraFLOPs();
      
      QSize size;
      if(NULL != state && task >= 0 && state->active_task_set.active_task[task].scheduler_state > 1)
      {
        setMovie(KBSSETISkyMapWindow::s_targetRunning);
        size = KBSSETISkyMapWindow::s_targetRunningSize;
      }
      else
      {
        setPixmap(KBSSETISkyMapWindow::s_targetIdle);
        size = KBSSETISkyMapWindow::s_targetIdle.size();
        lower();
      }
      setFixedSize(size);
      
      setBackgroundPixmap(KBSSETISkyMapWindow::s_skyMap);
      setBackgroundOrigin(ParentOrigin);
      
      move(KBSSETISkyMapWindow::position(ra, dec) - QPoint(size.width() / 2, size.height() / 2));
      
      QStringList tooltip;
      
      if(NULL != state)
        tooltip << i18n("Host name: %1").arg(state->host_info.domain_name);
        
      tooltip << i18n("WU name: %1")
                   .arg(m_workunit);
      
      tooltip << i18n("Position: %1 RA, %2 Dec")
                   .arg(formatRA(ra))
                   .arg(formatDec(dec));
      
      tooltip << i18n("Angle Range: %1 (%2 TeraFLOPs)")
                   .arg(locale->formatNumber(ar, 3))
                   .arg(locale->formatNumber(teraFLOPs, 2));
      
      if(NULL != state)
      {
        double secs, done;
        if(task >= 0) {
          secs = state->active_task_set.active_task[task].current_cpu_time;
          done = state->active_task_set.active_task[task].fraction_done;
        } else if(!result.isEmpty() && state->result[result].ready_to_report) {
          secs = state->result[result].final_cpu_time;
          done = 1.00;
        } else
          secs = done = 0.00;
        done = KBSSETICalibrator::self()->calibrate(boincMonitor->url(), ar, done);
        
        tooltip << i18n("Process time: %1 hours (%2%)")
                     .arg(locale->formatNumber(secs / 3600, 3))
                     .arg(locale->formatNumber(done * 1e2, 2));
                     
        if(secs > 0)
          tooltip << i18n("Process speed: %1 MegaFLOPs / sec")
                       .arg(locale->formatNumber(1e4 * teraFLOPs * done / secs, 1));
      }
      
      tooltip << i18n("Returned spikes: %1").arg(setiResult->spike.count());
      
      if(setiResult->state.best_spike.spike.time_jd > 0)
        tooltip << i18n("Best spike signal ratio: %1")
                     .arg(locale->formatNumber(setiResult->state.best_spike.spike.score(), 3));
      
      tooltip << i18n("Returned gaussians: %1").arg(setiResult->gaussian.count());
        
      if(setiResult->state.best_gaussian.gaussian.time_jd > 0)
        tooltip << i18n("Best gaussian signal ratio: %1")
                     .arg(locale->formatNumber(setiResult->state.best_gaussian.gaussian.score(), 3));
      
      tooltip << i18n("Returned pulses: %1").arg(setiResult->pulse.count());
        
      if(setiResult->state.best_pulse.pulse.time_jd > 0)
        tooltip << i18n("Best pulse score: %1")
                     .arg(locale->formatNumber(setiResult->state.best_pulse.pulse.score(), 3));
      
      tooltip << i18n("Returned triplets: %1").arg(setiResult->triplet.count());
      
      if(setiResult->state.best_triplet.triplet.time_jd > 0)
        tooltip << i18n("Best triplet score: %1")
                     .arg(locale->formatNumber(setiResult->state.best_triplet.triplet.score(), 3));
      
      QToolTip::remove(this);
      QToolTip::add(this, tooltip.join("\n"));
  
      show();
    }
    else
      hide();
  }
  else
    hide();
}

void KBSSETISkyMapTarget::update(const QString &workunit)
{
  if(workunit == m_workunit) update();
}

KBSSETISkyMapWindow *KBSSETISkyMapWindow::s_self = NULL;

const KBSSETIConstellation KBSSETISkyMapWindow::s_constellation[] =
{
  {"And", I18N_NOOP("Andromeda"), I18N_NOOP("article.php?articleid=1"), 1.0, 40.0},
  {"Ant", I18N_NOOP("Antila"), I18N_NOOP("article.php?articleid=2"), 10.0, -30.0},
  {"Aps", I18N_NOOP("Apus"), I18N_NOOP("article.php?articleid=3"), 16.0, -75.0},
  {"Aql", I18N_NOOP("Aquila"), I18N_NOOP("article.php?articleid=5"), 20.0, 5.0},
  {"Aqr", I18N_NOOP("Aquarius"), I18N_NOOP("article.php?articleid=4"), 22.0, -10.0},
  {"Ara", I18N_NOOP("Ara"), I18N_NOOP("article.php?articleid=6"), 17.0, -55.0},
  {"Ari", I18N_NOOP("Aries"), I18N_NOOP("article.php?articleid=7"), 3.0, 20.0},
  {"Aur", I18N_NOOP("Auriga"), I18N_NOOP("article.php?articleid=8"), 6.0, 40.0},
  {"Boo", I18N_NOOP("Bootes"), I18N_NOOP("article.php?articleid=9"), 15.0, 30.0},
  {"CMa", I18N_NOOP("Canis Major"), I18N_NOOP("article.php?articleid=14"), 7.0, -20.0},
  {"CMi", I18N_NOOP("Canis Minor"), I18N_NOOP("article.php?articleid=15"), 8.0, 5.0},
  {"CVn", I18N_NOOP("Canes Venatici"), I18N_NOOP("article.php?articleid=13"), 13.0, 40.0},
  {"Cae", I18N_NOOP("Caelum"), I18N_NOOP("article.php?articleid=10"), 5.0, -40.0},
  {"Cam", I18N_NOOP("Camelopardus"), I18N_NOOP("article.php?articleid=11"), 9.0, 70.0},
  {"Cap", I18N_NOOP("Capricornus"), I18N_NOOP("article.php?articleid=16"), 21.0, -20.0},
  {"Car", I18N_NOOP("Carina"), I18N_NOOP("article.php?articleid=17"), 9.0, -65.0},
  {"Cas", I18N_NOOP("Cassiopeia"), I18N_NOOP("article.php?articleid=18"), 1.0, 60.0},
  {"Cen", I18N_NOOP("Centaurus"), I18N_NOOP("article.php?articleid=19"), 13.0, -50.0},
  {"Cep", I18N_NOOP("Cepheus"), I18N_NOOP("article.php?articleid=20"), 2.0, 75.0},
  {"Cet", I18N_NOOP("Cetus"), I18N_NOOP("article.php?articleid=21"), 2.0, -10.0},
  {"Cha", I18N_NOOP("Chamaeleon"), I18N_NOOP("article.php?articleid=22"), 11.0, -80.0},
  {"Cir", I18N_NOOP("Circinus"), I18N_NOOP("article.php?articleid=23"), 15.0, -60.0},
  {"Cnc", I18N_NOOP("Cancer"), I18N_NOOP("article.php?articleid=12"), 9.0, 20.0},
  {"Col", I18N_NOOP("Columba"), I18N_NOOP("article.php?articleid=24"), 6.0, -35.0},
  {"Com", I18N_NOOP("Coma Berenices"), I18N_NOOP("article.php?articleid=25"), 13.0, 25.0},
  {"CrA", I18N_NOOP("Corona Australis"), I18N_NOOP("article.php?articleid=26"), 19.0, -40.0},
  {"CrB", I18N_NOOP("Corona Borealis"), I18N_NOOP("article.php?articleid=27"), 16.0, 35.0},
  {"Crt", I18N_NOOP("Crater"), I18N_NOOP("article.php?articleid=29"), 11.0, -15.0},
  {"Cru", I18N_NOOP("Crux"), I18N_NOOP("article.php?articleid=30"), 12.0, -60.0},
  {"Crv", I18N_NOOP("Corvus"), I18N_NOOP("article.php?articleid=28"), 12.0, -20.0},
  {"Cyg", I18N_NOOP("Cygnus"), I18N_NOOP("article.php?articleid=31"), 21.0, 45.0},
  {"Del", I18N_NOOP("Delphinus"), I18N_NOOP("article.php?articleid=32"), 21.0, 10.0},
  {"Dor", I18N_NOOP("Dorado"), I18N_NOOP("article.php?articleid=33"), 5.0, -60.0},
  {"Dra", I18N_NOOP("Draco"), I18N_NOOP("article.php?articleid=34"), 15.0, 65.0},
  {"Equ", I18N_NOOP("Equuleus"), I18N_NOOP("article.php?articleid=35"), 21.0, 10.0},
  {"Eri", I18N_NOOP("Eridanus"), I18N_NOOP("article.php?articleid=36"), 3.0, -20.0},
  {"For", I18N_NOOP("Fornax"), I18N_NOOP("article.php?articleid=37"), 3.0, -30.0},
  {"Gem", I18N_NOOP("Gemini"), I18N_NOOP("article.php?articleid=38"), 7.0, 25.0},
  {"Gru", I18N_NOOP("Grus"), I18N_NOOP("article.php?articleid=39"), 22.0, -45.0},
  {"Her", I18N_NOOP("Hercules"), I18N_NOOP("article.php?articleid=40"), 17.0, 30.0},
  {"Hor", I18N_NOOP("Horologium"), I18N_NOOP("article.php?articleid=41"), 3.0, -55.0},
  {"Hya", I18N_NOOP("Hydra"), I18N_NOOP("article.php?articleid=42"), 11.0, -15.0},
  {"Hyi", I18N_NOOP("Hydrus"), I18N_NOOP("article.php?articleid=43"), 2.0, -70.0},
  {"Ind", I18N_NOOP("Indus"), I18N_NOOP("article.php?articleid=44"), 22.0, -60.0},
  {"LMi", I18N_NOOP("Leo Minor"), I18N_NOOP("article.php?articleid=47"), 10.0, 35.0},
  {"Lac", I18N_NOOP("Lacerta"), I18N_NOOP("article.php?articleid=45"), 22.0, 45.0},
  {"Leo", I18N_NOOP("Leo"), I18N_NOOP("article.php?articleid=46"), 11.0, 15.0},
  {"Lep", I18N_NOOP("Lepus"), I18N_NOOP("article.php?articleid=48"), 6.0, -20.0},
  {"Lib", I18N_NOOP("Libra"), I18N_NOOP("article.php?articleid=49"), 15.0, -15.0},
  {"Lup", I18N_NOOP("Lupus"), I18N_NOOP("article.php?articleid=50"), 15.0, -45.0},
  {"Lyn", I18N_NOOP("Lynx"), I18N_NOOP("article.php?articleid=51"), 8.0, 50.0},
  {"Lyr", I18N_NOOP("Lyra"), I18N_NOOP("article.php?articleid=52"), 19.0, 35.0},
  {"Men", I18N_NOOP("Mensa"), I18N_NOOP("article.php?articleid=53"), 5.0, -80.0},
  {"Mic", I18N_NOOP("Microscopium"), I18N_NOOP("article.php?articleid=54"), 21.0, -35.0},
  {"Mon", I18N_NOOP("Monoceros"), I18N_NOOP("article.php?articleid=55"), 7.0, 0.0},
  {"Mus", I18N_NOOP("Musca"), I18N_NOOP("article.php?articleid=56"), 13.0, -70.0},
  {"Nor", I18N_NOOP("Norma"), I18N_NOOP("article.php?articleid=57"), 16.0, -50.0},
  {"Oct", I18N_NOOP("Octans"), I18N_NOOP("article.php?articleid=58"), 22.0, -85.0},
  {"Oph", I18N_NOOP("Ophiuchus"), I18N_NOOP("article.php?articleid=59"), 17.0, -10.0},
  {"Ori", I18N_NOOP("Orion"), I18N_NOOP("article.php?articleid=60"), 6.0, 5.0},
  {"Pav", I18N_NOOP("Pavo"), I18N_NOOP("article.php?articleid=61"), 20.0, -65.0},
  {"Peg", I18N_NOOP("Pegasus"), I18N_NOOP("article.php?articleid=62"), 23.0, 20.0},
  {"Per", I18N_NOOP("Perseus"), I18N_NOOP("article.php?articleid=63"), 3.0, 45.0},
  {"Phe", I18N_NOOP("Phoenix"), I18N_NOOP("article.php?articleid=64"), 1.0, -50.0},
  {"Pic", I18N_NOOP("Pictor"), I18N_NOOP("article.php?articleid=65"), 6.0, -55.0},
  {"PsA", I18N_NOOP("Pisces Australis"), I18N_NOOP("article.php?articleid=67"), 22.0, -30.0},
  {"Psc", I18N_NOOP("Pisces"), I18N_NOOP("article.php?articleid=66"), 0.0, 15.0},
  {"Pup", I18N_NOOP("Puppis"), I18N_NOOP("article.php?articleid=68"), 7.0, -30.0},
  {"Pyx", I18N_NOOP("Pyxis"), I18N_NOOP("article.php?articleid=69"), 9.0, -30.0},
  {"Ret", I18N_NOOP("Reticulum"), I18N_NOOP("article.php?articleid=70"), 4.0, -60.0},
  {"Sci", I18N_NOOP("Sculptor"), I18N_NOOP("article.php?articleid=74"), 0.0, -35.0},
  {"Sco", I18N_NOOP("Scorpius"), I18N_NOOP("article.php?articleid=73"), 17.0, -25.0},
  {"Sct", I18N_NOOP("Scutum"), I18N_NOOP("article.php?articleid=75"), 19.0, -10.0},
  {"Ser", I18N_NOOP("Serpens"), I18N_NOOP("article.php?articleid=76"), 17.0, 5.0},
  {"Sex", I18N_NOOP("Sextans"), I18N_NOOP("article.php?articleid=77"), 10.0, 0.0},
  {"Sge", I18N_NOOP("Sagitta"), I18N_NOOP("article.php?articleid=71"), 20.0, 20.0},
  {"Sgr", I18N_NOOP("Sagittarius"), I18N_NOOP("article.php?articleid=72"), 19.0, -30.0},
  {"Tau", I18N_NOOP("Taurus"), I18N_NOOP("article.php?articleid=78"), 5.0, 15.0},
  {"Tel", I18N_NOOP("Telescopium"), I18N_NOOP("article.php?articleid=79"), 19.0, -50.0},
  {"TrA", I18N_NOOP("Triangulum Australis"), I18N_NOOP("article.php?articleid=81"), 16.0, -65.0},
  {"Tri", I18N_NOOP("Triangulum"), I18N_NOOP("article.php?articleid=80"), 2.0, 30.0},
  {"Tuc", I18N_NOOP("Tucana"), I18N_NOOP("article.php?articleid=82"), 0.0, -65.0},
  {"UMa", I18N_NOOP("Ursa Major"), I18N_NOOP("article.php?articleid=83"), 11.0, 50.0},
  {"UMi", I18N_NOOP("Ursa Minor"), I18N_NOOP("article.php?articleid=84"), 15.0, 75.0},
  {"Vel", I18N_NOOP("Vela"), I18N_NOOP("article.php?articleid=85"), 10.0, -45.0},
  {"Vir", I18N_NOOP("Virgo"), I18N_NOOP("article.php?articleid=86"), 13.0, -5.0},
  {"Vol", I18N_NOOP("Volans"), I18N_NOOP("article.php?articleid=87"), 8.0, -70.0},
  {"Vul", I18N_NOOP("Vulpecula"), I18N_NOOP("article.php?articleid=88"), 20.0, 25.0}
};

const QPixmap KBSSETISkyMapWindow::s_skyMap        = UserIcon("seti/skymap");
const QPixmap KBSSETISkyMapWindow::s_targetIdle    = UserIcon("seti/target_idle");
const QPixmap KBSSETISkyMapWindow::s_targetHistory = UserIcon("seti/target_history");

const QMovie KBSSETISkyMapWindow::s_targetRunning =
  QMovie(locate("data", "kboincspy/pics/seti/target_running.gif"));
const QSize  KBSSETISkyMapWindow::s_targetRunningSize = QSize(27, 27);

KBSSETISkyMapWindow *KBSSETISkyMapWindow::self()
{
  if(NULL == s_self) s_self = new KBSSETISkyMapWindow();
  
  return s_self;
}

KBSSETISkyMapWindow::KBSSETISkyMapWindow(QWidget *parent, const char *name)
                   : KBSStandardWindow(parent, name),
                     m_historyVisible(true), m_legend(new KBSSETISkyMapLegend(this))
{
  setCaption(i18n("SETI@home Sky Map"));
  
  QScrollView *scrollView = new QScrollView(this);
  setCentralWidget(scrollView);
  
  m_view = new QWidget(scrollView->viewport());
  m_view->installEventFilter(this);
  m_view->setBackgroundMode(FixedPixmap);
  m_view->setPaletteBackgroundPixmap(s_skyMap);
  m_view->setFixedSize(s_skyMap.size());
  
  scrollView->addChild(m_view);
  
  m_targets.setAutoDelete(true);
  m_history.setAutoDelete(true);
  
  KBSSETILogManager *logManager = KBSSETILogManager::self();
  connect(logManager, SIGNAL(logChanged()), this, SLOT(buildHistory()));
  connect(logManager, SIGNAL(workunitsUpdated()), this, SLOT(updateHistory()));
  buildHistory();  
  
  setAutoSaveGeometry("SETI@home Sky Map");
  
  setupActions();
}

unsigned KBSSETISkyMapWindow::constellations()
{
  return 88;
}

QString KBSSETISkyMapWindow::constellation(unsigned index)
{
  return s_constellation[index].abbrev;
}

QString KBSSETISkyMapWindow::constellationName(int index)
{
  return (index >= 0) ? i18n(s_constellation[index].name)
                      : i18n("Peoria Astronomical Society");
}

KURL KBSSETISkyMapWindow::constellationURL(int index)
{
  return (index >= 0) ? KURL(i18n("http://www.astronomical.org/portal/modules/wfsection/"),
                             i18n(s_constellation[index].id))
                      : KURL(i18n("http://www.astronomical.org/"));
}

unsigned KBSSETISkyMapWindow::findNearestConstellation(double ra, double dec)
{
  double best_distance = 0.0;
  unsigned best = constellations();
  const unsigned constellations = best;
  for(unsigned i = 0; i < constellations; ++i)
  {
    const double distance = KBSSETISkyMapWindow::distance(ra, 
                                                          dec,
                                                          s_constellation[i].ra,
                                                          s_constellation[i].dec);
    
    if(best >= constellations || distance < best_distance) {
      best_distance = distance;
      best = i;
    }
  }
  
  return best;
}

bool KBSSETISkyMapWindow::isHistoryVisible() const
{
  return m_historyVisible;
}

void KBSSETISkyMapWindow::setHistoryVisible(bool visible)
{
  if(visible == m_historyVisible) return;
  
  m_historyVisible = visible;
  
  for(QLabel *label = m_history.first(); label != NULL; label = m_history.next())
    if(visible) label->show();
    else label->hide();
}
    
void KBSSETISkyMapWindow::addWorkunit(KBSSETIProjectMonitor *projectMonitor, const QString &workunit)
{
  KBSSETISkyMapTarget *target = m_targets.find(workunit);
  if(NULL == target) {
    target = new KBSSETISkyMapTarget(workunit, m_view);
    m_targets.insert(workunit, target);
  }
  
  target->addProjectMonitor(projectMonitor);
}

void KBSSETISkyMapWindow::removeWorkunit(KBSSETIProjectMonitor *projectMonitor, const QString &workunit)
{
  KBSSETISkyMapTarget *target = m_targets.find(workunit);
  if(NULL == target) return;
  
  target->removeProjectMonitor(projectMonitor);
  
  if(m_targets.isEmpty())
  {    
    m_legend->close();
    close();
    
    destroy();
    s_self = NULL;
  }
}

QPixmap KBSSETISkyMapWindow::pixmap()
{
  return QPixmap::grabWidget(m_view);
}

QPoint KBSSETISkyMapWindow::position(double ra, double dec)
{
  ra -= 24.0 * int(ra / 24); // normalize RAs > 24

  const int x = (ra <= 12.0) ? 481 - int(40.1 * ra) : 481 + int(40.1 * (24.0 - ra));
  const int y = 240 - int(8.0 / 3.0 * dec);

  return QPoint(x, y);
}

double KBSSETISkyMapWindow::distance(const double ra1, const double dec1, const double ra2, const double dec2)
{
  const double dx = (ra1 - 24.0 * int(ra1 / 24) - ra2 + 24.0 * int(ra2 / 24)) / 24;
  const double dy = (dec1 - dec2) / 360;

  return(dx * dx + dy * dy);
}

void KBSSETISkyMapWindow::buildHistory()
{
  m_history.clear();
  updateHistory();
}

void KBSSETISkyMapWindow::updateHistory()
{
  KLocale *locale = KGlobal::locale();
  
  const unsigned start = m_history.count();
  const KBSLogData log = KBSSETILogManager::self()->workunits();
  for(KBSLogData::const_iterator it = log.at(start); it != log.end(); ++it)
  {
    if(!(*it).contains("start_ra")) continue;
    const double ra = (*it)["start_ra"].toDouble();
    if(!(*it).contains("start_dec")) continue;
    const double dec = (*it)["start_dec"].toDouble();
    
    QLabel *target = new QLabel(m_view);
    m_history.append(target);
    
    QPixmap pixmap = s_targetHistory;
    QSize size = s_targetHistory.size();
    
    target->setPixmap(pixmap);
    target->setFixedSize(size);
    target->lower();
    
    target->setBackgroundPixmap(s_skyMap);
    target->setBackgroundOrigin(ParentOrigin);
    
    target->move(KBSSETISkyMapWindow::position(ra, dec) - QPoint(size.width() / 2, size.height() / 2));
    
    QStringList tooltip;
    
    if((*it).contains("domain_name"))
      tooltip << i18n("Host name: %1").arg((*it)["domain_name"].toString());
    
    if((*it).contains("wu_name"))
      tooltip << i18n("WU name: %1")
                   .arg((*it)["wu_name"].toString());
    
    if((*it).contains("date"))
      tooltip << i18n("Returned: %1")
                   .arg(locale->formatDateTime((*it)["date"].toDateTime()));
    
    tooltip << i18n("Position: %1 RA, %2 Dec")
                 .arg(formatRA(ra))
                 .arg(formatDec(dec));
    
    double teraFLOPs = 0.0;
    if((*it).contains("angle_range"))
    {
      const double ar = (*it)["angle_range"].toDouble();
      teraFLOPs = SETIDataDesc::teraFLOPs(ar);
      
      tooltip << i18n("Angle Range: %1 (%2 TeraFLOPs)")
                   .arg(locale->formatNumber(ar, 3))
                   .arg(locale->formatNumber(teraFLOPs, 2));
    }
    if((*it).contains("teraflops"))
      teraFLOPs = (*it)["teraflops"].toDouble();
      
    if((*it).contains("cpu"))
    {
      double cpu = (*it)["cpu"].toDouble();
      double prog = (*it).contains("prog") ? (*it)["prog"].toDouble() : 1.0;
      
      tooltip << i18n("Process time: %1 hours (%2%)")
                   .arg(locale->formatNumber(cpu / 3600, 3))
                   .arg(locale->formatNumber(prog * 1e2, 2));
      
      if(cpu > 0 && teraFLOPs > 0)
        tooltip << i18n("Process speed: %1 MegaFLOPs / sec")
                     .arg(locale->formatNumber(1e6 * teraFLOPs * prog / cpu, 1));
    }
    
    if((*it).contains("spike_count"))
      tooltip << i18n("Returned spikes: %1").arg((*it)["spike_count"].toUInt());
      
    if((*it).contains("bs_score"))
      tooltip << i18n("Best spike signal ratio: %1")
                   .arg(locale->formatNumber((*it)["bs_score"].toDouble(), 3));
    
    if((*it).contains("gaussian_count"))
      tooltip << i18n("Returned gaussians: %1").arg((*it)["gaussian_count"].toUInt());
      
    if((*it).contains("bg_score"))
      tooltip << i18n("Best gaussian signal ratio: %1")
                   .arg(locale->formatNumber((*it)["bg_score"].toDouble(), 3));
    
    if((*it).contains("pulse_count"))
      tooltip << i18n("Returned pulses: %1").arg((*it)["pulse_count"].toUInt());
      
    if((*it).contains("bp_score"))
      tooltip << i18n("Best pulse score: %1")
                   .arg(locale->formatNumber((*it)["bp_score"].toDouble(), 3));
    
    if((*it).contains("triplet_count"))
      tooltip << i18n("Returned triplets: %1").arg((*it)["triplet_count"].toUInt());
      
    if((*it).contains("bt_score"))
      tooltip << i18n("Best triplet score: %1")
                   .arg(locale->formatNumber((*it)["bt_score"].toDouble(), 3));
    
    QToolTip::add(target, tooltip.join("\n"));
    
    if(m_historyVisible)
      target->show();
  }
}

void KBSSETISkyMapWindow::toggleHistory()
{
  setHistoryVisible(show_history->isChecked());
}

void KBSSETISkyMapWindow::showLegend()
{
  if(!m_legend->isVisible()) m_legend->show();
}

void KBSSETISkyMapWindow::setupActions()
{
  show_history = new KToggleAction(i18n("Show &History"), 0,
                                   this, SLOT(toggleHistory()), actionCollection());
  
  show_history->setChecked(m_historyVisible);
  
  KAction *show_legend = new KAction(i18n("Show &Legend"), 0,
                                     this, SLOT(showLegend()), actionCollection());
  
  KBSStandardWindow::setupActions();

  QPopupMenu *context = static_cast<QPopupMenu*>(guiFactory()->container("context", this));
  context->insertSeparator(0);
  show_legend->plug(context, 0);
  show_history->plug(context, 0);
}

#include "kbssetiskymapwindow.moc"

Generated by  Doxygen 1.6.0   Back to index