00001 #ifndef INTERACTIVE_CONSOLE_CPP
00002 #define INTERACTIVE_CONSOLE_CPP
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include "InteractiveConsole.h"
00038 #include "Utilities.h"
00039 #include "ESTAnalyzer.h"
00040 #include "EST.h"
00041 #include "MPIHelper.h"
00042
00043 #include <algorithm>
00044 #include <stdio.h>
00045
00046 #ifdef HAVE_LIBREADLINE
00047 #include <readline/readline.h>
00048 #include <readline/history.h>
00049 #else
00050 #define add_history(x)
00051 #endif
00052
00053 #include <cmath>
00054 #include <iomanip>
00055
00056 #define INTRO \
00057 "\033[1;38mPEACE: Parallel EST Analyzer and Clustering Engine\n" \
00058 "\033[0;39mCopyright (c) Miami University, Oxford, OHIO." \
00059 "All rights reserved.\n" \
00060 "Type the command \033[1;32mhelp\033[0;39m to obtain list " \
00061 "of commands to run\n"
00062
00063
00064 InteractiveConsole::CmdEntry InteractiveConsole::cmdHandlerList[] = {
00065 {"exit", &InteractiveConsole::exit},
00066 {"stats", &InteractiveConsole::printStats},
00067 {"list", &InteractiveConsole::list},
00068 {"analyze", &InteractiveConsole::analyze},
00069 {"help", &InteractiveConsole::help},
00070 {"print", &InteractiveConsole::print},
00071 {"", NULL}
00072 };
00073
00074 InteractiveConsole::InteractiveConsole(ESTAnalyzer* estAnalyzer) :
00075 analyzer(estAnalyzer) {
00076 ASSERT ( analyzer != NULL );
00077 }
00078
00079 InteractiveConsole::~InteractiveConsole() {
00080
00081 }
00082
00083 bool
00084 InteractiveConsole::initialize() {
00085
00086 std::cout << INTRO << std::endl;
00087
00088
00089
00090 std::cout << "Loading ESTs..." << std::flush;
00091 const double startTime = MPI_WTIME();
00092 bool retVal = analyzer->initialize() == 0;
00093
00094 const double elapsedTime = (MPI_WTIME() - startTime) * 1000.0;
00095 if (!retVal) {
00096
00097 std::cerr << "Error initializing EST analyzer.\nExiting.\n";
00098 } else {
00099 std::cout << "Loaded " << EST::getESTCount() << " ESTs.\n"
00100 << "* Elapsed time: " << elapsedTime << " msecs.\n\n";
00101 }
00102
00103 return retVal;
00104 }
00105
00106 void
00107 InteractiveConsole::processCommands() {
00108
00109 if (!initialize()) {
00110
00111 return;
00112 }
00113
00114 bool done = false;
00115 do {
00116
00117 char *cmdLine = readline("\033[1;33mpeace> ");
00118 std::cout << "\033[0;39m";
00119 if (cmdLine == NULL) {
00120
00121 break;
00122 }
00123
00124 std::vector<std::string> cmdWords = tokenize(cmdLine);
00125
00126 if (cmdWords.size() > 0) {
00127 add_history(cmdLine);
00128 }
00129
00130 free(cmdLine);
00131 if (cmdWords.size() < 1) {
00132
00133 continue;
00134 }
00135
00136
00137 std::transform(cmdWords[0].begin(), cmdWords[0].end(),
00138 cmdWords[0].begin(), tolower);
00139
00140 int cmdIndex = 0;
00141 while ((cmdWords[0] != cmdHandlerList[cmdIndex].cmd) &&
00142 (cmdHandlerList[cmdIndex].handler != NULL)) {
00143
00144 cmdIndex++;
00145 }
00146
00147 if (cmdHandlerList[cmdIndex].handler != NULL) {
00148 (this->*cmdHandlerList[cmdIndex].handler)(cmdWords);
00149 } else {
00150
00151 std::cout << "huh?\n";
00152 }
00153
00154 done = (cmdIndex == 0);
00155 } while (!done);
00156 }
00157
00158 std::vector<std::string>
00159 InteractiveConsole::tokenize(const std::string& str,
00160 const std::string& delims) {
00161
00162 std::vector<std::string> tokens;
00163
00164 std::string::size_type lastPos = str.find_first_not_of(delims, 0);
00165
00166 std::string::size_type pos = str.find_first_of(delims, lastPos);
00167
00168 while ((pos != std::string::npos) || (lastPos != std::string::npos)) {
00169
00170 tokens.push_back(str.substr(lastPos, pos - lastPos));
00171
00172 lastPos = str.find_first_not_of(delims, pos);
00173
00174 pos = str.find_first_of(delims, lastPos);
00175 }
00176
00177 return tokens;
00178 }
00179
00180 void
00181 InteractiveConsole::printStats(const std::vector<std::string>& UNREFERENCED_PARAMETER(cmdWords)) {
00182
00183 const double startTime = MPI_WTIME();
00184
00185 const std::vector<EST*>& estList = EST::getESTList();
00186
00187 size_t minLen = 0xffffffff, maxLen = 0;
00188 double lenSum = 0, lenSumSqr = 0;
00189 for(size_t idx = 0; (idx < estList.size()); idx++) {
00190
00191 const size_t len = strlen(estList[idx]->getSequence());
00192
00193 minLen = std::min<size_t>(minLen, len);
00194 maxLen = std::max<size_t>(maxLen, len);
00195
00196 lenSum += len;
00197 lenSumSqr += (len * len);
00198 }
00199
00200 const double meanLen = lenSum / estList.size();
00201 const double stdDev = sqrt((lenSumSqr - estList.size() *
00202 meanLen * meanLen) / (estList.size() - 1));
00203 std::cout << "Number of ests : " << estList.size() << std::endl;
00204 std::cout << "Mean EST size : " << meanLen << " bp\n";
00205 std::cout << "Deviation in EST size: " << stdDev << " bp\n";
00206 std::cout << "Minimum EST size : " << minLen << " bp\n";
00207 std::cout << "Maximum EST size : " << maxLen << " bp\n";
00208
00209
00210
00211 std::cout << "* Elapsed time: "
00212 << ((MPI_WTIME() - startTime) * 1000.0) << " msecs\n";
00213 }
00214
00215 void
00216 InteractiveConsole::exit(const std::vector<std::string>& UNREFERENCED_PARAMETER(cmdWords)) {
00217 std::cout << "PEACE out.\n";
00218 }
00219
00220 void
00221 InteractiveConsole::list(const std::vector<std::string>& UNREFERENCED_PARAMETER(cmdWords)) {
00222
00223 const std::vector<EST*>& estList = EST::getESTList();
00224
00225 std::cout << "Index FASTA Identifier\n"
00226 << "---------------------------------------------------------\n";
00227
00228 for(size_t idx = 0; (idx < estList.size()); idx++) {
00229 std::cout << std::setw(8) << idx
00230 << " : " << estList[idx]->getInfo()
00231 << std::endl;
00232 }
00233 std::cout << "---------------------------------------------------------\n";
00234 }
00235
00236 void
00237 InteractiveConsole::analyze(const std::vector<std::string>& cmdWords) {
00238 if (cmdWords.size() != 3) {
00239 std::cout << "analyze command requires two arguments, the FASTA "
00240 << "identifier or the index of the ESTs to compare.\n";
00241 return;
00242 }
00243
00244 const int index1 = getESTIndex(cmdWords[1]);
00245 const int index2 = getESTIndex(cmdWords[2]);
00246 if ((index1 == -1) || (index2 == -1)) {
00247
00248 return;
00249 }
00250
00251 const EST* const est1 = EST::getEST(index1);
00252 const EST* const est2 = EST::getEST(index2);
00253 std::cout << "Analyzing EST " << est1->getInfo() << " (index: " << index1
00254 << ") with\n"
00255 << " EST " << est2->getInfo() << " (index: " << index2
00256 << ")...\n";
00257
00258 const double startTime = MPI_WTIME();
00259
00260 analyzer->setReferenceEST(index1);
00261
00262 float metric = analyzer->analyze(index2);
00263
00264 const double elapsedTime = (MPI_WTIME() - startTime) * 1000.0;
00265
00266 std::cout << "\033[1;38m" << analyzer->getName()
00267 << (analyzer->isDistanceMetric() ? " distance" : " similarity")
00268 << " metric: " << metric;
00269
00270 int alignmentData = 0;
00271 if (analyzer->getAlignmentData(alignmentData)) {
00272 std::cout << " (Alignment pos: " << alignmentData << ")";
00273 }
00274 std::cout << "\033[0;39m\n";
00275
00276 std::cout << "* Elapsed time: " << elapsedTime << " msecs.\n";
00277 }
00278
00279 int
00280 InteractiveConsole::getESTIndex(const std::string& id) const {
00281
00282 const std::vector<EST*>& estList = EST::getESTList();
00283 const int EstCount = (int) estList.size();
00284
00285
00286 char *endptr = NULL;
00287 int index = strtol(id.c_str(), &endptr, 10);
00288
00289
00290 if ((endptr == NULL) || (*endptr != '\0')) {
00291
00292
00293 for(index = 0; (index < EstCount); index++) {
00294 if (id == estList[index]->getInfo()) {
00295
00296 break;
00297 }
00298 }
00299 }
00300
00301 if ((index < 0) || (index >= EstCount)) {
00302 std::cout << "Invalid EST index/identifier (" << id << ").\n";
00303 return -1;
00304 }
00305
00306 return index;
00307 }
00308
00309 void
00310 InteractiveConsole::print(const std::vector<std::string>& cmdWords) {
00311 if (cmdWords.size() != 2) {
00312 std::cout << "The print command requires one argument, namely "
00313 << "the FASTA identifier or the index of the EST "
00314 << "whose information is to be printed.\n";
00315 return;
00316 }
00317
00318 const int index = getESTIndex(cmdWords[1]);
00319 if (index == -1) {
00320
00321 return;
00322 }
00323
00324 const EST* const est = EST::getEST(index);
00325 std::cout << "Info on EST " << est->getInfo()
00326 << " (index: " << index << "), Len: "
00327 << strlen(est->getSequence()) << " base pairs\n";
00328 std::cout << est->getSequence() << std::endl;
00329 }
00330
00331 void
00332 InteractiveConsole::help(const std::vector<std::string>& UNREFERENCED_PARAMETER(cmdWords)) {
00333
00334
00335 std::cout << "Command Description \n"
00336 << "------- --------------------------------------------\n";
00337 std::cout << "help Shows this information.\n"
00338 << "list List brief info. on all loaded ESTs.\n"
00339 << "print Print information about a given EST.\n"
00340 << "analyze Print d2/clu metrics for a given pair of ESTs.\n"
00341 << "stats Print statistics about all the ESTs.\n"
00342 << "exit Quit out of PEACE interactive console.\n";
00343 }
00344
00345 #ifndef HAVE_LIBREADLINE
00346 char*
00347 InteractiveConsole::readline(const char *prompt) {
00348 std::cout << prompt;
00349 char line[1024];
00350 std::cin.getline(line, 1024);
00351 if (std::cin.gcount() == 0) {
00352
00353 return NULL;
00354 }
00355
00356 const int len = (int) strlen(line) + 1;
00357 char *retVal = (char *) malloc(len);
00358 strcpy(retVal, line);
00359 return retVal;
00360 }
00361 #endif
00362
00363 #endif
00364