]> git.donarmstrong.com Git - mothur.git/blob - pipelinepdscommand.cpp
fixed phylo.diversity and made trim.seqs with allfiles=T open one file at a time.
[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                 if (pipeFilename == "") { 
242                         createPatsPipeline(); 
243                         
244                         //run Pats pipeline
245                         for (int i = 0; i < commands.size(); i++) {
246                                 m->mothurOutEndLine(); m->mothurOut("mothur > " + commands[i]); m->mothurOutEndLine();
247                                                         
248                                 if (m->control_pressed) { return 0; }
249
250                                 CommandOptionParser parser(commands[i]);
251                                 string commandName = parser.getCommandString();
252                                 string options = parser.getOptionString();
253                                         
254                                 #ifdef USE_MPI
255                                         int pid;
256                                         MPI_Comm_rank(MPI_COMM_WORLD, &pid); 
257                                         
258                                         if ((cFactory->MPIEnabled(commandName)) || (pid == 0)) {
259                                 #endif
260                                 
261                                 //executes valid command
262                                 Command* command = cFactory->getCommand(commandName, options, "pipe");
263                                 command->execute();
264                                 
265                                 //add output files to list
266                                 map<string, vector<string> > thisCommandsFile = command->getOutputFiles();
267                                 map<string, vector<string> >::iterator itMade;
268                                 for (itMade = thisCommandsFile.begin(); itMade != thisCommandsFile.end(); itMade++) { 
269                                         vector<string> temp = itMade->second; 
270                                         for (int j = 0; j < temp.size(); j++) { outputNames.push_back(temp[j]); }
271                                 }
272                                                                         
273                                 #ifdef USE_MPI
274                                         }
275                                 #endif
276                         }
277                         
278                 }else {  runUsersPipeline(); }
279                 
280                 if (m->control_pressed) { return 0; }
281                 
282                 m->mothurOutEndLine();
283                 m->mothurOut("Output File Names: "); m->mothurOutEndLine();
284                 for (int i = 0; i < outputNames.size(); i++) {  m->mothurOut(outputNames[i]); m->mothurOutEndLine();    }
285                 m->mothurOutEndLine();
286                 
287                 return 0;
288         }
289         catch(exception& e) {
290                 m->errorOut(e, "PipelineCommand", "execute");
291                 exit(1);
292         }
293 }
294 //**********************************************************************************************************************
295
296 bool PipelineCommand::readUsersPipeline(){
297         try {
298                 
299                 ifstream in;
300                 m->openInputFile(pipeFilename, in);
301                 
302                 string nextCommand = "";
303                 
304                 map<string, vector<string> > mothurMadeFiles;
305                 
306                 while(!in.eof()) {
307                         nextCommand = m->getline(in); m->gobble(in);
308
309                         if (nextCommand[0] != '#') {
310                                 bool error = false;
311                                 
312                                 string commandName, options;
313                                 error = parseCommand(nextCommand, commandName, options);
314                                 
315                                 if (error) { in.close(); return error; }
316                                 if (commandName == "pipeline.pds") { m->mothurOut("Cannot run the pipeline.pds command from inside the pipeline.pds command."); m->mothurOutEndLine(); in.close(); return true; }
317                                 
318                                 error = checkForValidAndRequiredParameters(commandName, options, mothurMadeFiles);
319                                 
320                                 if (error) { in.close(); return error; }
321                         }
322                 }
323                 
324                 in.close();
325                 
326                 return false;
327         }
328         catch(exception& e) {
329                 m->errorOut(e, "PipelineCommand", "readUsersPipeline");
330                 exit(1);
331         }
332 }
333 //**********************************************************************************************************************
334
335 bool PipelineCommand::parseCommand(string nextCommand, string& name, string& options){
336         try {
337                 CommandOptionParser parser(nextCommand);
338                 name = parser.getCommandString();
339                 options = parser.getOptionString();
340                 
341                 if (name == "") { return true; } //name == "" if () are not right
342                 
343                 return false;
344         }
345         catch(exception& e) {
346                 m->errorOut(e, "PipelineCommand", "parseCommand");
347                 exit(1);
348         }
349 }
350 //**********************************************************************************************************************
351
352 bool PipelineCommand::checkForValidAndRequiredParameters(string name, string options, map<string, vector<string> >& mothurMadeFiles){
353         try {
354                 
355                 //get shell of the command so we can check to make sure its valid without running it
356                 Command* command = cFactory->getCommand(name);
357                 
358                 //check to make sure all parameters are valid for command
359                 vector<string> validParameters = command->getValidParameters();
360                 
361                 OptionParser parser(options);
362                 map<string, string> parameters = parser.getParameters(); 
363                         
364                 ValidParameters validParameter;
365                 map<string, string>::iterator it;
366                 map<string, vector<string> >::iterator itMade;
367                         
368                 for (it = parameters.begin(); it != parameters.end(); it++) { 
369                         if (validParameter.isValidParameter(it->first, validParameters, it->second) != true) {  return true;  } // not valid
370                         if (it->second == "mothurmade") {
371                                 itMade = mothurMadeFiles.find(it->first);
372                                 
373                                 if (itMade == mothurMadeFiles.end()) {  
374                                         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();
375                                         return true;
376                                 }
377                         }
378                 }
379                 
380                 //is the command missing any required
381                 vector<string> requiredParameters = command->getRequiredParameters();
382                 
383                 //check for or
384                 bool hasOr = false;
385                 int numFound = 0;
386                 if (requiredParameters.size() > 2) {  
387                         if (requiredParameters[(requiredParameters.size()-1)] == "or") { hasOr = true; }
388                 }
389                         
390                 for (int i = 0; i < requiredParameters.size(); i++) { 
391                         it = parameters.find(requiredParameters[i]);
392                         
393                         if (it != parameters.end()) { numFound++; }
394                         else {
395                                 if (!hasOr) { m->mothurOut(name + " requires the " + requiredParameters[i] + " parameter, please correct."); m->mothurOutEndLine(); }
396                         }
397                 }
398                 
399                 // if all are needed and not all are found
400                 if ((!hasOr) && (numFound != requiredParameters.size())) { return true; }
401                 //if one is needed and none are found
402                 else if ((hasOr) && (numFound == 0)) { return true; }
403                 
404                 //update MothurMade
405                 map<string, vector<string> > thisCommandsFile = command->getOutputFiles();
406                 for (itMade = thisCommandsFile.begin(); itMade != thisCommandsFile.end(); itMade++) { 
407                         mothurMadeFiles[itMade->first] = itMade->second; //adds any new types
408                 }
409                 
410                 return false;
411         }
412         catch(exception& e) {
413                 m->errorOut(e, "PipelineCommand", "checkForValidAndRequiredParameters");
414                 exit(1);
415         }
416 }
417 //**********************************************************************************************************************
418 int PipelineCommand::runUsersPipeline(){
419         try {
420                 ifstream in;
421                 m->openInputFile(pipeFilename, in);
422                 
423                 string nextCommand = "";
424                 
425                 map<string, vector<string> > mothurMadeFiles;
426                 
427                 while(!in.eof()) {
428                         nextCommand = m->getline(in);  m->gobble(in);
429                 
430                         if (nextCommand[0] != '#') {
431                                 CommandOptionParser parser(nextCommand);
432                                 string commandName = parser.getCommandString();
433                                 string options = parser.getOptionString();
434                                 
435                                 if (options != "") {
436                                         bool error = fillInMothurMade(options, mothurMadeFiles);
437                                         if (error) { in.close(); return 0; }
438                                 }
439                                 
440                                 m->mothurOutEndLine(); m->mothurOut("mothur > " + commandName + "(" + options + ")"); m->mothurOutEndLine();
441                                                                 
442                                 if (m->control_pressed) { return 0; }
443                                         
444                                 #ifdef USE_MPI
445                                         int pid;
446                                         MPI_Comm_rank(MPI_COMM_WORLD, &pid); 
447                                         
448                                         if ((cFactory->MPIEnabled(commandName)) || (pid == 0)) {
449                                 #endif
450                                 
451                                 //executes valid command
452                                 Command* command = cFactory->getCommand(commandName, options, "pipe");
453                                 command->execute();
454                                 
455                                 //add output files to list
456                                 map<string, vector<string> > thisCommandsFile = command->getOutputFiles();
457                                 map<string, vector<string> >::iterator itMade;
458                                 map<string, vector<string> >::iterator it;
459                                 for (itMade = thisCommandsFile.begin(); itMade != thisCommandsFile.end(); itMade++) { 
460                 
461                                         vector<string> temp = itMade->second;
462                                         for (int k = 0; k < temp.size(); k++) { outputNames.push_back(temp[k]); }  //
463                                         
464                                         //update Mothur Made for each file
465                                         it = mothurMadeFiles.find(itMade->first);
466                                         
467                                         if (it == mothurMadeFiles.end()) { //new type
468                         
469                                                 mothurMadeFiles[itMade->first] = temp;
470                                 
471                                         }else{ //update existing type
472                                                 vector<string> oldFileNames = it->second;
473                                                 //look at new files, see if an old version of the file exists, if so update, else just add.
474                                                 //for example you may have abrecovery.fasta and amazon.fasta as old files and you created a new amazon.trim.fasta.
475                                                 
476                                                 for (int k = 0; k < temp.size(); k++) {
477                                                         
478                                                         //get base name
479                                                         string root = m->getSimpleName(temp[k]);
480                                                         string individual = "";
481                                                         for(int i=0;i<root.length();i++){
482                                                                 if(root[i] == '.'){
483                                                                         root = individual;
484                                                                         break;
485                                                                 }else{
486                                                                         individual += root[i];
487                                                                 }
488                                                         }
489                                                         
490                                                         //look for that base name in oldfiles
491                                                         int spot = -1;
492                                                         for (int l = 0; l < oldFileNames.size(); l++) {
493                                                                 int pos = oldFileNames[l].find(root);
494                                                                 if (pos != string::npos) {
495                                                                         spot = l;
496                                                                         break;
497                                                                 }
498                                                         }
499                                                         
500                                                         //if you found it update it, else add it
501                                                         if (spot != -1) {
502                                                                 mothurMadeFiles[it->first][spot] = temp[k];
503                                                         }else{
504                                                                 mothurMadeFiles[it->first].push_back(temp[k]);
505                                                         }
506                                                 }
507                                         }
508                                 }
509                                                                         
510                                 #ifdef USE_MPI
511                                         }
512                                 #endif
513                         }
514                 }
515                 
516                 in.close();
517         }
518         catch(exception& e) {
519                 m->errorOut(e, "PipelineCommand", "runUsersPipeline");
520                 exit(1);
521         }
522 }
523 //**********************************************************************************************************************
524 bool PipelineCommand::fillInMothurMade(string& options, map<string, vector<string> > mothurMadeFiles){
525         try {
526                 OptionParser parser(options);
527                 map<string, string> parameters = parser.getParameters(); 
528                 map<string, string>::iterator it;
529                 map<string, vector<string> >::iterator itMade;
530                 
531                 options = "";
532                 
533                 //fill in mothurmade filenames
534                 for (it = parameters.begin(); it != parameters.end(); it++) { 
535                         if (it->second == "mothurmade") {
536                                 itMade = mothurMadeFiles.find(it->first);
537                                 
538                                 if (itMade == mothurMadeFiles.end()) { 
539                                         m->mothurOut("Looking for a mothurmade " + it->first + " file, but it seems mothur has not made that file type in your current pipeline, please correct."); m->mothurOutEndLine();
540                                         return true;
541                                 }else{
542                                         vector<string> temp = itMade->second;
543                                         
544                                         if (temp.size() > 1) {
545                                                 //ask user which file to use
546                                                 m->mothurOut("More than one file has been created for the " + it->first + " parameter. "); m->mothurOutEndLine();
547                                                 for (int i = 0; i < temp.size(); i++) {
548                                                         m->mothurOut(toString(i) + " - " + temp[i]); m->mothurOutEndLine();
549                                                 }
550                                                 m->mothurOut("Please select the number of the file you would like to use: ");
551                                                 int num = 0;
552                                                 cin >> num;
553                                                 m->mothurOutJustToLog(toString(num)); m->mothurOutEndLine();
554                                                 
555                                                 if ((num < 0) || (num > (temp.size()-1))) { m->mothurOut("Not a valid response, quitting."); m->mothurOutEndLine(); return true; }
556                                                 else {
557                                                         parameters[it->first] = temp[num];
558                                                 }
559                                 
560                                                 //clears buffer so next command doesn't have error
561                                                 string s;       
562                                                 getline(cin, s);
563                                                 
564                                         }else if (temp.size() == 0){
565                                                 m->mothurOut("Sorry, we seem to think you created a " + it->first + " file, but it seems mothur doesn't have a filename."); m->mothurOutEndLine();
566                                                 return true;
567                                         }else{
568                                                 parameters[it->first] = temp[0];
569                                         }
570                                 }
571                         }
572                         
573                         options += it->first + "=" + parameters[it->first] + ", ";
574                 }
575                 
576                 //rip off extra comma
577                 options = options.substr(0, (options.length()-2));
578                 
579                 return false;
580         }
581         catch(exception& e) {
582                 m->errorOut(e, "PipelineCommand", "fillInMothurMade");
583                 exit(1);
584         }
585 }
586
587 //**********************************************************************************************************************
588 void PipelineCommand::createPatsPipeline(){
589         try {
590                 
591                 //sff.info command
592                 string thisCommand = "sffinfo(sff=" + sffFile + ")";
593                 commands.push_back(thisCommand);
594                 
595                 //trim.seqs command
596                 string fastaFile = m->getRootName(m->getSimpleName(sffFile)) + "fasta";
597                 string qualFile = m->getRootName(m->getSimpleName(sffFile)) + "qual";
598                 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 + ")";
599                 commands.push_back(thisCommand);
600                 
601                 //unique.seqs
602                 string groupFile = m->getRootName(m->getSimpleName(fastaFile)) + "groups";
603                 qualFile =  m->getRootName(m->getSimpleName(fastaFile)) + "trim.qual";
604                 fastaFile =  m->getRootName(m->getSimpleName(fastaFile)) + "trim.fasta";
605                 thisCommand = "unique.seqs(fasta=" + fastaFile + ")"; 
606                 commands.push_back(thisCommand);
607                 
608                 //align.seqs
609                 string nameFile = m->getRootName(m->getSimpleName(fastaFile)) + "names";
610                 fastaFile = m->getRootName(m->getSimpleName(fastaFile)) + "unique" + m->getExtension(fastaFile);
611                 thisCommand = "align.seqs(processors=" + toString(processors) + ", candidate=" + fastaFile + ", template=" + alignFile + ")";
612                 commands.push_back(thisCommand);
613                 
614                 //screen.seqs
615                 fastaFile = m->getRootName(m->getSimpleName(fastaFile)) + "align";
616                 thisCommand = "screen.seqs(processors=" + toString(processors) + ", fasta=" + fastaFile + ", name=" + nameFile + ", group=" + groupFile + ", optimize=end-minlength)";
617                 commands.push_back(thisCommand);
618                 
619                 //chimera.slayer
620                 fastaFile = m->getRootName(m->getSimpleName(fastaFile)) + "good" + m->getExtension(fastaFile);
621                 nameFile = m->getRootName(m->getSimpleName(nameFile)) + "good" + m->getExtension(nameFile);
622                 groupFile = m->getRootName(m->getSimpleName(groupFile)) + "good" + m->getExtension(groupFile);
623                 thisCommand = "chimera.slayer(processors=" + toString(processors) + ", fasta=" + fastaFile + ", template=" + chimeraFile + ")";
624                 commands.push_back(thisCommand);
625                 
626                 //remove.seqs
627                 string accnosFile = m->getRootName(m->getSimpleName(fastaFile))  + "slayer.accnos";
628                 thisCommand = "remove.seqs(fasta=" + fastaFile + ", name=" + nameFile + ", group=" + groupFile + ", accnos=" + accnosFile + ", dups=T)";
629                 commands.push_back(thisCommand);
630                 
631                 //filter.seqs
632                 nameFile = m->getRootName(m->getSimpleName(nameFile)) + "pick" + m->getExtension(nameFile);
633                 groupFile = m->getRootName(m->getSimpleName(groupFile)) + "pick" + m->getExtension(groupFile);
634                 fastaFile = m->getRootName(m->getSimpleName(fastaFile)) + "pick" + m->getExtension(fastaFile);
635                 thisCommand = "filter.seqs(processors=" + toString(processors) + ", fasta=" + fastaFile + ", vertical=T, trump=.)";
636                 commands.push_back(thisCommand);
637                 
638                 //unique.seqs
639                 fastaFile =  m->getRootName(m->getSimpleName(fastaFile)) + "filter.fasta";
640                 thisCommand = "unique.seqs(fasta=" + fastaFile + ", name=" + nameFile + ")"; 
641                 commands.push_back(thisCommand);
642                 
643                 //pre.cluster
644                 nameFile = m->getRootName(m->getSimpleName(fastaFile)) + "names";
645                 fastaFile = m->getRootName(m->getSimpleName(fastaFile)) + "unique" + m->getExtension(fastaFile);
646                 thisCommand = "pre.cluster(fasta=" + fastaFile + ", name=" + nameFile + ", diffs=2)"; 
647                 commands.push_back(thisCommand);
648                 
649                 //dist.seqs
650                 nameFile = m->getRootName(m->getSimpleName(fastaFile)) + "precluster.names";
651                 fastaFile = m->getRootName(m->getSimpleName(fastaFile)) + "precluster" + m->getExtension(fastaFile);
652                 thisCommand = "dist.seqs(processors=" + toString(processors) + ", fasta=" + fastaFile + ", cutoff=0.20)";
653                 commands.push_back(thisCommand);
654                 
655                 //dist.seqs
656                 string columnFile = m->getRootName(m->getSimpleName(fastaFile)) + "dist";
657                 thisCommand = "dist.seqs(processors=" + toString(processors) + ", fasta=" + fastaFile + ", output=lt)";
658                 commands.push_back(thisCommand);
659                 
660                 //read.dist
661                 string phylipFile = m->getRootName(m->getSimpleName(fastaFile)) + "phylip.dist";
662                 thisCommand = "read.dist(column=" + columnFile + ", name=" + nameFile + ")";
663                 commands.push_back(thisCommand);
664                 
665                 //cluster
666                 thisCommand = "cluster(method=average, hard=T)";
667                 commands.push_back(thisCommand);
668                 
669                 string listFile = m->getRootName(m->getSimpleName(columnFile)) + "an.list";
670                 string rabundFile = m->getRootName(m->getSimpleName(columnFile)) + "an.rabund";
671                 
672                 //degap.seqs
673                 thisCommand = "degap.seqs(fasta=" + fastaFile + ")";
674                 commands.push_back(thisCommand);
675                 
676                 //classify.seqs
677                 fastaFile = m->getRootName(m->getSimpleName(fastaFile)) + "ng.fasta";
678                 thisCommand = "classify.seqs(processors=" + toString(processors) + ", fasta=" + fastaFile + ", name=" + nameFile + ", template=" + classifyFile + ", taxonomy=" + taxonomyFile + ", cutoff=80)";
679                 commands.push_back(thisCommand);
680                 
681                 string RippedTaxName = m->getRootName(m->getSimpleName(taxonomyFile));
682                 RippedTaxName = m->getExtension(RippedTaxName.substr(0, RippedTaxName.length()-1));
683                 if (RippedTaxName[0] == '.') { RippedTaxName = RippedTaxName.substr(1, RippedTaxName.length()); }
684                 RippedTaxName +=  "."; 
685                 
686                 string fastaTaxFile = m->getRootName(m->getSimpleName(fastaFile)) + RippedTaxName + "taxonomy";
687                 string taxSummaryFile = m->getRootName(m->getSimpleName(fastaFile)) + RippedTaxName + "tax.summary";
688                 
689                 //phylotype
690                 thisCommand = "phylotype(taxonomy=" + fastaTaxFile + ", name=" + nameFile + ")";
691                 commands.push_back(thisCommand);
692                 
693                 string phyloListFile = m->getRootName(m->getSimpleName(fastaTaxFile)) + "tx.list";
694                 string phyloRabundFile = m->getRootName(m->getSimpleName(fastaTaxFile)) + "tx.rabund";
695                 
696                 //clearcut
697                 thisCommand = "clearcut(phylip=" + phylipFile + ", neighbor=T)";
698                 commands.push_back(thisCommand);
699                 
700                 string treeFile = m->getRootName(m->getSimpleName(phylipFile)) + "tre";
701                 
702                 //read.otu
703                 thisCommand = "read.otu(list=" + listFile + ", group=" + groupFile + ", label=0.03)";
704                 commands.push_back(thisCommand);
705                 
706                 string sharedFile = m->getRootName(m->getSimpleName(listFile)) + "shared";
707                 
708                 //read.otu
709                 thisCommand = "read.otu(list=" + phyloListFile + ", group=" + groupFile + ", label=1)";
710                 commands.push_back(thisCommand);
711                 
712                 string phyloSharedFile = m->getRootName(m->getSimpleName(phyloListFile)) + "shared";
713                 
714                 //read.otu
715                 thisCommand = "read.otu(shared=" + sharedFile + ")";
716                 commands.push_back(thisCommand);
717
718                 //summary.single
719                 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)";
720                 commands.push_back(thisCommand);
721                 
722                 //summary.shared
723                 thisCommand = "summary.shared(calc=sharednseqs-sharedsobs-sharedchao-sharedace-anderberg-jclass-jest-kulczynski-kulczynskicody-lennon-ochiai-sorclass-sorest-whittaker-braycurtis-jabund-morisitahorn-sorabund-thetan-thetayc)";
724                 commands.push_back(thisCommand);
725                 
726                 //read.otu
727                 thisCommand = "read.otu(rabund=" + rabundFile + ", label=0.03)";
728                 commands.push_back(thisCommand);
729                 
730                 //summary.single
731                 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)";
732                 commands.push_back(thisCommand);
733                 
734                 //read.otu
735                 thisCommand = "read.otu(shared=" + phyloSharedFile + ")";
736                 commands.push_back(thisCommand);
737                 
738                 //summary.single
739                 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)";
740                 commands.push_back(thisCommand);
741                 
742                 //summary.shared
743                 thisCommand = "summary.shared(calc=sharednseqs-sharedsobs-sharedchao-sharedace-anderberg-jclass-jest-kulczynski-kulczynskicody-lennon-ochiai-sorclass-sorest-whittaker-braycurtis-jabund-morisitahorn-sorabund-thetan-thetayc)";
744                 commands.push_back(thisCommand);
745
746                 //read.otu
747                 thisCommand = "read.otu(rabund=" + phyloRabundFile + ", label=1)";
748                 commands.push_back(thisCommand);
749                 
750                 //summary.single
751                 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)";
752                 commands.push_back(thisCommand);
753                 
754                 //classify.otu
755                 thisCommand = "classify.otu(taxonomy=" + fastaTaxFile + ", name=" + nameFile + ", list=" + listFile + ", cutoff=51, label=0.03)";
756                 commands.push_back(thisCommand);
757                 
758                 //classify.otu
759                 thisCommand = "classify.otu(taxonomy=" + fastaTaxFile + ", name=" + nameFile + ", list=" + phyloListFile + ", cutoff=51, label=1)";
760                 commands.push_back(thisCommand);
761                 
762                 //read.tree
763                 thisCommand = "read.tree(tree=" + treeFile + ", name=" + nameFile + ", group=" + groupFile + ")";
764                 commands.push_back(thisCommand);
765                 
766                 //phylo.diversity
767                 thisCommand = "phylo.diversity(iters=100,rarefy=T)";
768                 commands.push_back(thisCommand);
769                 
770                 //unifrac.weighted
771                 thisCommand = "unifrac.weighted(random=false, distance=true, groups=all, processors=" + toString(processors) + ")";
772                 commands.push_back(thisCommand);
773                 
774                 //unifrac.unweighted
775                 thisCommand = "unifrac.unweighted(random=false, distance=true, processors=" + toString(processors) + ")";
776                 commands.push_back(thisCommand);
777                 
778                 
779         }
780         catch(exception& e) {
781                 m->errorOut(e, "PipelineCommand", "createPatsPipeline");
782                 exit(1);
783         }
784 }
785
786 //**********************************************************************************************************************