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
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
00156 clientOutput = new KTextBrowser();
00157 clientOutput->setCaption(QString(i18n("Location %1: Client Output")).arg(loc));
00158
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
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
00222 initWUScore(&mymax);
00223
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
00236
00237 for(int i=0;i<(int)(sizeof(graphwidget)/sizeof(graphwidget[0]));i++)
00238 if(graphwidget[i])
00239 graphwidget[i]->hide();
00240
00241
00242 QDir d(logDirectory());
00243 d.remove(".triplets.dat");
00244
00245
00246 emit newWorkUnit(wud, description(), color());
00247 }
00248
00249
00250 void SetiLoc::checkWUStatus()
00251 {
00252 if(sets.log == true)
00253 {
00254
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
00264
00265 emit workUnitLogged(this);
00266 }
00267 }
00268 }
00269
00270
00271 QString SetiLoc::logDirectory()
00272 {
00273 QString logdir;
00274
00275
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
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
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
00357 if(f_sel.exists() == false && error == 0)
00358 {
00359 if(f_sel.open(IO_ReadWrite))
00360 {
00361
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
00383
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
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
00431 if(exists(SC_UserInfoFile) && error == 0)
00432 {
00433 for(i=1; i<CSV_USERINFO_COLUMNS; i++)
00434 {
00435 if(i == 4)
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
00446 if(exists(SC_ResultFile) && error == 0)
00447 {
00448 for(i=0; i<CSV_DATAINFO_COLUMNS; i++)
00449 {
00450 if(i == 1)
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
00466
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
00475 entry = readEntry(rsfFileName, "cpu_time");
00476 }
00477 else if(strcmp(csv_state[i].text, "prog") == 0 && warn == 1)
00478 {
00479
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
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
00563 if(logEx) tin << endl;
00564 tin << "[" << readEntry(SC_ResultFile, "name") << "]";
00565
00566 while(line.find("end_seti_header") != 0 && !resFile.atEnd())
00567 line = tout.readLine();
00568
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
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
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
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
00648 if(sets.stopAfterProcess)
00649 client << "-stop_after_process";
00650 if(sets.email)
00651 client << "-email";
00652 if(sets.graphics)
00653 client << "-graphics";
00654
00655 client << "-nice" << QString::number(20 - sets.priority);
00656
00657 if(sets.useProxy)
00658 client << "-proxy"
00659 << sets.proxyServer + ":" + QString::number(sets.proxyPort);
00660
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
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
00675 int i = 20;
00676 while((cltPid = getClientPid()) == oldPid && i > 0)
00677 {
00678 usleep(10000);
00679 i--;
00680 }
00681
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
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
00747 QStringList tlist = QStringList::split(' ', tdata);
00748
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
00762 ll = QStringList::split(',', line);
00763
00764 it = ll.begin();
00765 double tpower2 = (*it).toDouble();
00766
00767 it++;
00768 double tperiod2 = (*it).toDouble();
00769
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
00778 for(int i=0;i<3;i++)
00779 {
00780 it++;
00781 ret += QString(" index%1=%2").arg(i).arg((*it).toInt());
00782 }
00783
00784 ret += " len_prof=512";
00785
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
00804 line.replace(QRegExp("= +"), "=");
00805
00806 QStringList llist = QStringList::split(' ', line);
00807
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
00828 line.replace(QRegExp("= +"), "=");
00829
00830 QStringList llist = QStringList::split(' ', line);
00831
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
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
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
00899 line.replace(QRegExp("= +"), "=");
00900
00901 QStringList llist = QStringList::split(' ', line);
00902
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
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
00937 line.replace(QRegExp("= +"), "=");
00938
00939 QStringList llist = QStringList::split(' ', line);
00940
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