]> git.donarmstrong.com Git - mothur.git/blob - phylotypecommand.cpp
added pipeline commands which involved change to command factory and command class...
[mothur.git] / phylotypecommand.cpp
1 /*
2  *  phylotypecommand.cpp
3  *  Mothur
4  *
5  *  Created by westcott on 11/20/09.
6  *  Copyright 2009 Schloss Lab. All rights reserved.
7  *
8  */
9
10 #include "phylotypecommand.h"
11 #include "phylotree.h"
12 #include "listvector.hpp"
13 #include "rabundvector.hpp"
14 #include "sabundvector.hpp"
15
16 //**********************************************************************************************************************
17 vector<string> PhylotypeCommand::getValidParameters(){  
18         try {
19                 string Array[] =  {"taxonomy","cutoff","label","name","outputdir","inputdir"};
20                 vector<string> myArray (Array, Array+(sizeof(Array)/sizeof(string)));
21                 return myArray;
22         }
23         catch(exception& e) {
24                 m->errorOut(e, "PhylotypeCommand", "getValidParameters");
25                 exit(1);
26         }
27 }
28 //**********************************************************************************************************************
29 PhylotypeCommand::PhylotypeCommand(){   
30         try {
31                 //initialize outputTypes
32                 vector<string> tempOutNames;
33                 outputTypes["list"] = tempOutNames;
34                 outputTypes["sabund"] = tempOutNames;
35                 outputTypes["rabund"] = tempOutNames;
36         }
37         catch(exception& e) {
38                 m->errorOut(e, "PhylotypeCommand", "PhylotypeCommand");
39                 exit(1);
40         }
41 }
42 //**********************************************************************************************************************
43 vector<string> PhylotypeCommand::getRequiredParameters(){       
44         try {
45                 string Array[] =  {"taxonomy"};
46                 vector<string> myArray (Array, Array+(sizeof(Array)/sizeof(string)));
47                 return myArray;
48         }
49         catch(exception& e) {
50                 m->errorOut(e, "PhylotypeCommand", "getRequiredParameters");
51                 exit(1);
52         }
53 }
54 //**********************************************************************************************************************
55 vector<string> PhylotypeCommand::getRequiredFiles(){    
56         try {
57                 vector<string> myArray;
58                 return myArray;
59         }
60         catch(exception& e) {
61                 m->errorOut(e, "PhylotypeCommand", "getRequiredFiles");
62                 exit(1);
63         }
64 }
65 /**********************************************************************************************************************/
66 PhylotypeCommand::PhylotypeCommand(string option)  {
67         try {
68                 abort = false;
69                 
70                 //allow user to run help
71                 if(option == "help") { help(); abort = true; }
72                 
73                 else {
74                         
75                         //valid paramters for this command
76                         string AlignArray[] =  {"taxonomy","cutoff","label","name","outputdir","inputdir"};
77                         vector<string> myArray (AlignArray, AlignArray+(sizeof(AlignArray)/sizeof(string)));
78                         
79                         OptionParser parser(option);
80                         map<string, string> parameters = parser.getParameters(); 
81                         
82                         ValidParameters validParameter;
83                         map<string, string>::iterator it;
84                         
85                         //check to make sure all parameters are valid for command
86                         for (it = parameters.begin(); it != parameters.end(); it++) { 
87                                 if (validParameter.isValidParameter(it->first, myArray, it->second) != true) {  abort = true;  }
88                         }
89                         
90                         //initialize outputTypes
91                         vector<string> tempOutNames;
92                         outputTypes["list"] = tempOutNames;
93                         outputTypes["sabund"] = tempOutNames;
94                         outputTypes["rabund"] = tempOutNames;
95                         
96                         //if the user changes the input directory command factory will send this info to us in the output parameter 
97                         string inputDir = validParameter.validFile(parameters, "inputdir", false);              
98                         if (inputDir == "not found"){   inputDir = "";          }
99                         else {
100                                 string path;
101                                 it = parameters.find("taxonomy");
102                                 //user has given a template file
103                                 if(it != parameters.end()){ 
104                                         path = m->hasPath(it->second);
105                                         //if the user has not given a path then, add inputdir. else leave path alone.
106                                         if (path == "") {       parameters["taxonomy"] = inputDir + it->second;         }
107                                 }
108                                 
109                                 it = parameters.find("name");
110                                 //user has given a template file
111                                 if(it != parameters.end()){ 
112                                         path = m->hasPath(it->second);
113                                         //if the user has not given a path then, add inputdir. else leave path alone.
114                                         if (path == "") {       parameters["name"] = inputDir + it->second;             }
115                                 }
116                         }
117
118                         taxonomyFileName = validParameter.validFile(parameters, "taxonomy", true);
119                         if (taxonomyFileName == "not found") { 
120                                 m->mothurOut("taxonomy is a required parameter for the phylotype command."); 
121                                 m->mothurOutEndLine();
122                                 abort = true; 
123                         }else if (taxonomyFileName == "not open") { abort = true; }     
124                         
125                         namefile = validParameter.validFile(parameters, "name", true);
126                         if (namefile == "not open") { abort = true; }
127                         else if (namefile == "not found") { namefile = ""; }
128                         else { readNamesFile(); }       
129                         
130                         //if the user changes the output directory command factory will send this info to us in the output parameter 
131                         outputDir = validParameter.validFile(parameters, "outputdir", false);           if (outputDir == "not found"){  
132                                 outputDir = ""; 
133                                 outputDir += m->hasPath(taxonomyFileName); //if user entered a file with a path then preserve it        
134                         }
135                         
136                         string temp = validParameter.validFile(parameters, "cutoff", false);
137                         if (temp == "not found") { temp = "-1"; }
138                         convert(temp, cutoff); 
139                         
140                         label = validParameter.validFile(parameters, "label", false);                   
141                         if (label == "not found") { label = ""; allLines = 1; }
142                         else { 
143                                 if(label != "all") {  m->splitAtDash(label, labels);  allLines = 0;  }
144                                 else { allLines = 1;  }
145                         }
146                         
147                 }
148         }
149         catch(exception& e) {
150                 m->errorOut(e, "PhylotypeCommand", "PhylotypeCommand");
151                 exit(1);
152         }
153 }
154 /**********************************************************************************************************************/
155
156 void PhylotypeCommand::help(){
157         try {
158                 m->mothurOut("The phylotype command reads a taxonomy file and outputs a .list, .rabund and .sabund file. \n");
159                 m->mothurOut("The phylotype command parameter options are taxonomy, cutoff and label. The taxonomy parameter is required.\n");
160                 m->mothurOut("The cutoff parameter allows you to specify the level you want to stop at.  The default is the highest level in your taxonomy file. \n");
161                 m->mothurOut("For example: taxonomy = Bacteria;Bacteroidetes-Chlorobi;Bacteroidetes; - cutoff=2, would truncate the taxonomy to Bacteria;Bacteroidetes-Chlorobi; \n");
162                 m->mothurOut("For the cutoff parameter levels count up from the root of the phylotree. This enables you to look at the grouping down to a specific resolution, say the genus level.\n");
163                 m->mothurOut("The label parameter allows you to specify which level you would like, and are separated by dashes.  The default all levels in your taxonomy file. \n");
164                 m->mothurOut("For the label parameter, levels count down from the root to keep the output similiar to mothur's other commands which report information from finer resolution to coarser resolutions.\n");
165                 m->mothurOut("The phylotype command should be in the following format: \n");
166                 m->mothurOut("phylotype(taxonomy=yourTaxonomyFile, cutoff=yourCutoff, label=yourLabels) \n");
167                 m->mothurOut("Eaxample: phylotype(taxonomy=amazon.taxonomy, cutoff=5, label=1-3-5).\n\n");
168         }
169         catch(exception& e) {
170                 m->errorOut(e, "PhylotypeCommand", "help");
171                 exit(1);
172         }
173 }
174 /**********************************************************************************************************************/
175
176 PhylotypeCommand::~PhylotypeCommand(){}
177
178 /**********************************************************************************************************************/
179
180 int PhylotypeCommand::execute(){
181         try {
182         
183                 if (abort == true) { return 0; }
184                 
185                 //reads in taxonomy file and makes all the taxonomies the same length 
186                 //by appending the last taxon to a given taxonomy as many times as needed to 
187                 //make it as long as the longest taxonomy in the file 
188                 TaxEqualizer* taxEqual = new TaxEqualizer(taxonomyFileName, cutoff, outputDir);
189                 
190                 if (m->control_pressed) { delete taxEqual; return 0; }
191                 
192                 string equalizedTaxFile = taxEqual->getEqualizedTaxFile();
193                 
194                 delete taxEqual;
195                 
196                 //build taxonomy tree from equalized file
197                 PhyloTree* tree = new PhyloTree(equalizedTaxFile);
198                 vector<int> leaves = tree->getGenusNodes();
199                 
200                 //store leaf nodes in current map
201                 for (int i = 0; i < leaves.size(); i++)         {       currentNodes[leaves[i]] = leaves[i];    }
202                 
203                 bool done = false;
204                 if (tree->get(leaves[0]).parent == -1) {  m->mothurOut("Empty Tree"); m->mothurOutEndLine();    done = true;    }
205                 
206                 if (m->control_pressed) { delete tree; return 0; }
207                 
208                 string fileroot = outputDir + m->getRootName(m->getSimpleName(taxonomyFileName));
209                 
210                 ofstream outList;
211                 string outputListFile = fileroot + "tx.list";
212                 m->openOutputFile(outputListFile, outList);
213                 ofstream outSabund;
214                 string outputSabundFile = fileroot + "tx.sabund";
215                 m->openOutputFile(outputSabundFile, outSabund);
216                 ofstream outRabund;
217                 string outputRabundFile = fileroot + "tx.rabund";
218                 m->openOutputFile(outputRabundFile, outRabund);
219                 
220                 outputNames.push_back(outputListFile); outputTypes["list"].push_back(outputListFile);
221                 outputNames.push_back(outputSabundFile); outputTypes["sabund"].push_back(outputSabundFile);
222                 outputNames.push_back(outputRabundFile); outputTypes["rabund"].push_back(outputRabundFile);
223                 
224                 int count = 1;          
225                 //start at leaves of tree and work towards root, processing the labels the user wants
226                 while((!done) && ((allLines == 1) || (labels.size() != 0))) {
227                 
228                         string level = toString(count); 
229                         count++;
230                         
231                         if (m->control_pressed) { 
232                                 outRabund.close(); outSabund.close(); outList.close();
233                                 for (int i = 0; i < outputNames.size(); i++) {  remove(outputNames[i].c_str());  }
234                                 delete tree; return 0; 
235                         }
236                         
237                         //is this a level the user want output for
238                         if(allLines == 1 || labels.count(level) == 1){  
239                                 
240                                 //output level
241                                 m->mothurOut(level); m->mothurOutEndLine();
242                                 
243                                 ListVector list;
244                                 list.setLabel(level);
245                                 //go through nodes and build listvector 
246                                 for (itCurrent = currentNodes.begin(); itCurrent != currentNodes.end(); itCurrent++) {
247                         
248                                         //get parents
249                                         TaxNode node = tree->get(itCurrent->first);
250                                         parentNodes[node.parent] = node.parent;
251                                         
252                                         vector<string> names = node.accessions;
253                                         
254                                         //make the names compatable with listvector
255                                         string name = "";
256                                         for (int i = 0; i < names.size(); i++) {  
257                                                 if (namefile != "") {   
258                                                         map<string, string>::iterator itNames = namemap.find(names[i]);  //make sure this name is in namefile
259                 
260                                                         if (itNames != namemap.end()) {  name += namemap[names[i]] + ",";   } //you found it in namefile
261                                                         else { m->mothurOut(names[i] + " is not in your namefile, please correct."); m->mothurOutEndLine(); exit(1);  }
262                                                         
263                                                 }else{   name += names[i] + ",";        }
264                                         }
265                                         name = name.substr(0, name.length()-1);  //rip off extra ','
266                                         
267                                         //add bin to list vector
268                                         list.push_back(name);
269                                 }       
270                                 
271                                 //print listvector
272                                 list.print(outList);
273                                 //print rabund
274                                 list.getRAbundVector().print(outRabund);
275                                 //print sabund
276                                 list.getSAbundVector().print(outSabund);
277                         
278                                 labels.erase(level);
279                                 
280                         }else {
281                                 
282                                 //just get parents
283                                 for (itCurrent = currentNodes.begin(); itCurrent != currentNodes.end(); itCurrent++) {
284                                         int parent = tree->get(itCurrent->first).parent;
285                                         parentNodes[parent] = parent;
286                                 }
287                         }
288                         
289                         //move up a level
290                         currentNodes = parentNodes;
291                         parentNodes.clear();
292                         
293                         //have we reached the rootnode
294                         if (tree->get(currentNodes.begin()->first).parent == -1)  {  done = true;  }
295                 }
296                         
297                 outList.close();
298                 outSabund.close();
299                 outRabund.close();      
300                 
301                 delete tree;
302                 
303                 if (m->control_pressed) { 
304                         for (int i = 0; i < outputNames.size(); i++) {  remove(outputNames[i].c_str());  }
305                         return 0; 
306                 }
307                 
308                 m->mothurOutEndLine();
309                 m->mothurOut("Output File Names: "); m->mothurOutEndLine();
310                 for (int i = 0; i < outputNames.size(); i++) {  m->mothurOut(outputNames[i]); m->mothurOutEndLine();    }
311                 m->mothurOutEndLine();
312                 
313                 return 0;               
314         }
315
316         catch(exception& e) {
317                 m->errorOut(e, "PhylotypeCommand", "execute");
318                 exit(1);
319         }
320 }
321 /*****************************************************************/
322 int PhylotypeCommand::readNamesFile() {
323         try {
324                                 
325                 ifstream in;
326                 m->openInputFile(namefile, in);
327                 
328                 string first, second;
329                 map<string, string>::iterator itNames;
330                 
331                 while(!in.eof()) {
332                         in >> first >> second; m->gobble(in);
333                         
334                         itNames = namemap.find(first);
335                         if (itNames == namemap.end()) {  
336                                 namemap[first] = second; 
337                         }else {  m->mothurOut(first + " has already been seen in namefile, disregarding names file."); m->mothurOutEndLine(); in.close(); namemap.clear(); namefile = ""; return 1; }                   
338                 }
339                 in.close();
340                 
341                 return 0;
342         }
343         catch(exception& e) {
344                 m->errorOut(e, "PhylotypeCommand", "readNamesFile");
345                 exit(1);
346         }
347 }
348
349 /**********************************************************************************************************************/