]> git.donarmstrong.com Git - mothur.git/blob - engine.cpp
removed read.dist, read.otu, read.tree and globaldata. added current to defaults...
[mothur.git] / engine.cpp
1 /*
2  *  engine.cpp
3  *  
4  *
5  *  Created by Pat Schloss on 8/15/08.
6  *  Copyright 2008 Patrick D. Schloss. All rights reserved.
7  *
8  *  There's a TON of duplicated code between InteractEngine and BatchEngine
9  *  I couldn't figure out how to transition between ifstream (batch) and cin (interact)
10  *  Fix later, don't have time now.
11  *
12  */
13
14
15 #include "engine.hpp"
16
17 /***********************************************************************/
18 Engine::Engine(){
19         try {
20                 cFactory = CommandFactory::getInstance();
21                 mout = MothurOut::getInstance();
22         }
23         catch(exception& e) {
24                 mout->errorOut(e, "Engine", "Engine");
25                 exit(1);
26         }
27 }
28 /***********************************************************************/
29 string Engine::findMothursPath(){
30         try { 
31                 
32                 string envPath = getenv("PATH");
33                 string mothurPath = "";
34                 
35                 //delimiting path char
36                 char delim;
37                 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
38                         delim = ':';
39                 #else
40                         delim = ';';
41                 #endif
42                 
43                 //break apart path variable by ':'
44                 vector<string> dirs;
45                 mout->splitAtChar(envPath, dirs, delim);
46                 
47                 //get path related to mothur
48                 for (int i = 0; i < dirs.size(); i++) {
49                         //to lower so we can find it
50                         string tempLower = "";
51                         for (int j = 0; j < dirs[i].length(); j++) {  tempLower += tolower(dirs[i][j]);  }
52                         
53                         //is this mothurs path?
54                         if (tempLower.find("mothur") != -1) {  mothurPath = dirs[i]; break;  }
55                 }
56                 
57                 if (mothurPath != "") {
58                         //add mothur so it looks like what argv would look like
59                         #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
60                                 mothurPath += "/mothur";
61                         #else
62                                 mothurPath += "\\mothur";
63                         #endif
64                 }else {
65                         //okay mothur is not in the path, so the folder mothur is in must be in the path
66                         //lets find out which one
67                         
68                         //get path related to mothur
69                         for (int i = 0; i < dirs.size(); i++) {
70                                                                 
71                                 //is this mothurs path?
72                                 ifstream in;
73                                 string tempIn = dirs[i];
74                                 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
75                                         tempIn += "/mothur";
76                                 #else
77                                         tempIn += "\\mothur";
78                                 #endif
79                                 mout->openInputFile(tempIn, in, "");
80                                 
81                                 //if this file exists
82                                 if (in) { in.close(); mothurPath = tempIn;  break;  }
83                         }
84                 }
85                 
86                 return mothurPath;
87                 
88         }
89         catch(exception& e) {
90                 mout->errorOut(e, "Engine", "findMothursPath");
91                 exit(1);
92         }
93 }
94 /***********************************************************************/
95
96 InteractEngine::InteractEngine(string path){
97
98         
99         string temppath = path.substr(0, (path.find_last_of("othur")-5));
100         
101         //this will happen if you set the path variable to contain mothur's exe location
102         if (temppath == "") { path = findMothursPath(); }
103         
104         mout->argv = path;
105 }
106
107 /***********************************************************************/
108
109 InteractEngine::~InteractEngine(){}
110
111 /***********************************************************************/
112 //This function allows the user to input commands one line at a time until they quit.
113 //If the command is garbage it does nothing.
114 bool InteractEngine::getInput(){
115         try {
116                 string input = "";
117                 string commandName = "";
118                 string options = "";
119                 int quitCommandCalled = 0;
120                 
121                 while(quitCommandCalled != 1){
122
123                         #ifdef USE_MPI
124                                 int pid, processors;
125                                 MPI_Status status;
126                                 MPI_Comm_rank(MPI_COMM_WORLD, &pid); 
127                                 MPI_Comm_size(MPI_COMM_WORLD, &processors);
128                                 
129                                 if (pid == 0) {
130                                 
131                         #endif
132                         
133                         mout->mothurOutEndLine();
134                         
135                         input = getCommand();   
136                         mout->mothurOutEndLine();       
137                         
138                         if (mout->control_pressed) { input = "quit()"; }
139                         
140                         //allow user to omit the () on the quit command
141                         if (input == "quit") { input = "quit()"; }
142
143                         
144                         #ifdef USE_MPI
145                                 //send commandName
146                                 for(int i = 1; i < processors; i++) { 
147                                                 int length = input.length();
148                                                 MPI_Send(&length, 1, MPI_INT, i, 2001, MPI_COMM_WORLD);
149                                                 MPI_Send(&input[0], length, MPI_CHAR, i, 2001, MPI_COMM_WORLD);
150         
151                                         }
152                                 }else {
153                                         int length;
154                                         MPI_Recv(&length, 1, MPI_INT, 0, 2001, MPI_COMM_WORLD, &status);
155                                         //recieve container
156                                         char* tempBuf = new char[length];
157                                         MPI_Recv(&tempBuf[0], length, MPI_CHAR, 0, 2001, MPI_COMM_WORLD, &status);
158                                         
159                                         input = tempBuf;
160                                         if (input.length() > length) { input = input.substr(0, length);  }
161                                         delete tempBuf; 
162                                 }
163
164                         
165                         #endif
166                 
167                         CommandOptionParser parser(input);
168                         commandName = parser.getCommandString();
169         
170                         options = parser.getOptionString();
171                         
172                         if (commandName != "") {
173                                         mout->executing = true;
174                                         #ifdef USE_MPI
175                                                 int pid;
176                                                 MPI_Comm_rank(MPI_COMM_WORLD, &pid); 
177                                                 
178                                                 if ((cFactory->MPIEnabled(commandName)) || (pid == 0)) {
179                                         //cout << pid << " is in execute " << commandName << endl;
180                                         #endif
181                                         //executes valid command
182                                         Command* command = cFactory->getCommand(commandName, options);
183                                         quitCommandCalled = command->execute();
184                                                         
185                                         //if we aborted command
186                                         if (quitCommandCalled == 2) {  mout->mothurOut("[ERROR]: did not complete " + commandName + "."); mout->mothurOutEndLine(); }
187
188                                         mout->control_pressed = 0;
189                                         mout->executing = false;
190                                                                                 
191                                         #ifdef USE_MPI
192                                                 }
193                                         #endif
194                                 }else {         
195                                         mout->mothurOut("Invalid."); 
196                                         mout->mothurOutEndLine();
197                                 }
198                 }       
199                 return 1;
200         }
201         catch(exception& e) {
202                 mout->errorOut(e, "InteractEngine", "getInput");
203                 exit(1);
204         }
205 }
206 /***********************************************************************/
207 string Engine::getCommand()  {
208         try {
209         
210                 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
211                         #ifdef USE_READLINE
212                                 char* nextCommand = NULL;
213                                 nextCommand = readline("mothur > ");
214                                 
215                                 if(nextCommand != NULL) {  add_history(nextCommand);  } 
216                                 else{ //^D causes null string and we want it to quit mothur
217                                         strcpy(nextCommand, "quit"); 
218                                         mout->mothurOut(nextCommand);
219                                 }       
220                                 
221                                 mout->mothurOutJustToLog("mothur > " + toString(nextCommand));
222                                 return nextCommand;
223                         #else
224                                 string nextCommand = "";
225                                 mout->mothurOut("mothur > ");
226                                 getline(cin, nextCommand);
227                                 mout->mothurOutJustToLog("mothur > " + toString(nextCommand));
228                                 
229                                 return nextCommand;
230                         #endif
231                 #else
232                                 string nextCommand = "";
233                                 
234                                 mout->mothurOut("mothur > ");
235                                 getline(cin, nextCommand);
236                                 mout->mothurOutJustToLog(toString(nextCommand));
237                                 
238                                 return nextCommand;
239                 #endif
240         
241                                                 
242         }
243         catch(exception& e) {
244                 mout->errorOut(e, "Engine", "getCommand");
245                 exit(1);
246         }
247 }
248 /***********************************************************************/
249 //This function opens the batchfile to be used by BatchEngine::getInput.
250 BatchEngine::BatchEngine(string path, string batchFileName){
251         try {
252         
253                 openedBatch = mout->openInputFile(batchFileName, inputBatchFile);
254                 
255                 string temppath = path.substr(0, (path.find_last_of("othur")-5));
256         
257                 //this will happen if you set the path variable to contain mothur's exe location
258                 if (temppath == "") { path = findMothursPath(); }
259                 
260                 mout->argv = path;
261                                 
262         }
263         catch(exception& e) {
264                 mout->errorOut(e, "BatchEngine", "BatchEngine");
265                 exit(1);
266         }
267 }
268
269 /***********************************************************************/
270
271 BatchEngine::~BatchEngine(){    }
272
273 /***********************************************************************/
274 //This Function allows the user to run a batchfile containing several commands on Dotur
275 bool BatchEngine::getInput(){
276         try {
277                 //check if this is a valid batchfile
278                 if (openedBatch == 1) {  
279                         mout->mothurOut("unable to open batchfile");  
280                         mout->mothurOutEndLine();
281                         return 1; 
282                 }
283         
284                 string input = "";
285                 string commandName = "";
286                 string options = "";
287                 
288                 //CommandFactory cFactory;
289                 int quitCommandCalled = 0;
290             int count = 0;
291                 while(quitCommandCalled != 1){
292                         
293                         #ifdef USE_MPI
294                                 int pid, processors;
295                                 MPI_Status status;
296                                 MPI_Comm_rank(MPI_COMM_WORLD, &pid); 
297                                 MPI_Comm_size(MPI_COMM_WORLD, &processors);
298                                 
299                                 if (pid == 0) {
300                                 
301                         #endif
302                         
303                         input = getNextCommand(inputBatchFile);
304                         count++;
305                         
306                         #ifdef USE_MPI
307                                 //send commandName
308                                 for(int i = 1; i < processors; i++) { 
309                                                 int length = input.length();
310                                                 MPI_Send(&length, 1, MPI_INT, i, 2001, MPI_COMM_WORLD);
311                                                 MPI_Send(&input[0], length, MPI_CHAR, i, 2001, MPI_COMM_WORLD);
312         
313                                         }
314                                 }else {
315                                         int length;
316                                         MPI_Recv(&length, 1, MPI_INT, 0, 2001, MPI_COMM_WORLD, &status);
317                                         //recieve container
318                                         char* tempBuf = new char[length];
319                                         MPI_Recv(&tempBuf[0], length, MPI_CHAR, 0, 2001, MPI_COMM_WORLD, &status);
320                                         
321                                         input = tempBuf;
322                                         if (input.length() > length) { input = input.substr(0, length);  }
323                                         delete tempBuf; 
324                                 }
325
326                         
327                         #endif
328
329                         
330                         
331                         if (input[0] != '#') {
332                                 
333                                 mout->mothurOutEndLine();
334                                 mout->mothurOut("mothur > " + input);
335                                 mout->mothurOutEndLine();
336                                                         
337                                 if (mout->control_pressed) { input = "quit()"; }
338                                 
339                                 //allow user to omit the () on the quit command
340                                 if (input == "quit") { input = "quit()"; }
341
342                                 CommandOptionParser parser(input);
343                                 commandName = parser.getCommandString();
344                                 options = parser.getOptionString();
345                                                                                 
346                                 if (commandName != "") {
347                                         mout->executing = true;
348                                         #ifdef USE_MPI
349                                                 int pid;
350                                                 MPI_Comm_rank(MPI_COMM_WORLD, &pid); 
351                                                 
352 //cout << pid << " is here " << commandName << '\t' << count << endl;
353                                                 if ((cFactory->MPIEnabled(commandName)) || (pid == 0)) {
354                                         #endif
355                                         //executes valid command
356                                         Command* command = cFactory->getCommand(commandName, options);
357                                         quitCommandCalled = command->execute();
358                                                         
359                                         //if we aborted command
360                                         if (quitCommandCalled == 2) {  mout->mothurOut("[ERROR]: did not complete " + commandName + "."); mout->mothurOutEndLine(); }
361
362                                         mout->control_pressed = 0;
363                                         mout->executing = false;
364                                                                                 
365                                         #ifdef USE_MPI
366                                                 }
367                                         #endif
368                                 }else {         
369                                         mout->mothurOut("Invalid."); 
370                                         mout->mothurOutEndLine();
371                                 }
372                                 
373                         }
374                         mout->gobble(inputBatchFile);
375                 }
376                 
377                 inputBatchFile.close();
378                 return 1;
379         }
380         catch(exception& e) {
381                 mout->errorOut(e, "BatchEngine", "getInput");
382                 exit(1);
383         }
384 }
385 /***********************************************************************/
386 string BatchEngine::getNextCommand(ifstream& inputBatchFile) {
387         try {
388                 
389                 string nextcommand = "";
390                 
391                 if (inputBatchFile.eof()) { nextcommand = "quit()"; }
392                 else { nextcommand = mout->getline(inputBatchFile); }
393                 
394                 return nextcommand;
395         }
396         catch(exception& e) {
397                 mout->errorOut(e, "BatchEngine", "getNextCommand");
398                 exit(1);
399         }
400 }
401
402 /***********************************************************************/
403 /***********************************************************************/
404 //This function opens the batchfile to be used by BatchEngine::getInput.
405 ScriptEngine::ScriptEngine(string path, string commandString){
406         try {
407                 
408                 //remove quotes
409                 listOfCommands = commandString.substr(1, (commandString.length()-1));
410                 
411                 string temppath = path.substr(0, (path.find_last_of("othur")-5));
412
413                 //this will happen if you set the path variable to contain mothur's exe location
414                 if (temppath == "") { path = findMothursPath(); }
415                 
416                 mout->argv = path;
417                                 
418         }
419         catch(exception& e) {
420                 mout->errorOut(e, "ScriptEngine", "ScriptEngine");
421                 exit(1);
422         }
423 }
424
425 /***********************************************************************/
426
427 ScriptEngine::~ScriptEngine(){  }
428
429 /***********************************************************************/
430 //This Function allows the user to run a batchfile containing several commands on mothur
431 bool ScriptEngine::getInput(){
432         try {
433                         
434                 string input = "";
435                 string commandName = "";
436                 string options = "";
437                 
438                 
439                 //CommandFactory cFactory;
440                 int quitCommandCalled = 0;
441         
442                 while(quitCommandCalled != 1){
443                         
444                         #ifdef USE_MPI
445                                 int pid, processors;
446                                 MPI_Status status;
447                                 MPI_Comm_rank(MPI_COMM_WORLD, &pid); 
448                                 MPI_Comm_size(MPI_COMM_WORLD, &processors);
449                                 
450                                 if (pid == 0) {
451                                 
452                         #endif
453                         
454                         input = getNextCommand(listOfCommands); 
455                         
456                         if (input == "") { input = "quit()"; }
457                         
458                         mout->mothurOutEndLine();
459                         mout->mothurOut("mothur > " + input);
460                         mout->mothurOutEndLine();
461                         
462                         #ifdef USE_MPI
463                                 //send commandName
464                                 for(int i = 1; i < processors; i++) { 
465                                                 int length = input.length();
466                                                 MPI_Send(&length, 1, MPI_INT, i, 2001, MPI_COMM_WORLD);
467                                                 MPI_Send(&input[0], length, MPI_CHAR, i, 2001, MPI_COMM_WORLD);
468         
469                                         }
470                                 }else {
471                                         int length;
472                                         MPI_Recv(&length, 1, MPI_INT, 0, 2001, MPI_COMM_WORLD, &status);
473                                         //recieve container
474                                         char* tempBuf = new char[length];
475                                         MPI_Recv(&tempBuf[0], length, MPI_CHAR, 0, 2001, MPI_COMM_WORLD, &status);
476                                         
477                                         input = tempBuf;
478                                         if (input.length() > length) { input = input.substr(0, length);  }
479                                         delete tempBuf; 
480                                 }
481
482                         
483                         #endif
484                         
485                         
486                         if (mout->control_pressed) { input = "quit()"; }
487                                 
488                         //allow user to omit the () on the quit command
489                         if (input == "quit") { input = "quit()"; }
490
491                         CommandOptionParser parser(input);
492                         commandName = parser.getCommandString();
493                         options = parser.getOptionString();
494                                                                                 
495                         if (commandName != "") {
496                                         mout->executing = true;
497                                         #ifdef USE_MPI
498                                                 int pid, numProcesses;
499                                                 
500                                                 MPI_Comm_rank(MPI_COMM_WORLD, &pid); 
501                                                 MPI_Comm_size(MPI_COMM_WORLD, &numProcesses); 
502                                         
503 //cout << pid << " is here " << commandName  << endl;
504                                                 if ((cFactory->MPIEnabled(commandName)) || (pid == 0)) {
505                                                         //cout << pid << " is in execute" << endl;      
506                                         #endif
507                                         //executes valid command
508                                         Command* command = cFactory->getCommand(commandName, options);
509                                         quitCommandCalled = command->execute();
510                                         
511                                         //if we aborted command
512                                         if (quitCommandCalled == 2) {  mout->mothurOut("[ERROR]: did not complete " + commandName + "."); mout->mothurOutEndLine(); }
513                                                         
514                                         mout->control_pressed = 0;
515                                         mout->executing = false;
516                                                                         
517                                         #ifdef USE_MPI
518                                         //cout << pid << " is done in execute" << endl;
519                                                 }
520                                         #endif
521                                 }else {         
522                                         mout->mothurOut("Invalid."); 
523                                         mout->mothurOutEndLine();
524                                 }
525
526                         
527                 }
528                 
529                 return 1;
530         }
531         catch(exception& e) {
532                 mout->errorOut(e, "ScriptEngine", "getInput");
533                 exit(1);
534         }
535 }
536 /***********************************************************************/
537 string ScriptEngine::getNextCommand(string& commandString) {
538         try {
539                 
540                 string nextcommand = "";
541                 int count = 0;
542                 bool ignoreSemiColons = false;
543                 
544                 //go through string until you reach ; or end
545                 while (count < commandString.length()) { 
546                         
547                          //you want to ignore any ; until you reach the next '
548                         if ((commandString[count] == '\'') && (!ignoreSemiColons)) {  ignoreSemiColons = true;  } 
549                         else if ((commandString[count] == '\'') && (ignoreSemiColons)) {  ignoreSemiColons = false;  } 
550                                 
551                         if ((commandString[count] == ';') && (!ignoreSemiColons)) {  break;   }
552                         else {          nextcommand += commandString[count];    }
553                         
554                         count++;
555                 }
556                 
557                 //if you are not at the end
558                 if (count != commandString.length())  {   commandString = commandString.substr(count+1, commandString.length());  }
559                 else { commandString = ""; }
560                                 
561                 
562                 //get rid of spaces in between commands if any
563                 if (commandString.length() > 0) {
564                         while (commandString[0] == ' ') {  
565                                 commandString = commandString.substr(1,commandString.length());
566                                 if (commandString.length() == 0) {  break;  }
567                         }
568                 }
569                 
570                 return nextcommand;
571         }
572         catch(exception& e) {
573                 mout->errorOut(e, "ScriptEngine", "getNextCommand");
574                 exit(1);
575         }
576 }
577 /***********************************************************************/