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