]> git.donarmstrong.com Git - mothur.git/blob - pipelinepdscommand.cpp
added remove file option to pipeline command in user mode
[mothur.git] / pipelinepdscommand.cpp
1 /*
2  *  pipelinepdscommand.cpp
3  *  Mothur
4  *
5  *  Created by westcott on 10/5/10.
6  *  Copyright 2010 Schloss Lab. All rights reserved.
7  *
8  */
9
10 #include "pipelinepdscommand.h"
11 #include "sffinfocommand.h"
12 #include "commandoptionparser.hpp"
13
14 //**********************************************************************************************************************
15 vector<string> PipelineCommand::getValidParameters(){   
16         try {
17                 string Array[] =  {"sff","oligos","align","chimera","classify","taxonomy","pipeline","processors","outputdir","inputdir"};
18                 vector<string> myArray (Array, Array+(sizeof(Array)/sizeof(string)));
19                 return myArray;
20         }
21         catch(exception& e) {
22                 m->errorOut(e, "PipelineCommand", "getValidParameters");
23                 exit(1);
24         }
25 }
26 //**********************************************************************************************************************
27 vector<string> PipelineCommand::getRequiredParameters(){        
28         try {
29                 vector<string> myArray;
30                 return myArray;
31         }
32         catch(exception& e) {
33                 m->errorOut(e, "PipelineCommand", "getRequiredParameters");
34                 exit(1);
35         }
36 }
37 //**********************************************************************************************************************
38 vector<string> PipelineCommand::getRequiredFiles(){     
39         try {
40                 vector<string> myArray;
41                 return myArray;
42         }
43         catch(exception& e) {
44                 m->errorOut(e, "PipelineCommand", "getRequiredFiles");
45                 exit(1);
46         }
47 }
48 //**********************************************************************************************************************
49 PipelineCommand::PipelineCommand(string option) {
50         try {
51                 cFactory = CommandFactory::getInstance();
52                 abort = false;
53                 
54                 //allow user to run help
55                 if(option == "help") { help(); abort = true; }
56                 
57                 else {
58                         
59                         //valid paramters for this command
60                         string AlignArray[] =  {"sff","oligos","align","chimera","classify","taxonomy","pipeline","processors","outputdir","inputdir"};
61                         vector<string> myArray (AlignArray, AlignArray+(sizeof(AlignArray)/sizeof(string)));
62                         
63                         OptionParser parser(option);
64                         map<string, string> parameters = parser.getParameters(); 
65                         
66                         ValidParameters validParameter;
67                         map<string, string>::iterator it;
68                         
69                         //check to make sure all parameters are valid for command
70                         for (it = parameters.begin(); it != parameters.end(); it++) { 
71                                 if (validParameter.isValidParameter(it->first, myArray, it->second) != true) {  abort = true;  }
72                         }
73                         
74                         //if the user changes the input directory command factory will send this info to us in the output parameter 
75                         string inputDir = validParameter.validFile(parameters, "inputdir", false);              
76                         if (inputDir == "not found"){   inputDir = "";          }
77                         else {
78                                 string path;
79                                 it = parameters.find("sff");
80                                 //user has given a template file
81                                 if(it != parameters.end()){ 
82                                         path = m->hasPath(it->second);
83                                         //if the user has not given a path then, add inputdir. else leave path alone.
84                                         if (path == "") {       parameters["sff"] = inputDir + it->second;              }
85                                 }
86                                 
87                                 it = parameters.find("oligos");
88                                 //user has given a template file
89                                 if(it != parameters.end()){ 
90                                         path = m->hasPath(it->second);
91                                         //if the user has not given a path then, add inputdir. else leave path alone.
92                                         if (path == "") {       parameters["oligos"] = inputDir + it->second;           }
93                                 }
94                                 
95                                 it = parameters.find("align");
96                                 //user has given a template file
97                                 if(it != parameters.end()){ 
98                                         path = m->hasPath(it->second);
99                                         //if the user has not given a path then, add inputdir. else leave path alone.
100                                         if (path == "") {       parameters["align"] = inputDir + it->second;            }
101                                 }
102                                 
103                                 it = parameters.find("chimera");
104                                 //user has given a template file
105                                 if(it != parameters.end()){ 
106                                         path = m->hasPath(it->second);
107                                         //if the user has not given a path then, add inputdir. else leave path alone.
108                                         if (path == "") {       parameters["chimera"] = inputDir + it->second;          }
109                                 }
110                                 
111                                 it = parameters.find("classify");
112                                 //user has given a template file
113                                 if(it != parameters.end()){ 
114                                         path = m->hasPath(it->second);
115                                         //if the user has not given a path then, add inputdir. else leave path alone.
116                                         if (path == "") {       parameters["classify"] = inputDir + it->second;         }
117                                 }
118                                 
119                                 it = parameters.find("taxonomy");
120                                 //user has given a template file
121                                 if(it != parameters.end()){ 
122                                         path = m->hasPath(it->second);
123                                         //if the user has not given a path then, add inputdir. else leave path alone.
124                                         if (path == "") {       parameters["taxonomy"] = inputDir + it->second;         }
125                                 }
126                                 
127                                 it = parameters.find("pipeline");
128                                 //user has given a template file
129                                 if(it != parameters.end()){ 
130                                         path = m->hasPath(it->second);
131                                         //if the user has not given a path then, add inputdir. else leave path alone.
132                                         if (path == "") {       parameters["pipeline"] = inputDir + it->second;         }
133                                 }
134                         }
135                         
136                         outputDir = validParameter.validFile(parameters, "outputdir", false);           if (outputDir == "not found"){  outputDir = ""; }
137                         
138                         pipeFilename = validParameter.validFile(parameters, "pipeline", true);
139                         if (pipeFilename == "not found") { pipeFilename = "";  }
140                         else if (pipeFilename == "not open") { pipeFilename = ""; abort = true; }
141                         
142                         string temp = validParameter.validFile(parameters, "processors", false);        if (temp == "not found"){       temp = "1";                             }
143                         convert(temp, processors); 
144                         
145                         if (pipeFilename != "") {
146                                 abort = readUsersPipeline();
147                         }else{
148                                 sffFile = validParameter.validFile(parameters, "sff", true);
149                                 if (sffFile == "not found") { m->mothurOut("sff is a required parameter for the pipeline command."); m->mothurOutEndLine(); abort = true;  }
150                                 else if (sffFile == "not open") { sffFile = ""; abort = true; }
151                                         
152                                 oligosFile = validParameter.validFile(parameters, "oligos", true);
153                                 if (oligosFile == "not found") { m->mothurOut("oligos is a required parameter for the pipeline command."); m->mothurOutEndLine(); abort = true;  }
154                                 else if (oligosFile == "not open") { oligosFile = ""; abort = true; }
155                                         
156                                 alignFile = validParameter.validFile(parameters, "align", true);
157                                 if (alignFile == "not found") { m->mothurOut("align is a required parameter for the pipeline command. Please provide the template to align with."); m->mothurOutEndLine(); abort = true;  }
158                                 else if (alignFile == "not open") { alignFile = ""; abort = true; }
159
160                                 chimeraFile = validParameter.validFile(parameters, "chimera", true);
161                                 if (chimeraFile == "not found") { m->mothurOut("chimera is a required parameter for the pipeline command. Please provide the template to check for chimeras with."); m->mothurOutEndLine(); abort = true;  }
162                                 else if (chimeraFile == "not open") { chimeraFile = ""; abort = true; }
163
164                                 classifyFile = validParameter.validFile(parameters, "classify", true);
165                                 if (classifyFile == "not found") { m->mothurOut("classify is a required parameter for the pipeline command. Please provide the template to use with the classifier."); m->mothurOutEndLine(); abort = true;  }
166                                 else if (classifyFile == "not open") { classifyFile = ""; abort = true; }
167
168                                 taxonomyFile = validParameter.validFile(parameters, "taxonomy", true);
169                                 if (taxonomyFile == "not found") { m->mothurOut("taxonomy is a required parameter for the pipeline command."); m->mothurOutEndLine(); abort = true;  }
170                                 else if (taxonomyFile == "not open") { taxonomyFile = ""; abort = true; }
171                         }
172                 }
173
174         }
175         catch(exception& e) {
176                 m->errorOut(e, "PipelineCommand", "PipelineCommand");
177                 exit(1);
178         }
179 }
180 //**********************************************************************************************************************
181
182 void PipelineCommand::help(){
183         try {
184                  m->mothurOut("The pipeline command is designed to guide you through your analysis using mothur.\n"); 
185                  m->mothurOut("The pipeline command parameters are pipeline, sff, oligos, align, chimera, classify, taxonomy and processors.\n"); 
186                  m->mothurOut("The sff parameter allows you to enter your sff file. It is required.\n"); 
187                  m->mothurOut("The oligos parameter allows you to enter your oligos file. It is required.\n"); 
188                  m->mothurOut("The align parameter allows you to enter a template to use with the aligner. It is required.\n"); 
189                  m->mothurOut("The chimera parameter allows you to enter a template to use for chimera detection. It is required.\n"); 
190                  m->mothurOut("The classify parameter allows you to enter a template to use for classification. It is required.\n"); 
191                  m->mothurOut("The taxonomy parameter allows you to enter a taxonomy file for the classify template to use for classification. It is required.\n"); 
192                  m->mothurOut("The processors parameter allows you to specify the number of processors to use. The default is 1.\n");
193                  m->mothurOut("The pipeline parameter allows you to enter your own pipeline file. This file should look like a mothur batchfile, but where you would be using a mothur generated file, you can use mothurmade instead.\n"); 
194                  m->mothurOut("First column contains the command name, and the second column contains the parameter options or 'defaults', meaning use defaults. You may leave out file options.\n");
195                  m->mothurOut("Example: trim.seqs(processors=8, allfiles=T, maxambig=0, maxhomop=8, flip=T, bdiffs=1, pdiffs=2, qwindowaverage=35, qwindowsize=50, fasta=may1.v13.fasta, oligos=may1.v13.oligos, qfile=may1.v13.qual)\n");
196                  m->mothurOut("then, you could enter unique.seqs(fasta=mothurmade), and mothur would use the .trim.fasta file from the trim.seqs command. \n");
197                  m->mothurOut("then you could enter align.seqs(candidate=mothurmade, template=silva.v13.align, processors=8). , and mothur would use the .trim.unique.fasta file from the unique.seqs command. \n");
198                  m->mothurOut("If no pipeline file is given then mothur will use Pat's pipeline. \n\n");
199                  m->mothurOut("Here is a list of the commands used in Pat's pipeline.\n"); 
200                  m->mothurOut("All paralellized commands will use the processors you entered.\n"); 
201                  m->mothurOut("The sffinfo command takes your sff file and extracts the fasta and quality files.\n"); 
202                  m->mothurOut("The trim.seqs command uses your oligos file and the quality and fasta files generated by sffinfo.\n"); 
203                  m->mothurOut("The trim.seqs command sets the following parameters: allfiles=T, maxambig=0, maxhomop=8, flip=T, bdiffs=1, pdiffs=2, qwindowaverage=35, qwindowsize=50.\n"); 
204                  m->mothurOut("The unique.seqs command uses the trimmed fasta file and removes redundant sequences, don't worry the names file generated by unique.seqs will be used in the pipeline to make sure they are included.\n"); 
205                  m->mothurOut("The align.seqs command aligns the unique sequences using the aligners default options. \n"); 
206                  m->mothurOut("The screen.seqs command screens the sequences using optimize=end-minlength. \n"); 
207                  m->mothurOut("The pipeline uses chimera.slayer to detect chimeras using the default options. \n");
208                  m->mothurOut("The pipeline removes all sequences determined to be chimeric by chimera.slayer. \n");
209                  m->mothurOut("The filter.seqs command filters the sequences using vertical=T, trump=. \n"); 
210                  m->mothurOut("The unique.seqs command uses the filtered fasta file and name file to remove sequences that have become redundant after filtering.\n"); 
211                  m->mothurOut("The pre.cluster command clusters sequences that have no more than 2 differences.\n"); 
212                  m->mothurOut("The dist.seqs command is used to generate a column and phylip formatted distance matrix using cutoff=0.20 for column.\n"); 
213                  m->mothurOut("The pipeline uses cluster with method=average, hard=T. \n");
214                  m->mothurOut("The classify.seqs command is used to classify the sequences using the bayesian method with a cutoff of 80.\n"); 
215                  m->mothurOut("The phylotype command is used to cluster the sequences based on their classification.\n"); 
216                  m->mothurOut("The clearcut command is used to generate a tree using neighbor=T. \n");
217                  m->mothurOut("The summary.single and summary.shared commands are run on the otu files from cluster and phylotype commands. \n");
218                  m->mothurOut("The summary.shared command uses calc=sharednseqs-sharedsobs-sharedchao-sharedace-anderberg-jclass-jest-kulczynski-kulczynskicody-lennon-ochiai-sorclass-sorest-whittaker-braycurtis-jabund-morisitahorn-sorabund-thetan-thetayc. \n");
219                  m->mothurOut("The summary.single command uses calc=nseqs-sobs-coverage-bergerparker-chao-ace-jack-bootstrap-boneh-efron-shen-solow-shannon-npshannon-invsimpson-qstat-simpsoneven-shannoneven-heip-smithwilson. \n");
220                  m->mothurOut("The classify.otu command is used to get the concensus taxonomy for otu files from cluster and phylotype commands. \n");
221                  m->mothurOut("The phylo.diversity command run on the tree generated by clearcut with rarefy=T, iters=100. \n");
222                  m->mothurOut("The unifrac commands are also run on the tree generated by clearcut with random=F, distance=T. \n");
223                  m->mothurOut("\n\n");
224         }
225         catch(exception& e) {
226                 m->errorOut(e, "PipelineCommand", "help");
227                 exit(1);
228         }
229 }
230
231 //**********************************************************************************************************************
232
233 PipelineCommand::~PipelineCommand(){}
234
235 //**********************************************************************************************************************
236
237 int PipelineCommand::execute(){
238         try {
239                 if (abort == true) { return 0; }
240                 
241                 int start = time(NULL);
242                 
243                 if (pipeFilename == "") { 
244                         createPatsPipeline(); 
245                         
246                         //run Pats pipeline
247                         for (int i = 0; i < commands.size(); i++) {
248                                 m->mothurOutEndLine(); m->mothurOut("mothur > " + commands[i]); m->mothurOutEndLine();
249                                                         
250                                 if (m->control_pressed) { return 0; }
251
252                                 CommandOptionParser parser(commands[i]);
253                                 string commandName = parser.getCommandString();
254                                 string options = parser.getOptionString();
255                                         
256                                 #ifdef USE_MPI
257                                         int pid;
258                                         MPI_Comm_rank(MPI_COMM_WORLD, &pid); 
259                                         
260                                         if ((cFactory->MPIEnabled(commandName)) || (pid == 0)) {
261                                 #endif
262                                 
263                                 //executes valid command
264                                 Command* command = cFactory->getCommand(commandName, options, "pipe");
265                                 command->execute();
266                                 
267                                 //add output files to list
268                                 map<string, vector<string> > thisCommandsFile = command->getOutputFiles();
269                                 map<string, vector<string> >::iterator itMade;
270                                 for (itMade = thisCommandsFile.begin(); itMade != thisCommandsFile.end(); itMade++) { 
271                                         vector<string> temp = itMade->second; 
272                                         for (int j = 0; j < temp.size(); j++) { outputNames.push_back(temp[j]); }
273                                 }
274                                                                         
275                                 #ifdef USE_MPI
276                                         }
277                                 #endif
278                         }
279                         
280                 }else {  runUsersPipeline(); }
281                 
282                 if (m->control_pressed) { return 0; }
283                 
284                 m->mothurOut("It took " + toString(time(NULL) - start) + " secs to run the pipeline analysis."); m->mothurOutEndLine(); m->mothurOutEndLine();
285                 
286                 m->mothurOutEndLine();
287                 m->mothurOut("Output File Names: "); m->mothurOutEndLine();
288                 for (int i = 0; i < outputNames.size(); i++) {  m->mothurOut(outputNames[i]); m->mothurOutEndLine();    }
289                 m->mothurOutEndLine();
290                 
291                 return 0;
292         }
293         catch(exception& e) {
294                 m->errorOut(e, "PipelineCommand", "execute");
295                 exit(1);
296         }
297 }
298 //**********************************************************************************************************************
299
300 bool PipelineCommand::readUsersPipeline(){
301         try {
302                 
303                 ifstream in;
304                 m->openInputFile(pipeFilename, in);
305                 
306                 string nextCommand = "";
307                 
308                 map<string, vector<string> > mothurMadeFiles;
309                 
310                 while(!in.eof()) {
311                         nextCommand = m->getline(in); m->gobble(in);
312
313                         if (nextCommand[0] != '#') {
314                                 bool error = false;
315                                 
316                                 string commandName, options;
317                                 error = parseCommand(nextCommand, commandName, options);
318                                 
319                                 if (error) { in.close(); return error; }
320                                 if (commandName == "pipeline.pds") { m->mothurOut("Cannot run the pipeline.pds command from inside the pipeline.pds command."); m->mothurOutEndLine(); in.close(); return true; }
321                                 
322                                 error = checkForValidAndRequiredParameters(commandName, options, mothurMadeFiles);
323                                 
324                                 if (error) { in.close(); return error; }
325                         }
326                 }
327                 
328                 in.close();
329                 
330                 return false;
331         }
332         catch(exception& e) {
333                 m->errorOut(e, "PipelineCommand", "readUsersPipeline");
334                 exit(1);
335         }
336 }
337 //**********************************************************************************************************************
338
339 bool PipelineCommand::parseCommand(string nextCommand, string& name, string& options){
340         try {
341                 CommandOptionParser parser(nextCommand);
342                 name = parser.getCommandString();
343                 options = parser.getOptionString();
344                 
345                 if (name == "") { return true; } //name == "" if () are not right
346                 
347                 return false;
348         }
349         catch(exception& e) {
350                 m->errorOut(e, "PipelineCommand", "parseCommand");
351                 exit(1);
352         }
353 }
354 //**********************************************************************************************************************
355
356 bool PipelineCommand::checkForValidAndRequiredParameters(string name, string options, map<string, vector<string> >& mothurMadeFiles){
357         try {
358                 
359                 if (name == "system") { return false; }
360                 
361                 //get shell of the command so we can check to make sure its valid without running it
362                 Command* command = cFactory->getCommand(name);
363                 
364                 //check to make sure all parameters are valid for command
365                 vector<string> validParameters = command->getValidParameters();
366                 
367                 OptionParser parser(options);
368                 map<string, string> parameters = parser.getParameters(); 
369                         
370                 ValidParameters validParameter;
371                 map<string, string>::iterator it;
372                 map<string, vector<string> >::iterator itMade;
373                         
374                 for (it = parameters.begin(); it != parameters.end(); it++) { 
375                         if (validParameter.isValidParameter(it->first, validParameters, it->second) != true) {  return true;  } // not valid
376                         if (it->second == "mothurmade") {
377                                 itMade = mothurMadeFiles.find(it->first);
378                                 
379                                 if (itMade == mothurMadeFiles.end()) {  
380                                         if ((name == "align.seqs") && (it->first == "candidate")) {} //do nothing about candidate
381                                         else {
382                                                 m->mothurOut("You have the " + it->first + " listed as a mothurmade file for the " + name + " command, but it seems mothur will not make that file in your current pipeline, please correct."); m->mothurOutEndLine();
383                                                 return true;
384                                         }
385                                 }
386                         }
387                 }
388                 
389                 //is the command missing any required
390                 vector<string> requiredParameters = command->getRequiredParameters();
391                 
392                 //check for or
393                 bool hasOr = false;
394                 int numFound = 0;
395                 if (requiredParameters.size() > 2) {  
396                         if (requiredParameters[(requiredParameters.size()-1)] == "or") { hasOr = true; }
397                 }
398                         
399                 for (int i = 0; i < requiredParameters.size(); i++) { 
400                         it = parameters.find(requiredParameters[i]);
401                         
402                         if (it != parameters.end()) { numFound++; }
403                         else {
404                                 if (!hasOr) { m->mothurOut(name + " requires the " + requiredParameters[i] + " parameter, please correct."); m->mothurOutEndLine(); }
405                         }
406                 }
407                 
408                 // if all are needed and not all are found
409                 if ((!hasOr) && (numFound != requiredParameters.size())) { return true; }
410                 //if one is needed and none are found
411                 else if ((hasOr) && (numFound == 0)) { return true; }
412                 
413                 //update MothurMade
414                 map<string, vector<string> > thisCommandsFile = command->getOutputFiles();
415                 for (itMade = thisCommandsFile.begin(); itMade != thisCommandsFile.end(); itMade++) { 
416                         mothurMadeFiles[itMade->first] = itMade->second; //adds any new types
417                 }
418                 
419                 return false;
420         }
421         catch(exception& e) {
422                 m->errorOut(e, "PipelineCommand", "checkForValidAndRequiredParameters");
423                 exit(1);
424         }
425 }
426 //**********************************************************************************************************************
427 int PipelineCommand::runUsersPipeline(){
428         try {
429                 ifstream in;
430                 m->openInputFile(pipeFilename, in);
431                 
432                 string nextCommand = "";
433                 
434                 map<string, vector<string> > mothurMadeFiles;
435                 
436                 while(!in.eof()) {
437                         nextCommand = m->getline(in);  m->gobble(in);
438                 
439                         if (nextCommand[0] != '#') {
440                                 CommandOptionParser parser(nextCommand);
441                                 string commandName = parser.getCommandString();
442                                 string options = parser.getOptionString();
443                                 
444                                 if (options != "") {
445                                         bool error = fillInMothurMade(options, mothurMadeFiles);
446                                         if (error) { in.close(); return 0; }
447                                 }
448                                 
449                                 m->mothurOutEndLine(); m->mothurOut("mothur > " + commandName + "(" + options + ")"); m->mothurOutEndLine();
450                                                                 
451                                 if (m->control_pressed) { return 0; }
452                                         
453                                 #ifdef USE_MPI
454                                         int pid;
455                                         MPI_Comm_rank(MPI_COMM_WORLD, &pid); 
456                                         
457                                         if ((cFactory->MPIEnabled(commandName)) || (pid == 0)) {
458                                 #endif
459                                 
460                                 //executes valid command
461                                 Command* command = cFactory->getCommand(commandName, options, "pipe");
462                                 command->execute();
463                                 
464                                 //add output files to list
465                                 map<string, vector<string> > thisCommandsFile = command->getOutputFiles();
466                                 map<string, vector<string> >::iterator itMade;
467                                 map<string, vector<string> >::iterator it;
468                                 for (itMade = thisCommandsFile.begin(); itMade != thisCommandsFile.end(); itMade++) { 
469                 
470                                         vector<string> temp = itMade->second;
471                                         for (int k = 0; k < temp.size(); k++) { outputNames.push_back(temp[k]); }  //
472                                         
473                                         //update Mothur Made for each file
474                                         it = mothurMadeFiles.find(itMade->first);
475                                         
476                                         if (it == mothurMadeFiles.end()) { //new type
477                         
478                                                 mothurMadeFiles[itMade->first] = temp;
479                                 
480                                         }else{ //update existing type
481                                                 vector<string> oldFileNames = it->second;
482                                                 //look at new files, see if an old version of the file exists, if so update, else just add.
483                                                 //for example you may have abrecovery.fasta and amazon.fasta as old files and you created a new amazon.trim.fasta.
484                                                 
485                                                 for (int k = 0; k < temp.size(); k++) {
486                                                         
487                                                         //get base name
488                                                         string root = m->getSimpleName(temp[k]);
489                                                         string individual = "";
490                                                         for(int i=0;i<root.length();i++){
491                                                                 if(root[i] == '.'){
492                                                                         root = individual;
493                                                                         break;
494                                                                 }else{
495                                                                         individual += root[i];
496                                                                 }
497                                                         }
498                                                         
499                                                         //look for that base name in oldfiles
500                                                         int spot = -1;
501                                                         for (int l = 0; l < oldFileNames.size(); l++) {
502                                                                 int pos = oldFileNames[l].find(root);
503                                                                 if (pos != string::npos) {
504                                                                         spot = l;
505                                                                         break;
506                                                                 }
507                                                         }
508                                                         
509                                                         //if you found it update it, else add it
510                                                         if (spot != -1) {
511                                                                 mothurMadeFiles[it->first][spot] = temp[k];
512                                                         }else{
513                                                                 mothurMadeFiles[it->first].push_back(temp[k]);
514                                                         }
515                                                 }
516                                         }
517                                 }
518                                                                         
519                                 #ifdef USE_MPI
520                                         }
521                                 #endif
522                         }
523                 }
524                 
525                 in.close();
526         }
527         catch(exception& e) {
528                 m->errorOut(e, "PipelineCommand", "runUsersPipeline");
529                 exit(1);
530         }
531 }
532 //**********************************************************************************************************************
533 bool PipelineCommand::fillInMothurMade(string& options, map<string, vector<string> >& mothurMadeFiles){
534         try {
535                 OptionParser parser(options);
536                 map<string, string> parameters = parser.getParameters(); 
537                 map<string, string>::iterator it;
538                 map<string, vector<string> >::iterator itMade;
539                 
540                 options = "";
541                 
542                 //fill in mothurmade filenames
543                 for (it = parameters.begin(); it != parameters.end(); it++) { 
544                         string paraType = it->first;
545                         string tempOption = it->second;
546                         
547                         if (tempOption == "mothurmade") {
548                                 
549                                 if (it->first == "candidate") { paraType = "fasta"; }
550                         
551                                 itMade = mothurMadeFiles.find(paraType);
552                                 
553                                 if (itMade == mothurMadeFiles.end()) { 
554                                         m->mothurOut("Looking for a mothurmade " + paraType + " file, but it seems mothur has not made that file type in your current pipeline, please correct."); m->mothurOutEndLine();
555                                         return true;
556                                 }else{
557                                         vector<string> temp = itMade->second;
558                                         
559                                         if (temp.size() > 1) {
560                                                 //ask user which file to use
561                                                 m->mothurOut("More than one file has been created for the " + paraType + " parameter. "); m->mothurOutEndLine();
562                                                 for (int i = 0; i < temp.size(); i++) {
563                                                         m->mothurOut(toString(i) + " - " + temp[i]); m->mothurOutEndLine();
564                                                 }
565                                                 
566                                                 m->mothurOut("Please select the number of the file you would like to use: ");
567                                                 int num = 0;
568                                                 cin >> num;
569                                                 m->mothurOutJustToLog(toString(num)); m->mothurOutEndLine();
570                                                 
571                                                 if ((num < 0) || (num > (temp.size()-1))) { m->mothurOut("Not a valid response, quitting."); m->mothurOutEndLine(); return true; }
572                                                 else {
573                                                         tempOption = temp[num];
574                                                 }
575                                 
576                                                 //clears buffer so next command doesn't have error
577                                                 string s;       
578                                                 getline(cin, s);
579                                                 
580                                                 vector<string> newTemp;
581                                                 for (int i = 0; i < temp.size(); i++) {
582                                                         if (i == num) { newTemp.push_back(temp[i]); }
583                                                         else {
584                                                                 m->mothurOut("Would you like to remove " + temp[i] + " as an option for " + paraType + ", (y/n): "); m->mothurOutEndLine();
585                                                                 string response;
586                                                                 cin >> response;
587                                                                 m->mothurOutJustToLog(response); m->mothurOutEndLine();
588                                                         
589                                                                 if (response == "n") {  newTemp.push_back(temp[i]); }
590                                                         
591                                                                 //clears buffer so next command doesn't have error
592                                                                 string s;       
593                                                                 getline(cin, s);
594                                                         }
595                                                 }
596                                                 
597                                                 mothurMadeFiles[paraType] = newTemp;
598                                                 
599                                                 
600                                         }else if (temp.size() == 0){
601                                                 m->mothurOut("Sorry, we seem to think you created a " + paraType + " file, but it seems mothur doesn't have a filename."); m->mothurOutEndLine();
602                                                 return true;
603                                         }else{
604                                                 tempOption = temp[0];
605                                         }
606                                 }
607                         }
608                         
609                         options += it->first + "=" + tempOption + ", ";
610                 }
611                 
612                 //rip off extra comma
613                 options = options.substr(0, (options.length()-2));
614                 
615                 return false;
616         }
617         catch(exception& e) {
618                 m->errorOut(e, "PipelineCommand", "fillInMothurMade");
619                 exit(1);
620         }
621 }
622
623 //**********************************************************************************************************************
624 void PipelineCommand::createPatsPipeline(){
625         try {
626                 
627                 //sff.info command
628                 string thisCommand = "sffinfo(sff=" + sffFile + ")";
629                 commands.push_back(thisCommand);
630                 
631                 //trim.seqs command
632                 string fastaFile = m->getRootName(m->getSimpleName(sffFile)) + "fasta";
633                 string qualFile = m->getRootName(m->getSimpleName(sffFile)) + "qual";
634                 thisCommand = "trim.seqs(processors=" + toString(processors) + ", fasta=" + fastaFile + ", allfiles=T, maxambig=0, maxhomop=8, flip=T, bdiffs=1, pdiffs=2, qwindowaverage=35, qwindowsize=50, oligos=" + oligosFile + ", qfile=" + qualFile + ")";
635                 commands.push_back(thisCommand);
636                 
637                 //unique.seqs
638                 string groupFile = m->getRootName(m->getSimpleName(fastaFile)) + "groups";
639                 qualFile =  m->getRootName(m->getSimpleName(fastaFile)) + "trim.qual";
640                 fastaFile =  m->getRootName(m->getSimpleName(fastaFile)) + "trim.fasta";
641                 thisCommand = "unique.seqs(fasta=" + fastaFile + ")"; 
642                 commands.push_back(thisCommand);
643                 
644                 //align.seqs
645                 string nameFile = m->getRootName(m->getSimpleName(fastaFile)) + "names";
646                 fastaFile = m->getRootName(m->getSimpleName(fastaFile)) + "unique" + m->getExtension(fastaFile);
647                 thisCommand = "align.seqs(processors=" + toString(processors) + ", candidate=" + fastaFile + ", template=" + alignFile + ")";
648                 commands.push_back(thisCommand);
649                 
650                 //screen.seqs
651                 fastaFile = m->getRootName(m->getSimpleName(fastaFile)) + "align";
652                 thisCommand = "screen.seqs(processors=" + toString(processors) + ", fasta=" + fastaFile + ", name=" + nameFile + ", group=" + groupFile + ", optimize=end-minlength)";
653                 commands.push_back(thisCommand);
654                 
655                 //chimera.slayer
656                 fastaFile = m->getRootName(m->getSimpleName(fastaFile)) + "good" + m->getExtension(fastaFile);
657                 nameFile = m->getRootName(m->getSimpleName(nameFile)) + "good" + m->getExtension(nameFile);
658                 groupFile = m->getRootName(m->getSimpleName(groupFile)) + "good" + m->getExtension(groupFile);
659                 thisCommand = "chimera.slayer(processors=" + toString(processors) + ", fasta=" + fastaFile + ", template=" + chimeraFile + ")";
660                 commands.push_back(thisCommand);
661                 
662                 //remove.seqs
663                 string accnosFile = m->getRootName(m->getSimpleName(fastaFile))  + "slayer.accnos";
664                 thisCommand = "remove.seqs(fasta=" + fastaFile + ", name=" + nameFile + ", group=" + groupFile + ", accnos=" + accnosFile + ", dups=T)";
665                 commands.push_back(thisCommand);
666                 
667                 //filter.seqs
668                 nameFile = m->getRootName(m->getSimpleName(nameFile)) + "pick" + m->getExtension(nameFile);
669                 groupFile = m->getRootName(m->getSimpleName(groupFile)) + "pick" + m->getExtension(groupFile);
670                 fastaFile = m->getRootName(m->getSimpleName(fastaFile)) + "pick" + m->getExtension(fastaFile);
671                 thisCommand = "filter.seqs(processors=" + toString(processors) + ", fasta=" + fastaFile + ", vertical=T, trump=.)";
672                 commands.push_back(thisCommand);
673                 
674                 //unique.seqs
675                 fastaFile =  m->getRootName(m->getSimpleName(fastaFile)) + "filter.fasta";
676                 thisCommand = "unique.seqs(fasta=" + fastaFile + ", name=" + nameFile + ")"; 
677                 commands.push_back(thisCommand);
678                 
679                 //pre.cluster
680                 nameFile = m->getRootName(m->getSimpleName(fastaFile)) + "names";
681                 fastaFile = m->getRootName(m->getSimpleName(fastaFile)) + "unique" + m->getExtension(fastaFile);
682                 thisCommand = "pre.cluster(fasta=" + fastaFile + ", name=" + nameFile + ", diffs=2)"; 
683                 commands.push_back(thisCommand);
684                 
685                 //dist.seqs
686                 nameFile = m->getRootName(m->getSimpleName(fastaFile)) + "precluster.names";
687                 fastaFile = m->getRootName(m->getSimpleName(fastaFile)) + "precluster" + m->getExtension(fastaFile);
688                 thisCommand = "dist.seqs(processors=" + toString(processors) + ", fasta=" + fastaFile + ", cutoff=0.20)";
689                 commands.push_back(thisCommand);
690                 
691                 //dist.seqs
692                 string columnFile = m->getRootName(m->getSimpleName(fastaFile)) + "dist";
693                 thisCommand = "dist.seqs(processors=" + toString(processors) + ", fasta=" + fastaFile + ", output=lt)";
694                 commands.push_back(thisCommand);
695                 
696                 //read.dist
697                 string phylipFile = m->getRootName(m->getSimpleName(fastaFile)) + "phylip.dist";
698                 thisCommand = "read.dist(column=" + columnFile + ", name=" + nameFile + ")";
699                 commands.push_back(thisCommand);
700                 
701                 //cluster
702                 thisCommand = "cluster(method=average, hard=T)";
703                 commands.push_back(thisCommand);
704                 
705                 string listFile = m->getRootName(m->getSimpleName(columnFile)) + "an.list";
706                 string rabundFile = m->getRootName(m->getSimpleName(columnFile)) + "an.rabund";
707                 
708                 //degap.seqs
709                 thisCommand = "degap.seqs(fasta=" + fastaFile + ")";
710                 commands.push_back(thisCommand);
711                 
712                 //classify.seqs
713                 fastaFile = m->getRootName(m->getSimpleName(fastaFile)) + "ng.fasta";
714                 thisCommand = "classify.seqs(processors=" + toString(processors) + ", fasta=" + fastaFile + ", name=" + nameFile + ", template=" + classifyFile + ", taxonomy=" + taxonomyFile + ", cutoff=80)";
715                 commands.push_back(thisCommand);
716                 
717                 string RippedTaxName = m->getRootName(m->getSimpleName(taxonomyFile));
718                 RippedTaxName = m->getExtension(RippedTaxName.substr(0, RippedTaxName.length()-1));
719                 if (RippedTaxName[0] == '.') { RippedTaxName = RippedTaxName.substr(1, RippedTaxName.length()); }
720                 RippedTaxName +=  "."; 
721                 
722                 string fastaTaxFile = m->getRootName(m->getSimpleName(fastaFile)) + RippedTaxName + "taxonomy";
723                 string taxSummaryFile = m->getRootName(m->getSimpleName(fastaFile)) + RippedTaxName + "tax.summary";
724                 
725                 //phylotype
726                 thisCommand = "phylotype(taxonomy=" + fastaTaxFile + ", name=" + nameFile + ")";
727                 commands.push_back(thisCommand);
728                 
729                 string phyloListFile = m->getRootName(m->getSimpleName(fastaTaxFile)) + "tx.list";
730                 string phyloRabundFile = m->getRootName(m->getSimpleName(fastaTaxFile)) + "tx.rabund";
731                 
732                 //clearcut
733                 thisCommand = "clearcut(phylip=" + phylipFile + ", neighbor=T)";
734                 commands.push_back(thisCommand);
735                 
736                 string treeFile = m->getRootName(m->getSimpleName(phylipFile)) + "tre";
737                 
738                 //read.otu
739                 thisCommand = "read.otu(list=" + listFile + ", group=" + groupFile + ", label=0.03)";
740                 commands.push_back(thisCommand);
741                 
742                 string sharedFile = m->getRootName(m->getSimpleName(listFile)) + "shared";
743                 
744                 //read.otu
745                 thisCommand = "read.otu(list=" + phyloListFile + ", group=" + groupFile + ", label=1)";
746                 commands.push_back(thisCommand);
747                 
748                 string phyloSharedFile = m->getRootName(m->getSimpleName(phyloListFile)) + "shared";
749                 
750                 //read.otu
751                 thisCommand = "read.otu(shared=" + sharedFile + ")";
752                 commands.push_back(thisCommand);
753
754                 //summary.single
755                 thisCommand = "summary.single(calc=nseqs-sobs-coverage-bergerparker-chao-ace-jack-bootstrap-boneh-efron-shen-solow-shannon-npshannon-invsimpson-qstat-simpsoneven-shannoneven-heip-smithwilson, size=5000)";
756                 commands.push_back(thisCommand);
757                 
758                 //summary.shared
759                 thisCommand = "summary.shared(calc=sharednseqs-sharedsobs-sharedchao-sharedace-anderberg-jclass-jest-kulczynski-kulczynskicody-lennon-ochiai-sorclass-sorest-whittaker-braycurtis-jabund-morisitahorn-sorabund-thetan-thetayc)";
760                 commands.push_back(thisCommand);
761                 
762                 //read.otu
763                 thisCommand = "read.otu(rabund=" + rabundFile + ", label=0.03)";
764                 commands.push_back(thisCommand);
765                 
766                 //summary.single
767                 thisCommand = "summary.single(calc=nseqs-sobs-coverage-bergerparker-chao-ace-jack-bootstrap-boneh-efron-shen-solow-shannon-npshannon-invsimpson-qstat-simpsoneven-shannoneven-heip-smithwilson, size=5000)";
768                 commands.push_back(thisCommand);
769                 
770                 //read.otu
771                 thisCommand = "read.otu(shared=" + phyloSharedFile + ")";
772                 commands.push_back(thisCommand);
773                 
774                 //summary.single
775                 thisCommand = "summary.single(calc=nseqs-sobs-coverage-bergerparker-chao-ace-jack-bootstrap-boneh-efron-shen-solow-shannon-npshannon-invsimpson-qstat-simpsoneven-shannoneven-heip-smithwilson, size=5000)";
776                 commands.push_back(thisCommand);
777                 
778                 //summary.shared
779                 thisCommand = "summary.shared(calc=sharednseqs-sharedsobs-sharedchao-sharedace-anderberg-jclass-jest-kulczynski-kulczynskicody-lennon-ochiai-sorclass-sorest-whittaker-braycurtis-jabund-morisitahorn-sorabund-thetan-thetayc)";
780                 commands.push_back(thisCommand);
781
782                 //read.otu
783                 thisCommand = "read.otu(rabund=" + phyloRabundFile + ", label=1)";
784                 commands.push_back(thisCommand);
785                 
786                 //summary.single
787                 thisCommand = "summary.single(calc=nseqs-sobs-coverage-bergerparker-chao-ace-jack-bootstrap-boneh-efron-shen-solow-shannon-npshannon-invsimpson-qstat-simpsoneven-shannoneven-heip-smithwilson, size=5000)";
788                 commands.push_back(thisCommand);
789                 
790                 //classify.otu
791                 thisCommand = "classify.otu(taxonomy=" + fastaTaxFile + ", name=" + nameFile + ", list=" + listFile + ", cutoff=51, label=0.03)";
792                 commands.push_back(thisCommand);
793                 
794                 //classify.otu
795                 thisCommand = "classify.otu(taxonomy=" + fastaTaxFile + ", name=" + nameFile + ", list=" + phyloListFile + ", cutoff=51, label=1)";
796                 commands.push_back(thisCommand);
797                 
798                 //read.tree
799                 thisCommand = "read.tree(tree=" + treeFile + ", name=" + nameFile + ", group=" + groupFile + ")";
800                 commands.push_back(thisCommand);
801                 
802                 //phylo.diversity
803                 thisCommand = "phylo.diversity(iters=100,rarefy=T)";
804                 commands.push_back(thisCommand);
805                 
806                 //unifrac.weighted
807                 thisCommand = "unifrac.weighted(random=false, distance=true, groups=all, processors=" + toString(processors) + ")";
808                 commands.push_back(thisCommand);
809                 
810                 //unifrac.unweighted
811                 thisCommand = "unifrac.unweighted(random=false, distance=true, processors=" + toString(processors) + ")";
812                 commands.push_back(thisCommand);
813                 
814                 
815         }
816         catch(exception& e) {
817                 m->errorOut(e, "PipelineCommand", "createPatsPipeline");
818                 exit(1);
819         }
820 }
821
822 //**********************************************************************************************************************