Ksetiwatch API Documentation


setiloc.cpp

Go to the documentation of this file.
00001 /***************************************************************************/
00014 #include <kapp.h>
00015 #include <klocale.h>
00016 #include <kmessagebox.h>
00017 #include <ktextbrowser.h>
00018 
00019 #include <qglobal.h>
00020 #include <qmessagebox.h>
00021 #include <qdir.h>
00022 #include <qtextstream.h>
00023 #include <qregexp.h>
00024 #include <qcstring.h>
00025 #include <qfontmetrics.h>
00026 
00027 #include <math.h>
00028 
00029 #include "setiloc.h"
00030 #include "setigraph.h"
00031 #include "gaussianplot.h"
00032 #include "pulseplot.h"
00033 #include "tripletplot.h"
00034 #include "csvdatabase.h"
00035 
00037 struct csvHeaderField {
00038                       const char* text; 
00039                       int type;         
00042                       };
00043 
00044 csvHeaderField csv_userinfo[] =   {
00045                                   {"date", 1},
00046                                   {"id", 0},
00047                                   {"key", 0},
00048                                   {"email_addr", 1},
00049                                   {"user_name", 1},
00050                                   {"url", 1},
00051                                   {"country", 1},
00052                                   {"postal_code", 0},
00053                                   {"show_name", 1},
00054                                   {"show_email", 1},
00055                                   {"venue", 0},
00056                                   {"register_time", 1},
00057                                   {"last_wu_time", 1},
00058                                   {"last_result_time", 1},
00059                                   {"nwus", 0},
00060                                   {"nresults", 0},
00061                                   {"total_cpu", 0},
00062                                   {"params_index", 0}
00063                                   };
00064 #define CSV_USERINFO_COLUMNS 18
00065 
00066 csvHeaderField csv_datainfo[] =   {
00067                                   {"task", 1},
00068                                   {"version", 0},
00069                                   {"name", 1},
00070                                   {"data_type", 1},
00071                                   {"data_class", 0},
00072                                   {"splitter_version", 1},
00073                                   {"start_ra", 0},
00074                                   {"start_dec", 0},
00075                                   {"end_ra", 0},
00076                                   {"end_dec", 0},
00077                                   {"angle_range", 0},
00078                                   {"time_recorded", 1},
00079                                   {"subband_center", 0},
00080                                   {"subband_base", 0},
00081                                   {"subband_sample_rate", 0},
00082                                   {"fft_len", 0},
00083                                   {"ifft_len", 0},
00084                                   {"subband_number", 0},
00085                                   {"receiver", 1},
00086                                   {"nsamples", 0},
00087                                   {"tape_version", 0}
00088                                   };
00089 #define CSV_DATAINFO_COLUMNS 21
00090 
00091 csvHeaderField csv_state[] =  {
00092                               {"ncfft", 0},
00093                               {"cr", 0},
00094                               {"fl", 0},
00095                               {"cpu", 0},
00096                               {"prog", 0},
00097                               {"bs_power", 0},
00098                               {"bs_score", 0},
00099                               {"bs_bin", 0},
00100                               {"bs_fft_ind", 0},
00101                               {"bs_chirp_rate", 0},
00102                               {"bs_fft_len", 0},
00103                               {"bg_score", 0},
00104                               {"bg_power", 0},
00105                               {"bg_chisq", 0},
00106                               {"bg_bin", 0},
00107                               {"bg_fft_ind", 0},
00108                               {"bg_chirp_rate", 0},
00109                               {"bg_fft_len", 0},
00110                               {"bp_score", 0},
00111                               {"bp_power", 0},
00112                               {"bp_mean", 0},
00113                               {"bp_period", 0},
00114                               {"bp_freq_bin", 0},
00115                               {"bp_time_bin", 0},
00116                               {"bp_chirp_rate", 0},
00117                               {"bp_fft_len", 0},
00118                               {"bt_score", 0},
00119                               {"bt_power", 0},
00120                               {"bt_mean", 0},
00121                               {"bt_period", 0},
00122                               {"bt_bperiod", 0},
00123                               {"bt_tpotind0_0", 0},
00124                               {"bt_tpotind0_1", 0},
00125                               {"bt_tpotind1_0", 0},
00126                               {"bt_tpotind1_1", 0},
00127                               {"bt_tpotind2_0", 0},
00128                               {"bt_tpotind2_1", 0},
00129                               {"bt_freq_bin", 0},
00130                               {"bt_time_bin", 0},
00131                               {"bt_chirp_rate", 0},
00132                               {"bt_scale", 0},
00133                               {"bt_fft_len", 0}
00134                               };
00135 #define CSV_STATE_COLUMNS 42
00136 
00137 /*------------------------------------------------------------------------ */
00138 SetiLoc::SetiLoc(const QString& dir, const QString& loc, const QColor& col)
00139        : SetiContainer(dir), stoppedNormally(true)
00140 {
00141 sets.directory   = dir;
00142 sets.description = loc;
00143 sets.color       = col;
00144 
00145 /* Generate the unique id string. */
00146 thisId = QString::number((unsigned int)this, 16);
00147 
00148 for(int i=0; i<(int)(sizeof(graphwidget)/sizeof(graphwidget[0])); i++)
00149   graphwidget[i] = 0;
00150 
00151 sresult_timestamp = "";
00152 
00153 initMaxScore();
00154 
00155 // Catch the output of the client in a text window
00156 clientOutput = new KTextBrowser();
00157 clientOutput->setCaption(QString(i18n("Location %1: Client Output")).arg(loc));
00158 // Calculate approximate size of the window from the chosen font
00159 QFontMetrics fm(clientOutput->font());
00160 clientOutput->resize( 8*fm.width("abcdefghij"), 25*fm.lineSpacing() );
00161 connect(&client, SIGNAL(receivedStdout(KProcess*, char*, int)),
00162         this,    SLOT(slotDumpClientOutput(KProcess*, char*, int)));
00163 
00164 connect(this, SIGNAL(newWorkUnit(WorkUnitData)),
00165               SLOT(slotInitMaxScore(WorkUnitData)));
00166 }
00167 
00168 /*------------------------------------------------------------------------ */
00169 SetiLoc::~SetiLoc()
00170 {
00171 delete clientOutput;
00172 }
00173 
00174 /*------------------------------------------------------------------------ */
00175 const QString& SetiLoc::id() const
00176 {
00177 return((const QString&)thisId);
00178 }
00179 
00180 /*------------------------------------------------------------------------ */
00181 void SetiLoc::setOptions(const LocSettings& ls)
00182 {
00183 initMaxScore();
00184 sets = ls;
00185 sets.arguments = sets.arguments.simplifyWhiteSpace();
00186 // set the directory so that the SetiContainer knows about it
00187 setDirectory(sets.directory);
00188 }
00189 
00190 /*------------------------------------------------------------------------ */
00191 void SetiLoc::showGraph(int id)
00192 {
00193 switch(id)
00194   {
00195   case GaussianGraph:
00196     if(graphwidget[id] == 0)
00197       graphwidget[id] = new GaussianPlot(this);
00198     graphwidget[id]->show();
00199     break;
00200   case PulseGraph:
00201     if(graphwidget[id] == 0)
00202       graphwidget[id] = new PulsePlot(this);
00203     graphwidget[id]->show();
00204     break;
00205   case TripletGraph:
00206     if(graphwidget[id] == 0)
00207       graphwidget[id] = new TripletPlot(this);
00208     graphwidget[id]->show();
00209     break;
00210   case ClientOutput:
00211     clientOutput->show();
00212     break;
00213   default:
00214     break;
00215   }
00216 }
00217 
00218 /*------------------------------------------------------------------------ */
00219 void SetiLoc::initMaxScore()
00220 {
00221 // clear the max score
00222 initWUScore(&mymax);
00223 // this ensures that all data are read when checking for the first time
00224 mymax.spike.power    = -1.0;
00225 mymax.gaussian.score = -1.0;
00226 mymax.pulse.score    = -1.0;
00227 mymax.triplet.score  = -1.0;
00228 }
00229 
00230 /*------------------------------------------------------------------------ */
00231 void SetiLoc::slotInitMaxScore(WorkUnitData wud)
00232 {
00233 initWUScore(&mymax);
00234 
00235 // Hide the old graph widgets if present; implement a more elegant way
00236 // later.
00237 for(int i=0;i<(int)(sizeof(graphwidget)/sizeof(graphwidget[0]));i++)
00238   if(graphwidget[i])
00239     graphwidget[i]->hide();
00240 
00241 // Delete the '.triplets.dat' file
00242 QDir d(logDirectory());
00243 d.remove(".triplets.dat");
00244 
00245 // ...and notify graph widgets with extended information
00246 emit newWorkUnit(wud, description(), color());
00247 }
00248 
00249 /*------------------------------------------------------------------------ */
00250 void SetiLoc::checkWUStatus()
00251 {
00252 if(sets.log == true)
00253   {
00254   // we're using the timestamp of the result file to prevent multiple logging
00255   QFileInfo fi(rsfFileName);
00256   QDateTime dt = QDateTime(fi.lastModified());
00257   QString res_dt = dt.toString();
00258   if(res_dt != timestamp())
00259     {
00260     setTimestamp(res_dt);
00261     logResults();
00262     logWorkUnit();
00263     // Save the config to make sure that the timestamp is written to
00264     // disk.
00265     emit workUnitLogged(this);
00266     }
00267   }
00268 }
00269 
00270 /*------------------------------------------------------------------------ */
00271 QString SetiLoc::logDirectory()
00272 {
00273 QString logdir;
00274 
00275 // determine the right log directory
00276 if(sets.redirectLog)
00277   {
00278   if(sets.logDirectory.isEmpty())
00279     logdir = directory();
00280   else
00281     logdir = sets.logDirectory;
00282   }
00283 else
00284   {
00285   logdir = directory();
00286   }
00287 
00288 return(logdir);
00289 }
00290 
00291 /*------------------------------------------------------------------------ */
00292 void SetiLoc::storeTripletData(const TripletScore& triplet)
00293 {
00294 QString trip_file;
00295 
00296 trip_file = logDirectory() + "/.triplets.dat";
00297 QFile f_trip(trip_file);
00298 
00299 if(f_trip.open(IO_Append | IO_WriteOnly))
00300   {
00301   QTextStream t(&f_trip);
00302   QString line = QString("%1,%2,%3,%4,%5,").arg(triplet.power)
00303                                            .arg(triplet.period)
00304                                            .arg(triplet.tpotind0_0)
00305                                            .arg(triplet.tpotind1_0)
00306                                            .arg(triplet.tpotind2_0);
00307   for(int i=0;i<512;i++)
00308     {
00309     QString byte;
00310     byte.sprintf("%02hx", (unsigned short int)triplet.data[i]);
00311     line += byte;
00312     }
00313   t << line << endl;
00314   f_trip.close();
00315   }
00316 }
00317 
00318 /*------------------------------------------------------------------------ */
00319 void SetiLoc::logWorkUnit()
00320 {
00321 QString buffer, entry;
00322 int i;
00323 int error(0);
00324 int warn(0);
00325 QString setilog_file;
00326 
00327 setilog_file = logDirectory() + "/SETILog.csv";
00328 QFile f_sel(setilog_file);
00329 
00330 // check if SETILog.csv needs to be upgraded
00331 CSVDataBase csv(setilog_file);
00332 bool upgrade = false;
00333 if(f_sel.exists())
00334   {
00335   if(csv.open(IO_ReadOnly))
00336     {
00337     int cols = csv.columnCount();
00338     if(cols < CSV_USERINFO_COLUMNS+CSV_DATAINFO_COLUMNS+CSV_STATE_COLUMNS)
00339       {
00340       // rename SETILog.csv to SETILog.old
00341       if(0 != rename((const char*)setilog_file,
00342                      (const char*)(logDirectory()+"/SETILog.old")))
00343         {
00344         error = 3;
00345         debug("Renaming SETILog.csv failed.");
00346         }
00347       else
00348         {
00349         upgrade = true;
00350         }
00351       }
00352     csv.close();
00353     }
00354   }
00355 
00356 // create new SETILog.csv if necessary
00357 if(f_sel.exists() == false && error == 0)
00358   {
00359   if(f_sel.open(IO_ReadWrite))
00360     {
00361     // write the definition line
00362     for(i=0;i<CSV_USERINFO_COLUMNS;i++)
00363       {
00364       f_sel.putch('"');
00365       f_sel.writeBlock(csv_userinfo[i].text, strlen(csv_userinfo[i].text));
00366       f_sel.putch('"'); f_sel.putch(',');
00367       }
00368     for(i=0;i<CSV_DATAINFO_COLUMNS;i++)
00369       {
00370       f_sel.putch('"');
00371       f_sel.writeBlock(csv_datainfo[i].text, strlen(csv_datainfo[i].text));
00372       f_sel.putch('"'); f_sel.putch(',');
00373       }
00374     for(i=0;i<CSV_STATE_COLUMNS;i++)
00375       {
00376       f_sel.putch('"');
00377       f_sel.writeBlock(csv_state[i].text, strlen(csv_state[i].text));
00378       f_sel.putch('"');
00379     if(i < CSV_STATE_COLUMNS-1)
00380       f_sel.putch(',');
00381     }
00382     // If the upgrade flag is set copy the data from SETILog.old to the new
00383     // file.
00384     if(upgrade)
00385       {
00386       QFile oldf_sel(logDirectory()+"/SETILog.old");
00387       if(oldf_sel.open(IO_ReadWrite))
00388         {
00389         QTextStream tout(&oldf_sel);
00390         QTextStream tin(&f_sel);
00391         QString s;
00392         i = 0;
00393         while(!oldf_sel.atEnd())
00394           {
00395           s = tout.readLine();
00396           // discard the first line
00397           if(i > 0)
00398             tin << endl << s;
00399           i++;
00400           }
00401         oldf_sel.close();
00402         }
00403       else
00404         {
00405         error = 4;
00406         debug("Could not create new SETILog.csv.");
00407         }
00408       }
00409     f_sel.close();
00410     }
00411   }
00412 
00413 QFileInfo finfo(rsfFileName);
00414 QDateTime dt = finfo.lastModified();
00415 if(dt.isValid())
00416   {
00417   QDate d = dt.date();
00418   buffer.sprintf("\"%d.%02d.%02d ", d.year(), d.month(), d.day() );
00419   QTime t = dt.time();
00420   buffer += t.toString() + "\",";
00421   }
00422 else
00423   {
00424   QDate d = QDate::currentDate();
00425   buffer.sprintf("\"%d.%02d.%02d ", d.year(), d.month(), d.day() );
00426   QTime t = QTime::currentTime();
00427   buffer += t.toString() + "\",";
00428   }
00429 
00430 // Read the user info information.
00431 if(exists(SC_UserInfoFile) && error == 0)
00432   {
00433   for(i=1; i<CSV_USERINFO_COLUMNS; i++)
00434     {
00435     if(i == 4) // instead of "user_name" take "name" to retrieve the users's name
00436       entry = readEntry(SC_UserInfoFile, "name");
00437     else
00438       entry = readEntry(SC_UserInfoFile, csv_userinfo[i].text);
00439     buffer += constructEntry(entry, csv_userinfo[i].type);
00440     }
00441   }
00442 else
00443   error = 1;
00444 
00445 // Read the result information.
00446 if(exists(SC_ResultFile) && error == 0)
00447   {
00448   for(i=0; i<CSV_DATAINFO_COLUMNS; i++)
00449     {
00450     if(i == 1) // version
00451       {
00452       entry.sprintf("%.2f,", (double)clientVersion()/100.0);
00453       buffer += entry;
00454       }
00455     else
00456       {
00457       entry = readEntry(SC_ResultFile, csv_datainfo[i].text);
00458       buffer += constructEntry(entry, csv_datainfo[i].type);
00459       }
00460     }
00461   }
00462 else
00463   if(error == 0) error = 2;
00464 
00465 // Read the state file information. If state file could not be found
00466 // issue a warning, but try it anyway (maybe we have some data in memory).
00467 if(exists(SC_StateFile) == false) warn = 1;
00468 if(error == 0)
00469   {
00470   for(i=0;i<CSV_STATE_COLUMNS;i++)
00471     {
00472     if(strcmp(csv_state[i].text, "cpu") == 0 && warn == 1)
00473       {
00474       // try to get at least cpu time from result.sah
00475       entry = readEntry(rsfFileName, "cpu_time");
00476       }
00477     else if(strcmp(csv_state[i].text, "prog") == 0 && warn == 1)
00478       {
00479       // assume progress is 100 %
00480       entry = "0.99994457";
00481       }
00482     else
00483       entry = readEntry(SC_StateFile, csv_state[i].text);
00484     buffer += constructEntry(entry, csv_state[i].type);
00485     }
00486   buffer = buffer.left(buffer.length()-1);
00487   }
00488 
00489 if(error == 0)
00490   {
00491   if(f_sel.open(IO_Append | IO_WriteOnly))
00492     {
00493     QTextStream tlog(&f_sel);
00494     tlog << endl << buffer;
00495     f_sel.close();
00496 
00497     if(warn)
00498       {
00499       QString buf;
00500       buf = i18n("Ksetiwatch has logged the work unit for \"%1\" without\n"
00501             "existing 'state.sah' file. Some values might therefore be wrong\n"
00502             "or out of date. Consider adding the '-stop_after_process' \n"
00503             "command line option when starting the SETI@home client.").arg(description());
00504       QMessageBox* mb = new QMessageBox(i18n("Warning"), buf,
00505                                         QMessageBox::Information,
00506                                         QMessageBox::Ok|QMessageBox::Default,
00507                                         0, 0, 0, 0, false,
00508                                         WStyle_DialogBorder|WDestructiveClose);
00509       mb->show();
00510       }
00511     }
00512   }
00513 else
00514   {
00515   buffer = i18n("Missing file(s). Logging of work unit failed.\n"
00516                 "Error code: %1").arg(error);
00517   KMessageBox::error(0, buffer);
00518   }
00519 }
00520 
00521 /*------------------------------------------------------------------------ */
00522 QString SetiLoc::constructEntry(const QString& entry, int type)
00523 {
00524 QString val = entry;
00525 
00526 if(type == 0)
00527   val.append(",");
00528 if(type == 1)
00529   {
00530   if(!val.isEmpty())
00531     {
00532     val.insert(0, '\"');
00533     val.append("\",");
00534     }
00535   else
00536     {
00537     val.append(",");
00538     }
00539   }
00540 
00541 return(val);
00542 }
00543 
00544 /*------------------------------------------------------------------------ */
00545 void SetiLoc::logResults()
00546 {
00547 QFile resFile(rsfFileName);
00548 if(resFile.open(IO_ReadOnly))
00549   {
00550   QString reslog_file;
00551 
00552   reslog_file = logDirectory() + "/SETIResult.log";
00553   QFile resLog(reslog_file);
00554 
00555   // used to prevent empty line at the beginning
00556   bool logEx = resLog.exists();
00557   if(resLog.open(IO_Append | IO_WriteOnly))
00558     {
00559     QTextStream tin(&resLog);
00560     QTextStream tout(&resFile);
00561     QString line;
00562     // take the WU name as group name
00563     if(logEx) tin << endl;
00564     tin << "[" << readEntry(SC_ResultFile, "name") << "]";
00565     // skip past the header
00566     while(line.find("end_seti_header") != 0 && !resFile.atEnd())
00567       line = tout.readLine();
00568     // now scan for signal lines
00569     int sCnt = 1, gCnt = 1, pCnt = 1, tCnt = 1;
00570     int idlen = strlen("gaussian:");
00571     QString id;
00572     QString key;
00573     while(!resFile.atEnd())
00574       {
00575       line = tout.readLine();
00576       // take the left part as identifier
00577       id = line.left(idlen);
00578       if(id.find("spike:") == 0)
00579         {
00580         key.sprintf("spike%02d=", sCnt);
00581         tin << endl << key << line.mid(strlen("spike:"));
00582         sCnt++;
00583         }
00584       else if(id.find("gaussian:") == 0)
00585         {
00586         key.sprintf("gaussian%02d=", gCnt);
00587         tin << endl << key << line.mid(strlen("gaussian:"));
00588         gCnt++;
00589         }
00590       else if(id.find("pulse:") == 0)
00591         {
00592         key.sprintf("pulse%02d=", pCnt);
00593         tin << endl << key << line.mid(strlen("pulse:"));
00594         pCnt++;
00595         }
00596       else if(id.find("triplet:") == 0)
00597         {
00598         key.sprintf("triplet%02d=", tCnt);
00599         QString tdat = line.mid(strlen("triplet:"));
00600         tdat += loggedTripletProfile(tdat);
00601         tin << endl << key << tdat;
00602         tCnt++;
00603         }
00604       }
00605     resLog.close();
00606     }
00607   resFile.close();
00608   }
00609 }
00610 
00611 /*------------------------------------------------------------------------ */
00612 bool SetiLoc::startClient()
00613 {
00614 bool running = false;
00615 
00616 // take care of the -stop_after_send option
00617 QFile sas(directory() + "/stop_after_send.txt");
00618 if(sets.stopAfterSend)
00619   {
00620   if(sas.exists() == false)
00621     {
00622     sas.open(IO_WriteOnly);
00623     sas.close();
00624     }
00625   }
00626 else
00627   {
00628   if(sas.exists())
00629     {
00630     sas.remove();
00631     }
00632   }
00633 
00634 if(!isClientRunning(true))
00635   {
00636   client.clearArguments();
00637   // check for customized executable file
00638   if(sets.useCustomStartExe && !sets.customStartExe.isEmpty())
00639     {
00640     QStringList sl = QStringList::split(' ', sets.customStartExe);
00641     for(QStringList::Iterator it=sl.begin(); it!=sl.end(); it++)
00642       client << (*it);
00643     }
00644   else
00645     {
00646     client << (directory() + "/setiathome");
00647     // check the settings of the check boxes
00648     if(sets.stopAfterProcess)
00649       client << "-stop_after_process";
00650     if(sets.email)
00651       client << "-email";
00652     if(sets.graphics)
00653       client << "-graphics";
00654     // nice level
00655     client << "-nice" << QString::number(20 - sets.priority);
00656     // proxy settings
00657     if(sets.useProxy)
00658       client << "-proxy"
00659              << sets.proxyServer + ":" + QString::number(sets.proxyPort);
00660     // and now any text in the arguments field
00661     if(!sets.arguments.isEmpty())
00662       {
00663       QStringList sl = QStringList::split(' ', sets.arguments);
00664       for(QStringList::Iterator it=sl.begin(); it!=sl.end(); it++)
00665         client << (*it);
00666       }
00667     }
00668   // we have to change to the setiathome directory to properly start the client
00669   pid_t oldPid = getClientPid();
00670   QString curdir = QDir::currentDirPath();
00671   QDir::setCurrent(directory());
00672   client.start(KProcess::DontCare, KProcess::Stdout);
00673   QDir::setCurrent(curdir);
00674   // wait 0.2 secs at maximum
00675   int i = 20;
00676   while((cltPid = getClientPid()) == oldPid && i > 0)
00677     {
00678     usleep(10000);
00679     i--;
00680     }
00681   // and check if the process is running
00682   running = isClientRunning();
00683   }
00684 else
00685   running = true;
00686 
00687 if(running)
00688   stoppedNormally = false;
00689 
00690 return(running);
00691 }
00692 
00693 /*------------------------------------------------------------------------ */
00694 int SetiLoc::stopClient()
00695 {
00696 int ret(-1);
00697 
00698 if(sets.useCustomStopExe && !sets.customStopExe.isEmpty())
00699   {
00700   stopProc.clearArguments();
00701   QStringList sl = QStringList::split(' ', sets.customStopExe);
00702   for(QStringList::Iterator it=sl.begin(); it!=sl.end(); it++)
00703     client << (*it);
00704   stopProc.start(KProcess::DontCare, KProcess::NoCommunication);
00705   ret = 0;
00706   }
00707 else
00708   {
00709   if(cltPid > 0)
00710     ret = ::kill(cltPid, SIGTERM);
00711   }
00712 
00713 stoppedNormally = true;
00714 
00715 return(ret);
00716 }
00717 
00718 /*------------------------------------------------------------------------ */
00719 void SetiLoc::slotDumpClientOutput(KProcess*, char* buffer, int len)
00720 {
00721 QString output = clientOutput->text();
00722 if(output.length() > 5000)
00723   {
00724   output = output.right(output.length() - len);
00725   int linebrk = output.find('\n');
00726   if(linebrk >= 0)
00727     output = output.right(output.length() - linebrk - 1);
00728   }
00729 output += QCString(buffer, len) + '\n';
00730 clientOutput->setText(output);
00731 // scroll to bottom of window (only Qt3)
00732 #if QT_VERSION >= 0x030000
00733     clientOutput->scrollToBottom();
00734 #endif
00735 }
00736 
00737 /*------------------------------------------------------------------------ */
00738 QString SetiLoc::loggedTripletProfile(const QString& tdata)
00739 {
00740 QString ret = "";
00741 QString tripfile = logDirectory() + "/.triplets.dat";
00742 
00743 QFile tfile(tripfile);
00744 if(!tdata.isEmpty() && tfile.open(IO_ReadOnly))
00745   {
00746   // Split the line into separate strings. This allows us to...
00747   QStringList tlist = QStringList::split(' ', tdata);
00748   // use SetiContainer's method to retrieve the entries.
00749   double tpower1  = readEntry(tlist, "power").toDouble();
00750   double tperiod1 = readEntry(tlist, "period").toDouble();
00751 
00752   QTextStream t(&tfile);
00753   QString line;
00754 
00755   QStringList ll;
00756   QStringList::Iterator it;
00757   bool found = false;
00758   while(!t.atEnd())
00759     {
00760     line = t.readLine();
00761     // extra info is a comma-separated line; split it up
00762     ll = QStringList::split(',', line);
00763     // first entry is power
00764     it = ll.begin();
00765     double tpower2 = (*it).toDouble();
00766     // second entry is period
00767     it++;
00768     double tperiod2 = (*it).toDouble();
00769     // if entries match with values in result.sah jump out of while loop
00770     if(fabs(tpower1-tpower2) < 0.0001 &&
00771        fabs(tperiod1-tperiod2) < 0.0001 &&
00772        tpower1 > 0.0 && tpower2 > 0.0 &&
00773        tperiod1 > 0.0 && tperiod2 > 0.0) {found = true; break;}
00774     }
00775   if(found)
00776     {
00777     // next entries are triplet positions
00778     for(int i=0;i<3;i++)
00779       {
00780       it++;
00781       ret += QString(" index%1=%2").arg(i).arg((*it).toInt());
00782       }
00783     // triplet profile has always 512 points
00784     ret += " len_prof=512";
00785     // finally copy the triplet data
00786     it++;
00787     ret += " prof=" + (*it);
00788     }
00789 
00790   tfile.close();
00791   }
00792 
00793 return(ret);
00794 }
00795 
00796 /*------------------------------------------------------------------------ */
00797 SpikeScore SetiLoc::loggedSpikeSignal(QString& line)
00798 {
00799 WUScore score;
00800 
00801 initWUScore(&score);
00802 
00803 // replace all occurences of '= ' with '='
00804 line.replace(QRegExp("= +"), "=");
00805 // Split the line into separate strings. This allows us to...
00806 QStringList llist = QStringList::split(' ', line);
00807 // use SetiContainer's method to retrieve the entries.
00808 score.spike.power     = readEntry(llist, "power").toDouble();
00809 score.spike.ra        = readEntry(llist, "ra").toDouble();
00810 score.spike.dec       = readEntry(llist, "dec").toDouble();
00811 score.spike.fft_len   = readEntry(llist, "fft_len").toInt();
00812 score.spike.frequency = readEntry(llist, "freq").toDouble();
00813 score.spike.chirprate = readEntry(llist, "chirp_rate").toDouble();
00814 
00815 return(score.spike);
00816 }
00817 
00818 /*------------------------------------------------------------------------ */
00819 GaussianScore SetiLoc::loggedGaussianSignal(QString & line)
00820 {
00821 WUScore score;
00822 QString pot;
00823 unsigned short int data[64];
00824 
00825 initWUScore(&score);
00826 
00827 // replace all occurences of '= ' with '='
00828 line.replace(QRegExp("= +"), "=");
00829 // Split the line into separate strings. This allows us to...
00830 QStringList llist = QStringList::split(' ', line);
00831 // use SetiContainer's method to retrieve the entries.
00832 score.gaussian.power     = readEntry(llist, "peak").toDouble();
00833 score.gaussian.true_mean = readEntry(llist, "mean").toDouble();
00834 score.gaussian.ra        = readEntry(llist, "ra").toDouble();
00835 score.gaussian.dec       = readEntry(llist, "dec").toDouble();
00836 score.gaussian.sigma     = readEntry(llist, "sigma").toDouble();
00837 score.gaussian.chisq     = readEntry(llist, "chisqr").toDouble();
00838 score.gaussian.fft_len   = readEntry(llist, "fft_len").toInt();
00839 score.gaussian.frequency = readEntry(llist, "freq").toDouble();
00840 score.gaussian.chirprate = readEntry(llist, "chirprate").toDouble();
00841 score.gaussian.score     = score.gaussian.power/score.gaussian.chisq;
00842 
00843 pot = readEntry(llist, "pot");
00844 int dl = readDataString(&data[0], pot, 64);
00845 if(dl > 0)
00846   {
00847   double maxPower = readEntry(llist, "maxpow").toDouble();
00848   for(int i=0;i<dl;i++)
00849     score.gaussian.data[i] = maxPower*((double)data[i]/255.0);
00850   score.gaussian.data_len = dl;
00851   score.gaussian.fft_index = calcGaussianFFTIndex(&score.gaussian);
00852   }
00853 
00854 return(score.gaussian);
00855 }
00856 
00857 /*------------------------------------------------------------------------ */
00858 int SetiLoc::calcGaussianFFTIndex(GaussianScore* g)
00859 {
00860 int i, k;
00861 
00862 int index = 0;
00863 double min = -1.0;
00864 for(i=0; i<64; i++)
00865   {
00866   double lss = 0.0;
00867   double fit;
00868   // calculate the square sum between fit and experimental data
00869   for(k=0; k<64; k++)
00870     {
00871     fit = g->true_mean + g->power*exp(-((i-k)*(i-k))/(g->sigma*g->sigma));
00872     lss += (g->data[k] - fit)*(g->data[k] - fit);
00873     }
00874   // the minimum value will determine the position
00875   if(min < 0.0)
00876     min = lss;
00877   else
00878     {
00879     if(lss < min)
00880       {
00881       min = lss;
00882       index = i;
00883       }
00884     }
00885   }
00886 
00887 return(index);
00888 }
00889 
00890 /*------------------------------------------------------------------------ */
00891 PulseScore SetiLoc::loggedPulseSignal(QString& line)
00892 {
00893 WUScore score;
00894 QString pot;
00895 
00896 initWUScore(&score);
00897 
00898 // replace all occurences of '= ' with '='
00899 line.replace(QRegExp("= +"), "=");
00900 // Split the line into separate strings. This allows us to...
00901 QStringList llist = QStringList::split(' ', line);
00902 // use SetiContainer's method to retrieve the entries.
00903 score.pulse.power     = readEntry(llist, "power").toDouble();
00904 score.pulse.mean      = readEntry(llist, "mean").toDouble();
00905 score.pulse.period    = readEntry(llist, "period").toDouble();
00906 score.pulse.ra        = readEntry(llist, "ra").toDouble();
00907 score.pulse.dec       = readEntry(llist, "dec").toDouble();
00908 score.pulse.fft_len   = readEntry(llist, "fft_len").toInt();
00909 score.pulse.frequency = readEntry(llist, "freq").toDouble();
00910 score.pulse.chirprate = readEntry(llist, "chirp_rate").toDouble();
00911 
00912 // calculate the score from "thresh" and "snr"
00913 double thresh = readEntry(llist, "thresh").toDouble();
00914 double snr    = readEntry(llist, "snr").toDouble();
00915 if(thresh > 0.0) score.pulse.score = snr/thresh;
00916 
00917 int dl = readEntry(llist, "len_prof").toInt();
00918 if(dl > 0)
00919   {
00920   pot = readEntry(llist, "prof");
00921   dl = readDataString(&score.pulse.data[0], pot, dl);
00922   score.pulse.data_len = dl;
00923   }
00924 
00925 return(score.pulse);
00926 }
00927 
00928 /*------------------------------------------------------------------------ */
00929 TripletScore SetiLoc::loggedTripletSignal(QString& line)
00930 {
00931 WUScore score;
00932 QString pot;
00933 
00934 initWUScore(&score);
00935 
00936 // replace all occurences of '= ' with '='
00937 line.replace(QRegExp("= +"), "=");
00938 // Split the line into separate strings. This allows us to...
00939 QStringList llist = QStringList::split(' ', line);
00940 // use SetiContainer's method to retrieve the entries.
00941 score.triplet.power      = readEntry(llist, "power").toDouble();
00942 score.triplet.score      = score.triplet.power;
00943 score.triplet.mean       = readEntry(llist, "mean").toDouble();
00944 score.triplet.period     = readEntry(llist, "period").toDouble();
00945 score.triplet.ra         = readEntry(llist, "ra").toDouble();
00946 score.triplet.dec        = readEntry(llist, "dec").toDouble();
00947 score.triplet.fft_len    = readEntry(llist, "fft_len").toInt();
00948 score.triplet.frequency  = readEntry(llist, "freq").toDouble();
00949 score.triplet.chirprate  = readEntry(llist, "chirp_rate").toDouble();
00950 score.triplet.tpotind0_0 = readEntry(llist, "index0").toInt();
00951 score.triplet.tpotind0_1 = score.triplet.tpotind0_0;
00952 score.triplet.tpotind1_0 = readEntry(llist, "index1").toInt();
00953 score.triplet.tpotind1_1 = score.triplet.tpotind1_0;
00954 score.triplet.tpotind2_0 = readEntry(llist, "index2").toInt();
00955 score.triplet.tpotind2_1 = score.triplet.tpotind2_0;
00956 
00957 int dl = readEntry(llist, "len_prof").toInt();
00958 if(dl > 0)
00959   {
00960   pot = readEntry(llist, "prof");
00961   dl = readDataString(&score.triplet.data[0], pot, dl);
00962   score.triplet.data_len = dl;
00963   }
00964 
00965 return(score.triplet);
00966 }
00967 
00968 #include "setiloc.moc"
00969 
KDE Logo
This file is part of the documentation for Ksetiwatch API Version 2.6.1.
Documentation copyright © 2000-2003 Gordon Machel.
Generated on Fri Jun 6 00:28:15 2003 by doxygen 1.2.18, written by Dimitri van Heesch, © 1997-2002