]> git.donarmstrong.com Git - mothur.git/blob - getrabundcommand.cpp
working on pam
[mothur.git] / getrabundcommand.cpp
1 /*
2  *  getrabundcommand.cpp
3  *  Mothur
4  *
5  *  Created by Sarah Westcott on 6/2/09.
6  *  Copyright 2009 Schloss Lab Umass Amherst. All rights reserved.
7  *
8  */
9
10 #include "getrabundcommand.h"
11
12 //**********************************************************************************************************************
13 vector<string> GetRAbundCommand::setParameters(){       
14         try {
15                 CommandParameter plist("list", "InputTypes", "", "", "LRSS", "LRSS", "none","rabund",false,false, true); parameters.push_back(plist);
16         CommandParameter pcount("count", "InputTypes", "", "", "none", "none", "none","",false,false, false); parameters.push_back(pcount);
17                 CommandParameter psabund("sabund", "InputTypes", "", "", "LRSS", "LRSS", "none","rabund",false,false, true); parameters.push_back(psabund);             
18                 CommandParameter psorted("sorted", "Boolean", "", "T", "", "", "","",false,false); parameters.push_back(psorted);
19                 CommandParameter plabel("label", "String", "", "", "", "", "","",false,false); parameters.push_back(plabel);
20                 CommandParameter pinputdir("inputdir", "String", "", "", "", "", "","",false,false); parameters.push_back(pinputdir);
21                 CommandParameter poutputdir("outputdir", "String", "", "", "", "", "","",false,false); parameters.push_back(poutputdir);
22                 
23                 vector<string> myArray;
24                 for (int i = 0; i < parameters.size(); i++) {   myArray.push_back(parameters[i].name);          }
25                 return myArray;
26         }
27         catch(exception& e) {
28                 m->errorOut(e, "GetRAbundCommand", "setParameters");
29                 exit(1);
30         }
31 }
32 //**********************************************************************************************************************
33 string GetRAbundCommand::getHelpString(){       
34         try {
35                 string helpString = "";
36                 helpString += "The get.rabund command parameters are list, sabund, count, label and sorted.  list or sabund parameters are required, unless you have valid current files.\n";
37         helpString += "The count parameter allows you to provide a count file associated with your list file. If you clustered with a countfile the list file only contains the unique sequences and you will want to add the redundant counts into the rabund file, providing the count file allows you to do so.\n";
38                 helpString += "The label parameter allows you to select what distance levels you would like included in your .rabund file, and are separated by dashes.\n";
39                 helpString += "The sorted parameters allows you to print the rabund results sorted by abundance or not.  The default is sorted.\n";
40                 helpString += "The get.rabund command should be in the following format: get.rabund(label=yourLabels, sorted=yourSorted).\n";
41                 helpString += "Example get.rabund(sorted=F).\n";
42                 helpString += "The default value for label is all labels in your inputfile.\n";
43                 helpString += "The get.rabund command outputs a .rabund file containing the lines you selected.\n";
44                 helpString += "Note: No spaces between parameter labels (i.e. label), '=' and parameters (i.e.yourLabels).\n";
45                 return helpString;
46         }
47         catch(exception& e) {
48                 m->errorOut(e, "GetRAbundCommand", "getHelpString");
49                 exit(1);
50         }
51 }
52 //**********************************************************************************************************************
53 string GetRAbundCommand::getOutputPattern(string type) {
54     try {
55         string pattern = "";
56         
57         if (type == "rabund")      {   pattern = "[filename],rabund";    }
58         else { m->mothurOut("[ERROR]: No definition for type " + type + " output pattern.\n"); m->control_pressed = true;  }
59         
60         return pattern;
61     }
62     catch(exception& e) {
63         m->errorOut(e, "GetRAbundCommand", "getOutputPattern");
64         exit(1);
65     }
66 }
67
68 //**********************************************************************************************************************
69 GetRAbundCommand::GetRAbundCommand(){   
70         try {
71                 abort = true; calledHelp = true; 
72                 setParameters();
73                 vector<string> tempOutNames;
74                 outputTypes["rabund"] = tempOutNames;
75         }
76         catch(exception& e) {
77                 m->errorOut(e, "GetRAbundCommand", "GetRAbundCommand");
78                 exit(1);
79         }
80 }
81 //**********************************************************************************************************************
82 GetRAbundCommand::GetRAbundCommand(string option)  {
83         try {
84                 abort = false; calledHelp = false;   
85                 allLines = 1;
86                 
87                 //allow user to run help
88                 if(option == "help") { help(); abort = true; calledHelp = true; }
89                 else if(option == "citation") { citation(); abort = true; calledHelp = true;}
90                 
91                 else {
92                         vector<string> myArray = setParameters();
93                         
94                         OptionParser parser(option);
95                         map<string,string> parameters = parser.getParameters();
96                         map<string,string>::iterator it;
97                         
98                         ValidParameters validParameter;
99                         
100                         //check to make sure all parameters are valid for command
101                         for (it = parameters.begin(); it != parameters.end(); it++) { 
102                                 if (validParameter.isValidParameter(it->first, myArray, it->second) != true) {  abort = true;  }
103                         }
104                         
105                         //initialize outputTypes
106                         vector<string> tempOutNames;
107                         outputTypes["rabund"] = tempOutNames;
108                         
109                         //if the user changes the input directory command factory will send this info to us in the output parameter 
110                         string inputDir = validParameter.validFile(parameters, "inputdir", false);              
111                         if (inputDir == "not found"){   inputDir = "";          }
112                         else {
113                                 string path;
114                                 it = parameters.find("list");
115                                 //user has given a template file
116                                 if(it != parameters.end()){ 
117                                         path = m->hasPath(it->second);
118                                         //if the user has not given a path then, add inputdir. else leave path alone.
119                                         if (path == "") {       parameters["list"] = inputDir + it->second;             }
120                                 }
121                                 
122                                 it = parameters.find("sabund");
123                                 //user has given a template file
124                                 if(it != parameters.end()){ 
125                                         path = m->hasPath(it->second);
126                                         //if the user has not given a path then, add inputdir. else leave path alone.
127                                         if (path == "") {       parameters["sabund"] = inputDir + it->second;           }
128                                 }
129                 
130                 it = parameters.find("count");
131                                 //user has given a template file
132                                 if(it != parameters.end()){
133                                         path = m->hasPath(it->second);
134                                         //if the user has not given a path then, add inputdir. else leave path alone.
135                                         if (path == "") {       parameters["count"] = inputDir + it->second;            }
136                                 }
137                         }
138                         
139                         
140                         //check for required parameters
141                         listfile = validParameter.validFile(parameters, "list", true);
142                         if (listfile == "not open") { listfile = ""; abort = true; }
143                         else if (listfile == "not found") { listfile = ""; }
144                         else {  format = "list"; inputfile = listfile; m->setListFile(listfile); }
145                         
146                         sabundfile = validParameter.validFile(parameters, "sabund", true);
147                         if (sabundfile == "not open") { sabundfile = ""; abort = true; }        
148                         else if (sabundfile == "not found") { sabundfile = ""; }
149                         else {  format = "sabund"; inputfile = sabundfile; m->setSabundFile(sabundfile); }
150             
151             countfile = validParameter.validFile(parameters, "count", true);
152                         if (countfile == "not open") { countfile = ""; abort = true; }
153                         else if (countfile == "not found") { countfile = ""; }
154                         else {  m->setCountTableFile(countfile); }
155                         
156                         
157                         //check for optional parameter and set defaults
158                         // ...at some point should added some additional type checking...
159                         string temp;
160                         temp = validParameter.validFile(parameters, "sorted", false);                   if (temp == "not found") { temp = "T"; }
161                         sorted = m->isTrue(temp);
162                         
163                         label = validParameter.validFile(parameters, "label", false);                   
164                         if (label == "not found") { label = ""; }
165                         else { 
166                                 if(label != "all") {  m->splitAtDash(label, labels);  allLines = 0;  }
167                                 else { allLines = 1;  }
168                         }
169                         
170                         if ((listfile == "") && (sabundfile == "")) { 
171                                 //is there are current file available for any of these?
172                                 //give priority to shared, then list, then rabund, then sabund
173                                 //if there is a current shared file, use it
174                                 listfile = m->getListFile(); 
175                                 if (listfile != "") { inputfile = listfile; format = "list"; m->mothurOut("Using " + listfile + " as input file for the list parameter."); m->mothurOutEndLine(); }
176                                 else { 
177                                         sabundfile = m->getSabundFile(); 
178                                         if (sabundfile != "") { inputfile = sabundfile; format = "sabund"; m->mothurOut("Using " + sabundfile + " as input file for the sabund parameter."); m->mothurOutEndLine(); }
179                                         else { 
180                                                 m->mothurOut("No valid current files. You must provide a list or sabund file."); m->mothurOutEndLine(); 
181                                                 abort = true;
182                                         }
183                                 }
184                         }
185                         
186                         if ((countfile != "") && (listfile == "")) { m->mothurOut("[ERROR]: You can only use the count file with a list file, aborting.\n"); abort = true; }
187             
188                         //if the user changes the output directory command factory will send this info to us in the output parameter 
189                         outputDir = validParameter.validFile(parameters, "outputdir", false);           if (outputDir == "not found"){  outputDir = m->hasPath(inputfile);      }                       
190                         
191                 }
192                         
193
194         }
195         catch(exception& e) {
196                 m->errorOut(e, "GetRAbundCommand", "GetRAbundCommand");
197                 exit(1);
198         }                       
199 }
200 //**********************************************************************************************************************
201
202 int GetRAbundCommand::execute(){
203         try {
204         
205                 if (abort == true) { if (calledHelp) { return 0; }  return 2;   }
206                 
207         map<string, string> variables; 
208         variables["[filename]"] = outputDir + m->getRootName(m->getSimpleName(inputfile));
209                 filename = getOutputFileName("rabund", variables);
210                 m->openOutputFile(filename, out);
211                 
212         if (countfile != "") {
213             processList(out);
214         }else {
215             InputData input(inputfile, format);
216             RAbundVector* rabund = input.getRAbundVector();
217             string lastLabel = rabund->getLabel();
218             
219             //if the users enters label "0.06" and there is no "0.06" in their file use the next lowest label.
220             set<string> processedLabels;
221             set<string> userLabels = labels;
222             
223             if (m->control_pressed) {  outputTypes.clear();  out.close(); m->mothurRemove(filename); delete rabund;  return 0; }
224             
225             while((rabund != NULL) && ((allLines == 1) || (userLabels.size() != 0))) {
226                 
227                 if(allLines == 1 || labels.count(rabund->getLabel()) == 1){
228                                         m->mothurOut(rabund->getLabel()); m->mothurOutEndLine();
229                                         
230                                         if (m->control_pressed) {   outputTypes.clear(); out.close(); m->mothurRemove(filename);   delete rabund;  return 0;  }
231                                         
232                                         if(sorted)      {   rabund->print(out);                         }
233                                         else            {       rabund->nonSortedPrint(out);    }
234                     
235                                         processedLabels.insert(rabund->getLabel());
236                                         userLabels.erase(rabund->getLabel());
237                 }
238                 
239                 if ((m->anyLabelsToProcess(rabund->getLabel(), userLabels, "") == true) && (processedLabels.count(lastLabel) != 1)) {
240                                         string saveLabel = rabund->getLabel();
241                                         
242                                         delete rabund;
243                                         rabund = input.getRAbundVector(lastLabel);
244                                         
245                                         m->mothurOut(rabund->getLabel()); m->mothurOutEndLine();
246                                         
247                                         if (m->control_pressed) {   outputTypes.clear(); out.close(); m->mothurRemove(filename);  delete rabund;  return 0;  }
248                                         
249                                         if(sorted)      {   rabund->print(out);                         }
250                                         else            {       rabund->nonSortedPrint(out);    }
251                     
252                                         processedLabels.insert(rabund->getLabel());
253                                         userLabels.erase(rabund->getLabel());
254                                         
255                                         //restore real lastlabel to save below
256                                         rabund->setLabel(saveLabel);
257                 }
258                 
259                 lastLabel = rabund->getLabel();
260                 
261                 delete rabund;
262                 rabund = input.getRAbundVector();
263             }
264             
265             //output error messages about any remaining user labels
266             set<string>::iterator it;
267             bool needToRun = false;
268             for (it = userLabels.begin(); it != userLabels.end(); it++) {
269                 m->mothurOut("Your file does not include the label " + *it);
270                 if (processedLabels.count(lastLabel) != 1) {
271                     m->mothurOut(". I will use " + lastLabel + "."); m->mothurOutEndLine();
272                     needToRun = true;
273                 }else {
274                     m->mothurOut(". Please refer to " + lastLabel + "."); m->mothurOutEndLine();
275                 }
276             }
277             
278             //run last label if you need to
279             if (needToRun == true)  {
280                 if (rabund != NULL) {   delete rabund;  }
281                 rabund = input.getRAbundVector(lastLabel);
282                 
283                 m->mothurOut(rabund->getLabel()); m->mothurOutEndLine();
284                 
285                 if (m->control_pressed) {  outputTypes.clear(); out.close(); m->mothurRemove(filename);   delete rabund;  return 0; }
286                 
287                 if(sorted)      {   rabund->print(out);                         }
288                 else            {       rabund->nonSortedPrint(out);    }
289                 
290                 delete rabund;
291             }
292                 }
293         
294         if (m->control_pressed) {  outputTypes.clear();  out.close(); m->mothurRemove(filename);  return 0; }
295         
296                 m->mothurOutEndLine();
297                 m->mothurOut("Output File Names: "); m->mothurOutEndLine();
298                 m->mothurOut(filename); m->mothurOutEndLine();  outputNames.push_back(filename); outputTypes["rabund"].push_back(filename);
299                 m->mothurOutEndLine();
300                 
301                 out.close(); 
302                                 
303                 //set rabund file as new current rabundfile
304                 string current = "";
305                 itTypes = outputTypes.find("rabund");
306                 if (itTypes != outputTypes.end()) {
307                         if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setRabundFile(current); }
308                 }
309                 
310                 return 0;               
311         }
312
313         catch(exception& e) {
314                 m->errorOut(e, "GetRAbundCommand", "execute");
315                 exit(1);
316         }
317 }
318 //**********************************************************************************************************************
319 int GetRAbundCommand::processList(ofstream& out){
320         try {
321         CountTable ct;
322         ct.readTable(countfile, false, false);
323         
324         InputData input(inputfile, format);
325         ListVector* list = input.getListVector();
326         string lastLabel = list->getLabel();
327         
328         //if the users enters label "0.06" and there is no "0.06" in their file use the next lowest label.
329         set<string> processedLabels;
330         set<string> userLabels = labels;
331         
332         if (m->control_pressed) {  delete list;  return 0; }
333         
334         while((list != NULL) && ((allLines == 1) || (userLabels.size() != 0))) {
335             
336             if(allLines == 1 || labels.count(list->getLabel()) == 1){
337                 m->mothurOut(list->getLabel()); m->mothurOutEndLine();
338                 
339                 if (m->control_pressed) {   delete list;  return 0;  }
340                 
341                 RAbundVector* rabund = new RAbundVector();
342                 createRabund(ct, list, rabund);
343                 
344                 if(sorted)      {   rabund->print(out);                         }
345                 else            {       rabund->nonSortedPrint(out);    }
346                 
347                 delete rabund;
348                 processedLabels.insert(list->getLabel());
349                 userLabels.erase(list->getLabel());
350             }
351             
352             if ((m->anyLabelsToProcess(list->getLabel(), userLabels, "") == true) && (processedLabels.count(lastLabel) != 1)) {
353                 string saveLabel = list->getLabel();
354                 
355                 delete list;
356                 list = input.getListVector(lastLabel);
357                 
358                 m->mothurOut(list->getLabel()); m->mothurOutEndLine();
359                 
360                 if (m->control_pressed) {    delete list;  return 0;  }
361                 
362                 RAbundVector* rabund = new RAbundVector();
363                 createRabund(ct, list, rabund);
364                 
365                 if(sorted)      {   rabund->print(out);                         }
366                 else            {       rabund->nonSortedPrint(out);    }
367                 
368                 delete rabund;
369                 processedLabels.insert(list->getLabel());
370                 userLabels.erase(list->getLabel());
371                 
372                 //restore real lastlabel to save below
373                 list->setLabel(saveLabel);
374             }
375             
376             lastLabel = list->getLabel();
377             
378             delete list;
379             list = input.getListVector();
380         }
381         
382         //output error messages about any remaining user labels
383         set<string>::iterator it;
384         bool needToRun = false;
385         for (it = userLabels.begin(); it != userLabels.end(); it++) {
386             m->mothurOut("Your file does not include the label " + *it);
387             if (processedLabels.count(lastLabel) != 1) {
388                 m->mothurOut(". I will use " + lastLabel + "."); m->mothurOutEndLine();
389                 needToRun = true;
390             }else {
391                 m->mothurOut(". Please refer to " + lastLabel + "."); m->mothurOutEndLine();
392             }
393         }
394         
395         //run last label if you need to
396         if (needToRun == true)  {
397             if (list != NULL) { delete list;    }
398             list = input.getListVector(lastLabel);
399             
400             m->mothurOut(list->getLabel()); m->mothurOutEndLine();
401             
402             if (m->control_pressed) {   delete list;  return 0; }
403             
404             RAbundVector* rabund = new RAbundVector();
405             createRabund(ct, list, rabund);
406             
407             if(sorted)  {   rabund->print(out);                         }
408             else                {       rabund->nonSortedPrint(out);    }
409             
410             delete rabund;
411             delete list;
412         }
413
414         return 0;
415     }
416         catch(exception& e) {
417                 m->errorOut(e, "GetRAbundCommand", "processList");
418                 exit(1);
419         }
420 }
421 //**********************************************************************************************************************
422
423 int GetRAbundCommand::createRabund(CountTable& ct, ListVector*& list, RAbundVector*& rabund){
424     try {
425         
426         rabund->setLabel(list->getLabel());
427         for(int i = 0; i < list->getNumBins(); i++) {
428             if (m->control_pressed) { return 0; }
429             vector<string> binNames;
430             string bin = list->get(i);
431             m->splitAtComma(bin, binNames);
432             int total = 0;
433             for (int j = 0; j < binNames.size(); j++) {
434                 total += ct.getNumSeqs(binNames[j]);
435             }
436             rabund->push_back(total);
437         }
438         
439         return 0;
440     }
441     catch(exception& e) {
442                 m->errorOut(e, "GetRAbundCommand", "createRabund");
443                 exit(1);
444         }
445     
446 }
447
448 //**********************************************************************************************************************
449
450