]> git.donarmstrong.com Git - mothur.git/blob - sffmultiplecommand.cpp
changes while testing
[mothur.git] / sffmultiplecommand.cpp
1 //
2 //  sffmultiplecommand.cpp
3 //  Mothur
4 //
5 //  Created by Sarah Westcott on 8/14/12.
6 //  Copyright (c) 2012 Schloss Lab. All rights reserved.
7 //
8
9 #include "sffmultiplecommand.h"
10
11
12
13 //**********************************************************************************************************************
14 vector<string> SffMultipleCommand::setParameters(){     
15         try {           
16                 CommandParameter pfile("file", "InputTypes", "", "", "none", "none", "none","fasta-name",false,true,true); parameters.push_back(pfile);
17         
18         //sffinfo
19                 CommandParameter ptrim("trim", "Boolean", "", "T", "", "", "","",false,false); parameters.push_back(ptrim);
20         
21         //trim.flows
22                 CommandParameter pmaxhomop("maxhomop", "Number", "", "9", "", "", "","",false,false); parameters.push_back(pmaxhomop);
23                 CommandParameter pmaxflows("maxflows", "Number", "", "450", "", "", "","",false,false); parameters.push_back(pmaxflows);
24                 CommandParameter pminflows("minflows", "Number", "", "450", "", "", "","",false,false); parameters.push_back(pminflows);
25                 CommandParameter ppdiffs("pdiffs", "Number", "", "0", "", "", "","",false,false,true); parameters.push_back(ppdiffs);
26                 CommandParameter pbdiffs("bdiffs", "Number", "", "0", "", "", "","",false,false,true); parameters.push_back(pbdiffs);
27         CommandParameter pldiffs("ldiffs", "Number", "", "0", "", "", "","",false,false); parameters.push_back(pldiffs);
28                 CommandParameter psdiffs("sdiffs", "Number", "", "0", "", "", "","",false,false); parameters.push_back(psdiffs);
29         CommandParameter ptdiffs("tdiffs", "Number", "", "0", "", "", "","",false,false); parameters.push_back(ptdiffs);
30                 CommandParameter psignal("signal", "Number", "", "0.50", "", "", "","",false,false); parameters.push_back(psignal);
31                 CommandParameter pnoise("noise", "Number", "", "0.70", "", "", "","",false,false); parameters.push_back(pnoise);
32                 CommandParameter porder("order", "Multiple", "A-B-I", "A", "", "", "","",false,false, true); parameters.push_back(porder);
33         //shhh.flows
34         CommandParameter plookup("lookup", "InputTypes", "", "", "none", "none", "none","",false,false,true); parameters.push_back(plookup);
35                 CommandParameter pcutoff("cutoff", "Number", "", "0.01", "", "", "","",false,false); parameters.push_back(pcutoff);
36                 CommandParameter pmaxiter("maxiter", "Number", "", "1000", "", "", "","",false,false); parameters.push_back(pmaxiter);
37         CommandParameter plarge("large", "Number", "", "-1", "", "", "","",false,false); parameters.push_back(plarge);
38                 CommandParameter psigma("sigma", "Number", "", "60", "", "", "","",false,false); parameters.push_back(psigma);
39                 CommandParameter pmindelta("mindelta", "Number", "", "0.000001", "", "", "","",false,false); parameters.push_back(pmindelta);
40         
41         //trim.seqs parameters
42         CommandParameter pallfiles("allfiles", "Boolean", "", "t", "", "", "","",false,false); parameters.push_back(pallfiles);
43         CommandParameter pflip("flip", "Boolean", "", "F", "", "", "","",false,false,true); parameters.push_back(pflip);
44                 CommandParameter pmaxambig("maxambig", "Number", "", "-1", "", "", "","",false,false); parameters.push_back(pmaxambig);
45                 CommandParameter pminlength("minlength", "Number", "", "0", "", "", "","",false,false); parameters.push_back(pminlength);
46                 CommandParameter pmaxlength("maxlength", "Number", "", "0", "", "", "","",false,false); parameters.push_back(pmaxlength);
47                 CommandParameter pkeepforward("keepforward", "Boolean", "", "F", "", "", "","",false,false); parameters.push_back(pkeepforward);
48         CommandParameter pkeepfirst("keepfirst", "Number", "", "0", "", "", "","",false,false); parameters.push_back(pkeepfirst);
49                 CommandParameter premovelast("removelast", "Number", "", "0", "", "", "","",false,false); parameters.push_back(premovelast);
50
51         
52         CommandParameter pprocessors("processors", "Number", "", "1", "", "", "","",false,false,true); parameters.push_back(pprocessors);
53                 CommandParameter pinputdir("inputdir", "String", "", "", "", "", "","",false,false); parameters.push_back(pinputdir);
54                 CommandParameter poutputdir("outputdir", "String", "", "", "", "", "","",false,false); parameters.push_back(poutputdir);
55                 
56                 vector<string> myArray;
57                 for (int i = 0; i < parameters.size(); i++) {   myArray.push_back(parameters[i].name);          }
58                 return myArray;
59         }
60         catch(exception& e) {
61                 m->errorOut(e, "SffMultipleCommand", "setParameters");
62                 exit(1);
63         }
64 }
65 //**********************************************************************************************************************
66 string SffMultipleCommand::getHelpString(){     
67         try {
68                 string helpString = "";
69                 helpString += "The sff.multiple command reads a file containing sff filenames and optional oligos filenames. It runs the files through sffinfo, trim.flows, shhh.flows and trim.seqs combining the results.\n";
70                 helpString += "The sff.multiple command parameters are: ";
71         vector<string> parameters = setParameters();
72         for (int i = 0; i < parameters.size()-1; i++) {
73             helpString += parameters[i] + ", ";
74         }
75         helpString += parameters[parameters.size()-1] + ".\n";
76                 helpString += "The file parameter allows you to enter the a file containing the list of sff files and optional oligos files.\n";
77         helpString += "The trim parameter allows you to indicate if you would like a sequences and quality scores generated by sffinfo trimmed to the clipQualLeft and clipQualRight values.  Default=True. \n";
78         helpString += "The maxambig parameter allows you to set the maximum number of ambigious bases allowed. The default is -1.\n";
79                 helpString += "The maxhomop parameter allows you to set a maximum homopolymer length. \n";
80                 helpString += "The minlength parameter allows you to set and minimum sequence length. \n";
81                 helpString += "The maxlength parameter allows you to set and maximum sequence length. \n";
82                 helpString += "The tdiffs parameter is used to specify the total number of differences allowed in the sequence. The default is pdiffs + bdiffs + sdiffs + ldiffs.\n";
83                 helpString += "The bdiffs parameter is used to specify the number of differences allowed in the barcode. The default is 0.\n";
84                 helpString += "The pdiffs parameter is used to specify the number of differences allowed in the primer. The default is 0.\n";
85         helpString += "The ldiffs parameter is used to specify the number of differences allowed in the linker. The default is 0.\n";
86                 helpString += "The sdiffs parameter is used to specify the number of differences allowed in the spacer. The default is 0.\n";
87                 helpString += "The allfiles parameter will create separate group and fasta file for each grouping. The default is F.\n";
88                 helpString += "The keepforward parameter allows you to indicate whether you want the forward primer removed or not. The default is F, meaning remove the forward primer.\n";
89                 helpString += "The keepfirst parameter trims the sequence to the first keepfirst number of bases after the barcode or primers are removed, before the sequence is checked to see if it meets the other requirements. \n";
90                 helpString += "The removelast removes the last removelast number of bases after the barcode or primers are removed, before the sequence is checked to see if it meets the other requirements.\n";
91         helpString += "The order parameter options are A, B or I.  Default=A. A = TACG and B = TACGTACGTACGATGTAGTCGAGCATCATCTGACGCAGTACGTGCATGATCTCAGTCAGCAGCTATGTCAGTGCATGCAGTGACTGATCGTCATCAGCTAGCATCGACTGCATAGATCGCATGACGATCGCATATCGTCAGTGCATGTAGTCGAGCATCATCTGACGCAGTACGTGCATGATCTCAGTCAGCAGCTATGTCAGTGCATGCATAGATCGCATGACGATCGCATATCGTCAGTGCAGTGACTGATCGTCATCAGCTAGCATCGACTGCATGTAGTCGAGCATCATCTGACGCAGTACGTGCATAGATCGCATGACGATCGCATATCGTCAGTGCATGATCTCAGTCAGCAGCTATGTCAGTGCATGCAGTGACTGATCGTCATCAGCTAGCATCGACTGCATGTAGTCGAGCATCATCTGACGCAGTACGTGCAGTGACTGATCGTCATCAGCTAGCATCGACTGCATAGATCGCATGACGATCGCATATCGTCAGTGCATGATCTCAGTCAGCAGCTATGTCAGTGCATGCATGTAGTCGAGCATCATCTGACGCAGTACGTGCATAGATCGCATGACGATCGCATATCGTCAGTGCAGTGACTGATCGTCATCAGCTAGCATCGACTGCATGATCTCAGTCAGCAGCTATGTCAGTGCATGCAGTGACTGATCGTCATCAGCTAGCATCGACTGCATAGATCGCATGACGATCGCATATCGTCAGTGCATGATCTCAGTCAGCAGCTATGTCAGTGCATGCATGTAGTCGAGCATCATCTGACGCAGTACGTGCATAGATCGCATGACGATCGCATATCGTCAGTGCATGATCTCAGTCAGCAGCTATGTCAGTGCATGCAGTGACTGATCGTCATCAGCTAGCATCGACTGCATGTAGTCGAGCATCATCTGACGCAGTACGTGCATGATCTCAGTCAGCAGCTATGTCAGTGCATGCATAGATCGCATGACGATCGCATATCGTCAGTGCATGTAGTCGAGCATCATCTGACGCAGTACGTGCAGTGACTGATCGTCATCAGCTAGCATCGACTGCATAGATCGCATGACGATCGCATATCGTCAGTGCATGTAGTCGAGCATCATCTGACGCAGTACGTGCATGATCTCAGTCAGCAGCTATGTCAGTGCATGCAGTGACTGATCGTCATCAGCTAGCATCGACTGCATGATCTCAGTCAGCAGCTATGTCAGTGCATGCAGTGACTGATCGTCATCAGCTAGCATCGACTGCATAGATCGCATGACGATCGCATATCGTCAGTGCATGTAGTCGAGCATCATCTGACGCAGTACGTGCATGATCTCAGTCAGCAGCTATGTCAGTGCATGCATGTAGTCGAGCATCATCTGACGCAGTACGTGCAGTGACTGATCGTCATCAGCTAGCATCGACTGCATAGATCGCATGACGATCGCATATCGTCAGTGCAGTGACTGATCGTCATCAGCTAGCATCGACTGCATGTAGTCGAGCATCATCTGACGCAGTACGTGCATAGATCGCATGACGATCGCATATCGTCAGTGCATGATCTCAGTCAGCAGCTATGTCAGTGCATGCAGTGACTGATCGTCATCAGCTAGCATCGACTGCATGTAGTCGAGCATCATCTGACGCAGTACGTGCATGATCTCAGTCAGCAGCTATGTCAGTGCATGCATAGATCGCATGACGATCGCATATCGTCAGTGCAGTGACTGATCGTCATCAGCTAGCATCGACTGCATGATCTCAGTCAGCAGC and I = TACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGC.\n";
92                 helpString += "Example sff.multiple(file=mySffOligosFile.txt, trim=F).\n";
93                 helpString += "Note: No spaces between parameter labels (i.e. file), '=' and parameters (i.e.mySffOligosFile.txt).\n";
94                 return helpString;
95         }
96         catch(exception& e) {
97                 m->errorOut(e, "SffMultipleCommand", "getHelpString");
98                 exit(1);
99         }
100 }
101 //**********************************************************************************************************************
102 string SffMultipleCommand::getOutputPattern(string type) {
103     try {
104         string pattern = "";
105         
106         if (type == "fasta") {  pattern = "[filename],fasta"; } 
107         else if (type == "name") {  pattern = "[filename],names"; } 
108         else if (type == "group") {  pattern = "[filename],groups"; }
109         else { m->mothurOut("[ERROR]: No definition for type " + type + " output pattern.\n"); m->control_pressed = true;  }
110         
111         return pattern;
112     }
113     catch(exception& e) {
114         m->errorOut(e, "SffMultipleCommand", "getOutputPattern");
115         exit(1);
116     }
117 }
118 //**********************************************************************************************************************
119 SffMultipleCommand::SffMultipleCommand(){       
120         try {
121                 abort = true; calledHelp = true; 
122                 setParameters();
123                 vector<string> tempOutNames;
124                 outputTypes["fasta"] = tempOutNames;
125         outputTypes["name"] = tempOutNames;
126         outputTypes["group"] = tempOutNames;
127         }
128         catch(exception& e) {
129                 m->errorOut(e, "SffMultipleCommand", "SffMultipleCommand");
130                 exit(1);
131         }
132 }
133 //**********************************************************************************************************************
134
135 SffMultipleCommand::SffMultipleCommand(string option)  {
136         try {
137                 abort = false; calledHelp = false;  append=false; makeGroup=false;
138                 
139                 //allow user to run help
140                 if(option == "help") { help(); abort = true; calledHelp = true; }
141                 else if(option == "citation") { citation(); abort = true; calledHelp = true;}
142                 
143                 else {
144                         //valid paramters for this command
145                         vector<string> myArray = setParameters();
146                         
147                         OptionParser parser(option);
148                         map<string, string> parameters = parser.getParameters();
149                         
150                         ValidParameters validParameter;
151             map<string,string>::iterator it;
152             
153                         //check to make sure all parameters are valid for command
154                         for (it = parameters.begin(); it != parameters.end(); it++) { 
155                                 if (validParameter.isValidParameter(it->first, myArray, it->second) != true) {  abort = true;  }
156                         }
157                         
158                         //initialize outputTypes
159                         vector<string> tempOutNames;
160                         outputTypes["fasta"] = tempOutNames;
161             outputTypes["name"] = tempOutNames;
162             outputTypes["group"] = tempOutNames;
163
164                         
165                         //if the user changes the output directory command factory will send this info to us in the output parameter 
166                         outputDir = validParameter.validFile(parameters, "outputdir", false);           if (outputDir == "not found"){  outputDir = "";         }
167                         
168                         //if the user changes the input directory command factory will send this info to us in the output parameter 
169                         string inputDir = validParameter.validFile(parameters, "inputdir", false);              
170                         if (inputDir == "not found"){   inputDir = "";          }
171                         else {
172                                 string path;
173                 it = parameters.find("file");
174                                 //user has given a template file
175                                 if(it != parameters.end()){ 
176                                         path = m->hasPath(it->second);
177                                         //if the user has not given a path then, add inputdir. else leave path alone.
178                                         if (path == "") {       parameters["file"] = inputDir + it->second;             }
179                                 }
180                 
181                 it = parameters.find("lookup");
182                                 //user has given a template file
183                                 if(it != parameters.end()){ 
184                                         path = m->hasPath(it->second);
185                                         //if the user has not given a path then, add inputdir. else leave path alone.
186                                         if (path == "") {       parameters["lookup"] = inputDir + it->second;           }
187                                 }
188                         }
189             
190                         filename = validParameter.validFile(parameters, "file", true);
191             if (filename == "not open") { filename = ""; abort = true; }
192             else if (filename == "not found") { filename = "";  }
193                         
194                         string temp;
195                         temp = validParameter.validFile(parameters, "trim", false);                                     if (temp == "not found"){       temp = "T";                             }
196                         trim = m->isTrue(temp); 
197             
198             temp = validParameter.validFile(parameters, "minflows", false);     if (temp == "not found") { temp = "450"; }
199                         m->mothurConvert(temp, minFlows);  
200             
201                         temp = validParameter.validFile(parameters, "maxflows", false); if (temp == "not found") { temp = "450"; }
202                         m->mothurConvert(temp, maxFlows);  
203             
204             temp = validParameter.validFile(parameters, "maxhomop", false);             if (temp == "not found"){       temp = "9";             }
205                         m->mothurConvert(temp, maxHomoP);  
206             
207                         temp = validParameter.validFile(parameters, "signal", false);           if (temp == "not found"){       temp = "0.50";  }
208                         m->mothurConvert(temp, signal);  
209             
210                         temp = validParameter.validFile(parameters, "noise", false);            if (temp == "not found"){       temp = "0.70";  }
211                         m->mothurConvert(temp, noise);  
212             
213                         temp = validParameter.validFile(parameters, "bdiffs", false);           if (temp == "not found"){       temp = "0";             }
214                         m->mothurConvert(temp, bdiffs);
215                         
216                         temp = validParameter.validFile(parameters, "pdiffs", false);           if (temp == "not found"){       temp = "0";             }
217                         m->mothurConvert(temp, pdiffs);
218                         
219             temp = validParameter.validFile(parameters, "ldiffs", false);               if (temp == "not found") { temp = "0"; }
220                         m->mothurConvert(temp, ldiffs);
221             
222             temp = validParameter.validFile(parameters, "sdiffs", false);               if (temp == "not found") { temp = "0"; }
223                         m->mothurConvert(temp, sdiffs);
224                         
225                         temp = validParameter.validFile(parameters, "tdiffs", false);           if (temp == "not found") { int tempTotal = pdiffs + bdiffs + ldiffs + sdiffs;  temp = toString(tempTotal); }
226                         m->mothurConvert(temp, tdiffs);
227                         
228                         if(tdiffs == 0){        tdiffs = bdiffs + pdiffs + ldiffs + sdiffs;     }
229             
230                         
231                         temp = validParameter.validFile(parameters, "processors", false);       if (temp == "not found"){       temp = m->getProcessors();      }
232                         m->setProcessors(temp);
233                         m->mothurConvert(temp, processors);
234             
235                         temp = validParameter.validFile(parameters, "order", false);  if (temp == "not found"){         temp = "A";     }
236             if (temp.length() > 1) {  m->mothurOut("[ERROR]: " + temp + " is not a valid option for order. order options are A, B, or I. A = TACG, B = TACGTACGTACGATGTAGTCGAGCATCATCTGACGCAGTACGTGCATGATCTCAGTCAGCAGCTATGTCAGTGCATGCAGTGACTGATCGTCATCAGCTAGCATCGACTGCATAGATCGCATGACGATCGCATATCGTCAGTGCATGTAGTCGAGCATCATCTGACGCAGTACGTGCATGATCTCAGTCAGCAGCTATGTCAGTGCATGCATAGATCGCATGACGATCGCATATCGTCAGTGCAGTGACTGATCGTCATCAGCTAGCATCGACTGCATGTAGTCGAGCATCATCTGACGCAGTACGTGCATAGATCGCATGACGATCGCATATCGTCAGTGCATGATCTCAGTCAGCAGCTATGTCAGTGCATGCAGTGACTGATCGTCATCAGCTAGCATCGACTGCATGTAGTCGAGCATCATCTGACGCAGTACGTGCAGTGACTGATCGTCATCAGCTAGCATCGACTGCATAGATCGCATGACGATCGCATATCGTCAGTGCATGATCTCAGTCAGCAGCTATGTCAGTGCATGCATGTAGTCGAGCATCATCTGACGCAGTACGTGCATAGATCGCATGACGATCGCATATCGTCAGTGCAGTGACTGATCGTCATCAGCTAGCATCGACTGCATGATCTCAGTCAGCAGCTATGTCAGTGCATGCAGTGACTGATCGTCATCAGCTAGCATCGACTGCATAGATCGCATGACGATCGCATATCGTCAGTGCATGATCTCAGTCAGCAGCTATGTCAGTGCATGCATGTAGTCGAGCATCATCTGACGCAGTACGTGCATAGATCGCATGACGATCGCATATCGTCAGTGCATGATCTCAGTCAGCAGCTATGTCAGTGCATGCAGTGACTGATCGTCATCAGCTAGCATCGACTGCATGTAGTCGAGCATCATCTGACGCAGTACGTGCATGATCTCAGTCAGCAGCTATGTCAGTGCATGCATAGATCGCATGACGATCGCATATCGTCAGTGCATGTAGTCGAGCATCATCTGACGCAGTACGTGCAGTGACTGATCGTCATCAGCTAGCATCGACTGCATAGATCGCATGACGATCGCATATCGTCAGTGCATGTAGTCGAGCATCATCTGACGCAGTACGTGCATGATCTCAGTCAGCAGCTATGTCAGTGCATGCAGTGACTGATCGTCATCAGCTAGCATCGACTGCATGATCTCAGTCAGCAGCTATGTCAGTGCATGCAGTGACTGATCGTCATCAGCTAGCATCGACTGCATAGATCGCATGACGATCGCATATCGTCAGTGCATGTAGTCGAGCATCATCTGACGCAGTACGTGCATGATCTCAGTCAGCAGCTATGTCAGTGCATGCATGTAGTCGAGCATCATCTGACGCAGTACGTGCAGTGACTGATCGTCATCAGCTAGCATCGACTGCATAGATCGCATGACGATCGCATATCGTCAGTGCAGTGACTGATCGTCATCAGCTAGCATCGACTGCATGTAGTCGAGCATCATCTGACGCAGTACGTGCATAGATCGCATGACGATCGCATATCGTCAGTGCATGATCTCAGTCAGCAGCTATGTCAGTGCATGCAGTGACTGATCGTCATCAGCTAGCATCGACTGCATGTAGTCGAGCATCATCTGACGCAGTACGTGCATGATCTCAGTCAGCAGCTATGTCAGTGCATGCATAGATCGCATGACGATCGCATATCGTCAGTGCAGTGACTGATCGTCATCAGCTAGCATCGACTGCATGATCTCAGTCAGCAGC, and I = TACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGC.\n");  abort=true;
237             }
238             else {
239                 if (toupper(temp[0]) == 'A') {  flowOrder = "A";   }
240                 else if(toupper(temp[0]) == 'B'){
241                     flowOrder = "B";   }
242                 else if(toupper(temp[0]) == 'I'){
243                     flowOrder = "I";   }
244                 else {
245                     m->mothurOut("[ERROR]: " + temp + " is not a valid option for order. order options are A, B, or I. A = TACG, B = TACGTACGTACGATGTAGTCGAGCATCATCTGACGCAGTACGTGCATGATCTCAGTCAGCAGCTATGTCAGTGCATGCAGTGACTGATCGTCATCAGCTAGCATCGACTGCATAGATCGCATGACGATCGCATATCGTCAGTGCATGTAGTCGAGCATCATCTGACGCAGTACGTGCATGATCTCAGTCAGCAGCTATGTCAGTGCATGCATAGATCGCATGACGATCGCATATCGTCAGTGCAGTGACTGATCGTCATCAGCTAGCATCGACTGCATGTAGTCGAGCATCATCTGACGCAGTACGTGCATAGATCGCATGACGATCGCATATCGTCAGTGCATGATCTCAGTCAGCAGCTATGTCAGTGCATGCAGTGACTGATCGTCATCAGCTAGCATCGACTGCATGTAGTCGAGCATCATCTGACGCAGTACGTGCAGTGACTGATCGTCATCAGCTAGCATCGACTGCATAGATCGCATGACGATCGCATATCGTCAGTGCATGATCTCAGTCAGCAGCTATGTCAGTGCATGCATGTAGTCGAGCATCATCTGACGCAGTACGTGCATAGATCGCATGACGATCGCATATCGTCAGTGCAGTGACTGATCGTCATCAGCTAGCATCGACTGCATGATCTCAGTCAGCAGCTATGTCAGTGCATGCAGTGACTGATCGTCATCAGCTAGCATCGACTGCATAGATCGCATGACGATCGCATATCGTCAGTGCATGATCTCAGTCAGCAGCTATGTCAGTGCATGCATGTAGTCGAGCATCATCTGACGCAGTACGTGCATAGATCGCATGACGATCGCATATCGTCAGTGCATGATCTCAGTCAGCAGCTATGTCAGTGCATGCAGTGACTGATCGTCATCAGCTAGCATCGACTGCATGTAGTCGAGCATCATCTGACGCAGTACGTGCATGATCTCAGTCAGCAGCTATGTCAGTGCATGCATAGATCGCATGACGATCGCATATCGTCAGTGCATGTAGTCGAGCATCATCTGACGCAGTACGTGCAGTGACTGATCGTCATCAGCTAGCATCGACTGCATAGATCGCATGACGATCGCATATCGTCAGTGCATGTAGTCGAGCATCATCTGACGCAGTACGTGCATGATCTCAGTCAGCAGCTATGTCAGTGCATGCAGTGACTGATCGTCATCAGCTAGCATCGACTGCATGATCTCAGTCAGCAGCTATGTCAGTGCATGCAGTGACTGATCGTCATCAGCTAGCATCGACTGCATAGATCGCATGACGATCGCATATCGTCAGTGCATGTAGTCGAGCATCATCTGACGCAGTACGTGCATGATCTCAGTCAGCAGCTATGTCAGTGCATGCATGTAGTCGAGCATCATCTGACGCAGTACGTGCAGTGACTGATCGTCATCAGCTAGCATCGACTGCATAGATCGCATGACGATCGCATATCGTCAGTGCAGTGACTGATCGTCATCAGCTAGCATCGACTGCATGTAGTCGAGCATCATCTGACGCAGTACGTGCATAGATCGCATGACGATCGCATATCGTCAGTGCATGATCTCAGTCAGCAGCTATGTCAGTGCATGCAGTGACTGATCGTCATCAGCTAGCATCGACTGCATGTAGTCGAGCATCATCTGACGCAGTACGTGCATGATCTCAGTCAGCAGCTATGTCAGTGCATGCATAGATCGCATGACGATCGCATATCGTCAGTGCAGTGACTGATCGTCATCAGCTAGCATCGACTGCATGATCTCAGTCAGCAGC, and I = TACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGCTACGTACGTCTGAGCATCGATCGATGTACAGC.\n");  abort=true;
246                 }
247             }
248
249             
250             temp = validParameter.validFile(parameters, "cutoff", false);       if (temp == "not found"){       temp = "0.01";          }
251                         m->mothurConvert(temp, cutoff); 
252                         
253                         temp = validParameter.validFile(parameters, "mindelta", false); if (temp == "not found"){       temp = "0.000001";      }
254                         minDelta = temp; 
255             
256                         temp = validParameter.validFile(parameters, "maxiter", false);  if (temp == "not found"){       temp = "1000";          }
257                         m->mothurConvert(temp, maxIters); 
258             
259             temp = validParameter.validFile(parameters, "large", false);        if (temp == "not found"){       temp = "0";             }
260                         m->mothurConvert(temp, largeSize); 
261             if (largeSize != 0) { large = true; }
262             else { large = false;  }
263             if (largeSize < 0) {  m->mothurOut("The value of the large cannot be negative.\n"); }
264             
265                         temp = validParameter.validFile(parameters, "sigma", false);if (temp == "not found")    {       temp = "60";            }
266                         m->mothurConvert(temp, sigma); 
267             
268             temp = validParameter.validFile(parameters, "flip", false);
269                         if (temp == "not found")    {   flip = 0;       }
270                         else {  flip = m->isTrue(temp);         }
271                         
272                         temp = validParameter.validFile(parameters, "maxambig", false);         if (temp == "not found") { temp = "-1"; }
273                         m->mothurConvert(temp, maxAmbig);  
274                        
275                         temp = validParameter.validFile(parameters, "minlength", false);        if (temp == "not found") { temp = "0"; }
276                         m->mothurConvert(temp, minLength); 
277                         
278                         temp = validParameter.validFile(parameters, "maxlength", false);        if (temp == "not found") { temp = "0"; }
279                         m->mothurConvert(temp, maxLength);
280                                                 
281                         temp = validParameter.validFile(parameters, "keepfirst", false);        if (temp == "not found") { temp = "0"; }
282                         convert(temp, keepFirst);
283             
284                         temp = validParameter.validFile(parameters, "removelast", false);       if (temp == "not found") { temp = "0"; }
285                         convert(temp, removeLast);
286                         
287                         temp = validParameter.validFile(parameters, "allfiles", false);         if (temp == "not found") { temp = "F"; }
288                         allFiles = m->isTrue(temp);
289             
290             temp = validParameter.validFile(parameters, "keepforward", false);          if (temp == "not found") { temp = "F"; }
291                         keepforward = m->isTrue(temp);
292             
293             temp = validParameter.validFile(parameters, "lookup", true);
294                         if (temp == "not found")        {
295                 string path = m->argv;
296                 string tempPath = path;
297                 for (int i = 0; i < path.length(); i++) { tempPath[i] = tolower(path[i]); }
298                 path = path.substr(0, (tempPath.find_last_of('m')));
299                 
300 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) || (__linux__) || (__unix__) || (__unix)
301                 path += "lookupFiles/";
302 #else
303                 path += "lookupFiles\\";
304 #endif
305                                 lookupFileName = m->getFullPathName(path) + "LookUp_Titanium.pat";
306                                 
307                                 int ableToOpen;
308                                 ifstream in;
309                                 ableToOpen = m->openInputFile(lookupFileName, in, "noerror");
310                                 in.close();     
311                                 
312                                 //if you can't open it, try input location
313                                 if (ableToOpen == 1) {
314                                         if (inputDir != "") { //default path is set
315                                                 string tryPath = inputDir + m->getSimpleName(lookupFileName);
316                                                 m->mothurOut("Unable to open " + lookupFileName + ". Trying input directory " + tryPath); m->mothurOutEndLine();
317                                                 ifstream in2;
318                                                 ableToOpen = m->openInputFile(tryPath, in2, "noerror");
319                                                 in2.close();
320                                                 lookupFileName = tryPath;
321                                         }
322                                 }
323                                 
324                                 //if you can't open it, try default location
325                                 if (ableToOpen == 1) {
326                                         if (m->getDefaultPath() != "") { //default path is set
327                                                 string tryPath = m->getDefaultPath() + m->getSimpleName(lookupFileName);
328                                                 m->mothurOut("Unable to open " + lookupFileName + ". Trying default " + tryPath); m->mothurOutEndLine();
329                                                 ifstream in2;
330                                                 ableToOpen = m->openInputFile(tryPath, in2, "noerror");
331                                                 in2.close();
332                                                 lookupFileName = tryPath;
333                                         }
334                                 }
335                                 
336                                 //if you can't open it its not in current working directory or inputDir, try mothur excutable location
337                                 if (ableToOpen == 1) {
338                                         string exepath = m->argv;
339                                         string tempPath = exepath;
340                                         for (int i = 0; i < exepath.length(); i++) { tempPath[i] = tolower(exepath[i]); }
341                                         exepath = exepath.substr(0, (tempPath.find_last_of('m')));
342                                         
343                                         string tryPath = m->getFullPathName(exepath) + m->getSimpleName(lookupFileName);
344                                         m->mothurOut("Unable to open " + lookupFileName + ". Trying mothur's executable location " + tryPath); m->mothurOutEndLine();
345                                         ifstream in2;
346                                         ableToOpen = m->openInputFile(tryPath, in2, "noerror");
347                                         in2.close();
348                                         lookupFileName = tryPath;
349                                 }
350                                 
351                                 if (ableToOpen == 1) {  m->mothurOut("Unable to open " + lookupFileName + "."); m->mothurOutEndLine(); abort=true;  }
352                         }
353                         else if(temp == "not open")     {       
354                                 
355                                 lookupFileName = validParameter.validFile(parameters, "lookup", false);
356                                 
357                                 //if you can't open it its not inputDir, try mothur excutable location
358                                 string exepath = m->argv;
359                                 string tempPath = exepath;
360                                 for (int i = 0; i < exepath.length(); i++) { tempPath[i] = tolower(exepath[i]); }
361                                 exepath = exepath.substr(0, (tempPath.find_last_of('m')));
362                 
363                                 string tryPath = m->getFullPathName(exepath) + m->getSimpleName(lookupFileName);
364                                 m->mothurOut("Unable to open " + lookupFileName + ". Trying mothur's executable location " + tryPath); m->mothurOutEndLine();
365                                 ifstream in2;
366                                 int ableToOpen = m->openInputFile(tryPath, in2, "noerror");
367                                 in2.close();
368                                 lookupFileName = tryPath;
369                                 
370                                 if (ableToOpen == 1) {  m->mothurOut("Unable to open " + lookupFileName + "."); m->mothurOutEndLine(); abort=true;  }
371                         }else                                           {       lookupFileName = temp;  }
372                 }
373         }
374         catch(exception& e) {
375                 m->errorOut(e, "SffMultipleCommand", "SffMultipleCommand");
376                 exit(1);
377         }
378 }
379 //**********************************************************************************************************************
380 int SffMultipleCommand::execute(){
381         try {
382                 if (abort == true) { if (calledHelp) { return 0; }  return 2;   }
383                 
384                 vector<string> sffFiles, oligosFiles;
385         readFile(sffFiles, oligosFiles);
386         
387         outputDir = m->hasPath(filename);
388         string fileroot = outputDir + m->getRootName(m->getSimpleName(filename));
389         map<string, string> variables; 
390                 variables["[filename]"] = fileroot;
391         string fasta = getOutputFileName("fasta",variables);
392         string name = getOutputFileName("name",variables);
393         string group = getOutputFileName("group",variables);
394         
395         if (m->control_pressed) { return 0; }
396         
397         if (sffFiles.size() < processors) { processors = sffFiles.size(); }
398         
399 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) || (__linux__) || (__unix__) || (__unix)
400 #else
401         //trim.flows, shhh.flows cannot handle multiple processors for windows.
402         processors = 1; m->mothurOut("This command can only use 1 processor on Windows platforms, using 1 processors.\n\n");
403 #endif
404         if (processors == 1) { driver(sffFiles, oligosFiles, 0, sffFiles.size(), fasta, name, group); }
405         else { createProcesses(sffFiles, oligosFiles, fasta, name, group); } 
406                 
407                 if (m->control_pressed) {  for (int i = 0; i < outputNames.size(); i++) {       m->mothurRemove(outputNames[i]);        } return 0; }
408                 
409         if (append) { 
410             outputNames.push_back(fasta); outputTypes["fasta"].push_back(fasta);
411             m->setFastaFile(fasta);
412             outputNames.push_back(name); outputTypes["name"].push_back(name);
413             m->setNameFile(name);
414             if (makeGroup) { outputNames.push_back(group); outputTypes["group"].push_back(group); m->setGroupFile(group); }
415         }
416         
417                 //report output filenames
418                 m->mothurOutEndLine();
419                 m->mothurOut("Output File Names: "); m->mothurOutEndLine();
420                 for (int i = 0; i < outputNames.size(); i++) {  m->mothurOut(outputNames[i]); m->mothurOutEndLine();    }
421                 m->mothurOutEndLine();
422         
423                 return 0;
424         }
425         catch(exception& e) {
426                 m->errorOut(e, "SffMultipleCommand", "execute");
427                 exit(1);
428         }
429 }
430 //**********************************************************************************************************************
431 int SffMultipleCommand::readFile(vector<string>& sffFiles, vector<string>& oligosFiles){
432         try {
433         
434         ifstream in;
435         m->openInputFile(filename, in);
436         bool allBlank = true;
437         bool allFull = true;
438         
439         string oligos, sff;
440         while (!in.eof()) {
441             
442             if (m->control_pressed) { break; }
443             
444             in >> sff;
445             
446             sff = m->getFullPathName(sff);
447             
448             //ignore file pairing
449             if(sff[0] == '#'){ while (!in.eof())        {       char c = in.get();  if (c == 10 || c == 13){    break;  }       } m->gobble(in); }
450             else { //check for oligos file
451                 oligos = "";
452             
453                 // get rest of line in case there is a oligos filename
454                 while (!in.eof())       {       
455                     char c = in.get(); 
456                     if (c == 10 || c == 13 || c == -1){ break;  }
457                     else if (c == 32 || c == 9){;} //space or tab
458                     else {      oligos += c;  }
459                 } 
460                 sffFiles.push_back(sff);
461                 if (oligos != "") { oligos = m->getFullPathName(oligos); allBlank = false;  }
462                 if (oligos == "") { allFull = false;  }
463                 oligosFiles.push_back(oligos); //will push a blank if there is not an oligos for this sff file
464             }
465             m->gobble(in);
466         }
467         in.close();
468         
469         if (allBlank || allFull) { append = true; }
470         if (allFull) { makeGroup = true; }
471         
472         return 0;
473     }
474         catch(exception& e) {
475                 m->errorOut(e, "SffMultipleCommand", "readFile");
476                 exit(1);
477         }
478 }
479 //**********************************************************************************************************************
480 //runs sffinfo, summary.seqs, trim.flows, shhh.flows, trim.seqs, summary.seqs for each sff file.
481 int SffMultipleCommand::driver(vector<string> sffFiles, vector<string> oligosFiles, int start, int end, string fasta, string name, string group){
482     try {
483         m->mothurRemove(fasta); m->mothurRemove(name); m->mothurRemove(group);
484         int count = 0;
485         for (int s = start; s < end; s++) {
486             
487             string sff = sffFiles[s];
488             string oligos = oligosFiles[s];
489             
490             m->mothurOut("\n>>>>>\tProcessing " + sff + " (file " + toString(s+1) + " of " + toString(sffFiles.size()) + ")\t<<<<<\n");
491             
492             //run sff.info
493             string inputString = "sff=" + sff + ", flow=T";
494             if (trim) { inputString += ", trim=T"; }
495             m->mothurOut("/******************************************/"); m->mothurOutEndLine(); 
496             m->mothurOut("Running command: sffinfo(" + inputString + ")"); m->mothurOutEndLine(); 
497             m->mothurCalling = true;
498             
499             Command* sffCommand = new SffInfoCommand(inputString);
500             sffCommand->execute();
501             
502             if (m->control_pressed){ break; }
503             
504             map<string, vector<string> > filenames = sffCommand->getOutputFiles();
505             
506             delete sffCommand;
507             m->mothurCalling = false;
508             m->mothurOutEndLine(); 
509             
510             //run summary.seqs on the fasta file
511             string fastaFile = "";
512             map<string, vector<string> >::iterator it = filenames.find("fasta");
513             if (it != filenames.end()) {  if ((it->second).size() != 0) { fastaFile = (it->second)[0];  } }
514             else {  m->mothurOut("[ERROR]: sffinfo did not create a fasta file, quitting.\n"); m->control_pressed = true; break;  }
515             
516             inputString = "fasta=" + fastaFile + ", processors=1";
517             m->mothurOutEndLine(); 
518             m->mothurOut("Running command: summary.seqs(" + inputString + ")"); m->mothurOutEndLine(); 
519             m->mothurCalling = true;
520             
521             Command* summarySeqsCommand = new SeqSummaryCommand(inputString);
522             summarySeqsCommand->execute();
523             
524             if (m->control_pressed){ break; }
525             
526             map<string, vector<string> > temp = summarySeqsCommand->getOutputFiles();
527             mergeOutputFileList(filenames, temp);
528             
529             delete summarySeqsCommand;
530             m->mothurCalling = false;
531             
532             m->mothurOutEndLine(); 
533             
534             //run trim.flows on the fasta file
535             string flowFile = "";
536             it = filenames.find("flow");
537             if (it != filenames.end()) {  if ((it->second).size() != 0) { flowFile = (it->second)[0];  } }
538             else {  m->mothurOut("[ERROR]: sffinfo did not create a flow file, quitting.\n"); m->control_pressed = true; break;  }
539             
540             inputString = "flow=" + flowFile;
541             if (oligos != "") { inputString += ", oligos=" + oligos; }
542             inputString += ", maxhomop=" + toString(maxHomoP) + ", maxflows=" + toString(maxFlows) + ", minflows=" + toString(minFlows);
543             inputString += ", pdiffs=" + toString(pdiffs) + ", bdiffs=" + toString(bdiffs) + ", ldiffs=" + toString(ldiffs) + ", sdiffs=" + toString(sdiffs);
544             inputString += ", tdiffs=" + toString(tdiffs) + ", signal=" + toString(signal) + ", noise=" + toString(noise) + ", order=" + flowOrder + ", processors=1";
545             
546             m->mothurOutEndLine(); 
547             m->mothurOut("Running command: trim.flows(" + inputString + ")"); m->mothurOutEndLine(); 
548             m->mothurCalling = true;
549             
550             Command* trimFlowCommand = new TrimFlowsCommand(inputString);
551             trimFlowCommand->execute();
552             
553             if (m->control_pressed){ break; }
554             
555             temp = trimFlowCommand->getOutputFiles();
556             mergeOutputFileList(filenames, temp);
557             
558             delete trimFlowCommand;
559             m->mothurCalling = false;
560             
561             
562             string fileFileName = "";
563             flowFile = "";
564             if (oligos != "") { 
565                 it = temp.find("file");
566                 if (it != temp.end()) {  if ((it->second).size() != 0) { fileFileName = (it->second)[0];  } }
567                 else {  m->mothurOut("[ERROR]: trim.flows did not create a file file, quitting.\n"); m->control_pressed = true; break;  }
568             }else {
569                 vector<string> flowFiles;
570                 it = temp.find("flow");
571                 if (it != temp.end()) {  if ((it->second).size() != 0) { flowFiles = (it->second);  } }
572                 else {  m->mothurOut("[ERROR]: trim.flows did not create a flow file, quitting.\n"); m->control_pressed = true; break;  }
573                 
574                 for (int i = 0; i < flowFiles.size(); i++) {
575                     string end = flowFiles[i].substr(flowFiles[i].length()-9);
576                     if (end == "trim.flow") {
577                         flowFile = flowFiles[i]; i+=flowFiles.size(); //if we found the trim.flow file stop looking
578                     }
579                 }
580             }
581             
582             if ((fileFileName == "") && (flowFile == "")) { m->mothurOut("[ERROR]: trim.flows did not create a file file or a trim.flow file, quitting.\n"); m->control_pressed = true; break;  }
583             
584             if (fileFileName != "") { inputString = "file=" + fileFileName; }
585             else { inputString = "flow=" + flowFile; }
586             
587             inputString += ", lookup=" + lookupFileName + ", cutoff=" + toString(cutoff); + ", maxiters=" + toString(maxIters);
588             if (large) { inputString += ", large=" + toString(largeSize); }
589             inputString += ", sigma=" +toString(sigma);
590             inputString += ", mindelta=" + toString(minDelta);  
591             inputString += ", order=" + flowOrder + ", processors=1";
592             
593             //run shhh.flows
594             m->mothurOutEndLine(); 
595             m->mothurOut("Running command: shhh.flows(" + inputString + ")"); m->mothurOutEndLine(); 
596             m->mothurCalling = true;
597             
598             Command* shhhFlowCommand = new ShhherCommand(inputString);
599             shhhFlowCommand->execute();
600             
601             if (m->control_pressed){ break; }
602             
603             temp = shhhFlowCommand->getOutputFiles();
604             mergeOutputFileList(filenames, temp);
605             
606             delete shhhFlowCommand;
607             m->mothurCalling = false;
608             
609             vector<string> fastaFiles;
610             vector<string> nameFiles;
611             it = temp.find("fasta");
612             if (it != temp.end()) {  if ((it->second).size() != 0) { fastaFiles = (it->second);  } }
613             else {  m->mothurOut("[ERROR]: shhh.flows did not create a fasta file, quitting.\n"); m->control_pressed = true; break;  }
614            
615             it = temp.find("name");
616             if (it != temp.end()) {  if ((it->second).size() != 0) { nameFiles = (it->second);  } }
617             else {  m->mothurOut("[ERROR]: shhh.flows did not create a name file, quitting.\n"); m->control_pressed = true; break;  }
618             
619             //find fasta and name files with the shortest name.  This is because if there is a composite name it will be the shortest.
620             fastaFile = fastaFiles[0];
621             for (int i = 1; i < fastaFiles.size(); i++) { if (fastaFiles[i].length() < fastaFile.length()) { fastaFile = fastaFiles[i]; } }
622             string nameFile = nameFiles[0];
623             for (int i = 1; i < nameFiles.size(); i++) { if (nameFiles[i].length() < nameFile.length()) { nameFile = nameFiles[i]; } }
624             
625             inputString = "fasta=" + fastaFile + ", name=" + nameFile;
626             if (oligos != "") { inputString += ", oligos=" + oligos; }
627             if (allFiles) { inputString += ", allfiles=t"; }
628             else { inputString += ", allfiles=f";  }
629             if (flip) { inputString += ", flip=t"; }
630             else { inputString += ", flip=f";  }
631             if (keepforward) { inputString += ", keepforward=t"; }
632             else { inputString += ", keepforward=f";  }
633             
634             
635             inputString += ", pdiffs=" + toString(pdiffs) + ", bdiffs=" + toString(bdiffs) + ", ldiffs=" + toString(ldiffs) + ", sdiffs=" + toString(sdiffs);
636             inputString += ", tdiffs=" + toString(tdiffs) + ", maxambig=" + toString(maxAmbig) + ", minlength=" + toString(minLength) + ", maxlength=" + toString(maxLength);
637             if (keepFirst != 0) { inputString += ", keepfirst=" + toString(keepFirst); }
638             if (removeLast != 0) { inputString += ", removelast=" + toString(removeLast); }
639             inputString += ", processors=1";
640             
641             //run trim.seqs
642             m->mothurOutEndLine(); 
643             m->mothurOut("Running command: trim.seqs(" + inputString + ")"); m->mothurOutEndLine(); 
644             m->mothurCalling = true;
645             
646             Command* trimseqsCommand = new TrimSeqsCommand(inputString);
647             trimseqsCommand->execute();
648             
649             if (m->control_pressed){ break; }
650             
651             temp = trimseqsCommand->getOutputFiles();
652             mergeOutputFileList(filenames, temp);
653             
654             delete trimseqsCommand;
655             m->mothurCalling = false;
656             
657             it = temp.find("fasta");
658             if (it != temp.end()) {  if ((it->second).size() != 0) { fastaFiles = (it->second);  } }
659             else {  m->mothurOut("[ERROR]: trim.seqs did not create a fasta file, quitting.\n"); m->control_pressed = true; break;  }
660             
661             for (int i = 0; i < fastaFiles.size(); i++) {
662                 string end = fastaFiles[i].substr(fastaFiles[i].length()-10);
663                 if (end == "trim.fasta") {
664                     fastaFile = fastaFiles[i]; i+=fastaFiles.size(); //if we found the trim.fasta file stop looking
665                 }
666             }
667             
668             it = temp.find("name");
669             if (it != temp.end()) {  if ((it->second).size() != 0) { nameFiles = (it->second);  } }
670             else {  m->mothurOut("[ERROR]: trim.seqs did not create a name file, quitting.\n"); m->control_pressed = true; break;  }
671             
672             for (int i = 0; i < nameFiles.size(); i++) {
673                 string end = nameFiles[i].substr(nameFiles[i].length()-10);
674                 if (end == "trim.names") {
675                     nameFile = nameFiles[i]; i+=nameFiles.size(); //if we found the trim.names file stop looking
676                 }
677             }
678             
679             vector<string> groupFiles;
680             string groupFile = "";
681             if (makeGroup) {
682                 it = temp.find("group");
683                 if (it != temp.end()) {  if ((it->second).size() != 0) { groupFiles = (it->second);  } }
684             
685                 //find group file with the shortest name.  This is because if there is a composite group file it will be the shortest.
686                 groupFile = groupFiles[0];
687                 for (int i = 1; i < groupFiles.size(); i++) { if (groupFiles[i].length() < groupFile.length()) { groupFile = groupFiles[i]; } }
688             }
689             
690             inputString = "fasta=" + fastaFile + ", processors=1, name=" + nameFile;
691             m->mothurOutEndLine(); 
692             m->mothurOut("Running command: summary.seqs(" + inputString + ")"); m->mothurOutEndLine(); 
693             m->mothurCalling = true;
694             
695             summarySeqsCommand = new SeqSummaryCommand(inputString);
696             summarySeqsCommand->execute();
697             
698             if (m->control_pressed){ break; }
699             
700             temp = summarySeqsCommand->getOutputFiles();
701             mergeOutputFileList(filenames, temp);
702             
703             delete summarySeqsCommand;
704             m->mothurCalling = false;
705             
706             m->mothurOutEndLine(); 
707             m->mothurOut("/******************************************/"); m->mothurOutEndLine(); 
708             
709             if (append) {
710                 m->appendFiles(fastaFile, fasta);
711                 m->appendFiles(nameFile, name);
712                 if (makeGroup) { m->appendFiles(groupFile, group);  }
713             }
714             count++;
715             
716             for (it = filenames.begin(); it != filenames.end(); it++) {
717                 for (int i = 0; i < (it->second).size(); i++) {
718                     outputNames.push_back((it->second)[i]); outputTypes[it->first].push_back((it->second)[i]);
719                 }
720             }
721         }
722         
723         return count;
724     }
725         catch(exception& e) {
726                 m->errorOut(e, "SffMultipleCommand", "driver");
727                 exit(1);
728         }
729 }
730 //**********************************************************************************************************************
731 int SffMultipleCommand::mergeOutputFileList(map<string, vector<string> >& files, map<string, vector<string> >& temp){
732     try {
733         map<string, vector<string> >::iterator it;
734         for (it = temp.begin(); it != temp.end(); it++) {
735             map<string, vector<string> >::iterator it2 = files.find(it->first);
736             if (it2 == files.end()) { //we do not already have this type so just add it
737                 files[it->first] = it->second;
738             }else { //merge them
739                 for (int i = 0; i < (it->second).size(); i++) {
740                     files[it->first].push_back((it->second)[i]);
741                 }
742             }
743         }
744         
745         return 0;
746     }
747         catch(exception& e) {
748                 m->errorOut(e, "SffMultipleCommand", "mergeOutputFileList");
749                 exit(1);
750         }
751 }
752 //**********************************************************************************************************************
753 int SffMultipleCommand::createProcesses(vector<string> sffFiles, vector<string> oligosFiles, string fasta, string name, string group){
754     try {
755         vector<int> processIDS;
756                 int process = 1;
757                 int num = 0;
758                                 
759                 //divide the groups between the processors
760                 vector<linePair> lines;
761         vector<int> numFilesToComplete;
762                 int numFilesPerProcessor = sffFiles.size() / processors;
763                 for (int i = 0; i < processors; i++) {
764                         int startIndex =  i * numFilesPerProcessor;
765                         int endIndex = (i+1) * numFilesPerProcessor;
766                         if(i == (processors - 1)){      endIndex = sffFiles.size();     }
767                         lines.push_back(linePair(startIndex, endIndex));
768             numFilesToComplete.push_back((endIndex-startIndex));
769                 }
770                 
771 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) || (__linux__) || (__unix__) || (__unix)          
772                 
773                 //loop through and create all the processes you want
774                 while (process != processors) {
775                         int pid = fork();
776                         
777                         if (pid > 0) {
778                                 processIDS.push_back(pid);  //create map from line number to pid so you can append files in correct order later
779                                 process++;
780                         }else if (pid == 0){
781                                 num = driver(sffFiles, oligosFiles, lines[process].start, lines[process].end, fasta + toString(getpid()) + ".temp", name  + toString(getpid()) + ".temp", group  + toString(getpid()) + ".temp");
782                 
783                 //pass numSeqs to parent
784                                 ofstream out;
785                                 string tempFile = toString(getpid()) + ".num.temp";
786                                 m->openOutputFile(tempFile, out);
787                                 out << num << '\t' << outputNames.size() << endl;
788                 for (int i = 0; i < outputNames.size(); i++) {  out << outputNames[i] << endl;  }
789                                 out.close();
790                 
791                                 exit(0);
792                         }else { 
793                                 m->mothurOut("[ERROR]: unable to spawn the necessary processes."); m->mothurOutEndLine(); 
794                                 for (int i = 0; i < processIDS.size(); i++) { kill (processIDS[i], SIGINT); }
795                                 exit(0);
796                         }
797                 }
798                 
799                 //do my part
800                 num = driver(sffFiles, oligosFiles, lines[0].start, lines[0].end, fasta, name, group);
801                 
802                 //force parent to wait until all the processes are done
803                 for (int i=0;i<processIDS.size();i++) { 
804                         int temp = processIDS[i];
805                         wait(&temp);
806                 }
807         
808         for (int i=0;i<processIDS.size();i++) { 
809             ifstream in;
810                         string tempFile = toString(processIDS[i]) + ".num.temp";
811                         m->openInputFile(tempFile, in);
812                         if (!in.eof()) { 
813                 int tempNum = 0; int outputNamesSize = 0; 
814                 in >> tempNum >> outputNamesSize; m->gobble(in);
815                 for (int j = 0; j < outputNamesSize; j++) {
816                     string tempName;
817                     in >> tempName; m->gobble(in);
818                     outputNames.push_back(tempName);
819                 }
820                 if (tempNum != numFilesToComplete[i+1]) {
821                     m->mothurOut("[ERROR]: main process expected " + toString(processIDS[i]) + " to complete " + toString(numFilesToComplete[i+1]) + " files, and it only reported completing " + toString(tempNum) + ". This will cause file mismatches.  The flow files may be too large to process with multiple processors. \n");
822                 }
823             }
824                         in.close(); m->mothurRemove(tempFile);
825             
826             if (append) {
827                 m->appendFiles(fasta+toString(processIDS[i])+".temp", fasta);   m->mothurRemove(fasta+toString(processIDS[i])+".temp");
828                 m->appendFiles(name+toString(processIDS[i])+".temp", name);     m->mothurRemove(name+toString(processIDS[i])+".temp");
829                 if (makeGroup) { m->appendFiles(group+toString(processIDS[i])+".temp", group);  m->mothurRemove(group+toString(processIDS[i])+".temp"); }
830             }
831         }
832 #endif
833         return 0;
834         
835     }
836         catch(exception& e) {
837                 m->errorOut(e, "ShhherCommand", "createProcesses");
838                 exit(1);
839         }
840 }
841 //**********************************************************************************************************************
842
843
844
845