]> git.donarmstrong.com Git - mothur.git/blob - getlistcountcommand.cpp
created mothurOut class to handle logfiles
[mothur.git] / getlistcountcommand.cpp
1 /*
2  *  getlistcountcommand.cpp
3  *  Mothur
4  *
5  *  Created by westcott on 10/12/09.
6  *  Copyright 2009 Schloss Lab. All rights reserved.
7  *
8  */
9
10 #include "getlistcountcommand.h"
11
12 //**********************************************************************************************************************
13 GetListCountCommand::GetListCountCommand(string option)  {
14         try {
15                 globaldata = GlobalData::getInstance();
16                 abort = false;
17                 allLines = 1;
18                 labels.clear();
19                                 
20                 //allow user to run help
21                 if(option == "help") { help(); abort = true; }
22                 
23                 else {
24                         //valid paramters for this command
25                         string AlignArray[] =  {"list","label","outputdir","inputdir"};
26                         vector<string> myArray (AlignArray, AlignArray+(sizeof(AlignArray)/sizeof(string)));
27                         
28                         OptionParser parser(option);
29                         map<string, string> parameters = parser.getParameters();
30                         
31                         ValidParameters validParameter;
32                         map<string, string>::iterator it;
33                         
34                         //check to make sure all parameters are valid for command
35                         for (it = parameters.begin(); it != parameters.end(); it++) { 
36                                 if (validParameter.isValidParameter(it->first, myArray, it->second) != true) {  abort = true;  }
37                         }
38                         
39                         string ranRead = globaldata->getListFile();
40                         
41                         //if the user changes the input directory command factory will send this info to us in the output parameter 
42                         string inputDir = validParameter.validFile(parameters, "inputdir", false);              
43                         if (inputDir == "not found"){   inputDir = "";          }
44                         else {
45                                 string path;
46                                 it = parameters.find("list");
47                                 //user has given a template file
48                                 if(it != parameters.end()){ 
49                                         path = hasPath(it->second);
50                                         //if the user has not given a path then, add inputdir. else leave path alone.
51                                         if (path == "") {       parameters["list"] = inputDir + it->second;             }
52                                 }
53                         }
54
55                         //if the user changes the output directory command factory will send this info to us in the output parameter 
56                         outputDir = validParameter.validFile(parameters, "outputdir", false);           if (outputDir == "not found"){  outputDir = "";         }
57                         
58                         //check for required parameters
59                         listfile = validParameter.validFile(parameters, "list", true);
60                         if ((listfile == "not found") && (globaldata->getListFile() == ""))  { m->mothurOut("You must read a listfile before running the get.listcount command.");  m->mothurOutEndLine(); abort = true; }
61                         else if ((listfile == "not found") && (globaldata->getListFile() != "")) { listfile = globaldata->getListFile(); }
62                         else if (listfile == "not open") { abort = true; }      
63                         else { globaldata->setListFile(listfile); }
64                 
65                         //check for optional parameter and set defaults
66                         // ...at some point should added some additional type checking...
67                         
68                         label = validParameter.validFile(parameters, "label", false);                   
69                         if (label == "not found") { label = ""; }
70                         else { 
71                                 if(label != "all") {  splitAtDash(label, labels);  allLines = 0;  }
72                                 else { allLines = 1;  }
73                         }
74                         
75                         //if the user has not specified any labels use the ones from read.otu
76                         if ((label == "") && (ranRead != "")) {  
77                                 allLines = globaldata->allLines; 
78                                 labels = globaldata->labels; 
79                         }
80                 }
81         }
82         catch(exception& e) {
83                 m->errorOut(e, "GetListCountCommand", "GetListCountCommand");
84                 exit(1);
85         }
86 }
87 //**********************************************************************************************************************
88
89 void GetListCountCommand::help(){
90         try {
91                 m->mothurOut("The get.listcount command can only be executed after a successful read.otu command of a listfile or providing a list file using the list parameter.\n");
92                 m->mothurOut("The get.listcount command parameters are list and label.  No parameters are required.\n");
93                 m->mothurOut("The label parameter allows you to select what distance levels you would like a output files created for, and are separated by dashes.\n");
94                 m->mothurOut("The get.listcount command should be in the following format: get.listcount(list=yourlistFile, label=yourLabels).\n");
95                 m->mothurOut("Example get.listcount(list=amazon.fn.list, label=0.10).\n");
96                 m->mothurOut("The default value for label is all lines in your inputfile.\n");
97                 m->mothurOut("The get.listcount command outputs a .otu file for each distance you specify listing the bin number and the names of the sequences in that bin.\n");
98                 m->mothurOut("Note: No spaces between parameter labels (i.e. list), '=' and parameters (i.e.yourListFile).\n\n");
99         }
100         catch(exception& e) {
101                 m->errorOut(e, "GetListCountCommand", "help");
102                 exit(1);
103         }
104 }
105
106 //**********************************************************************************************************************
107
108 GetListCountCommand::~GetListCountCommand(){}
109
110 //**********************************************************************************************************************
111
112 int GetListCountCommand::execute(){
113         try {
114                 if (abort == true) {    return 0;       }
115
116                 globaldata->setFormat("list");
117                 
118                 //read list file
119                 read = new ReadOTUFile(listfile);       
120                 read->read(&*globaldata); 
121                 
122                 input = globaldata->ginput;
123                 list = globaldata->gListVector;
124                 string lastLabel = list->getLabel();
125
126                 //if the users enters label "0.06" and there is no "0.06" in their file use the next lowest label.
127                 set<string> processedLabels;
128                 set<string> userLabels = labels;
129
130                 while((list != NULL) && ((allLines == 1) || (userLabels.size() != 0))) {
131                         
132                         if(allLines == 1 || labels.count(list->getLabel()) == 1){
133                         
134                                 process(list);
135                                                         
136                                 processedLabels.insert(list->getLabel());
137                                 userLabels.erase(list->getLabel());
138                         }
139                         
140                         if ((anyLabelsToProcess(list->getLabel(), userLabels, "") == true) && (processedLabels.count(lastLabel) != 1)) {
141                                 string saveLabel = list->getLabel();
142                                 
143                                 delete list;
144                                 list = input->getListVector(lastLabel);
145                                 
146                                 process(list);
147                                                                                                         
148                                 processedLabels.insert(list->getLabel());
149                                 userLabels.erase(list->getLabel());
150                                 
151                                 //restore real lastlabel to save below
152                                 list->setLabel(saveLabel);
153                         }
154                         
155                         lastLabel = list->getLabel();                   
156                         
157                         delete list;
158                         list = input->getListVector();
159                 }
160                 
161                 
162                 //output error messages about any remaining user labels
163                 set<string>::iterator it;
164                 bool needToRun = false;
165                 for (it = userLabels.begin(); it != userLabels.end(); it++) {  
166                         m->mothurOut("Your file does not include the label " + *it); 
167                         if (processedLabels.count(lastLabel) != 1) {
168                                 m->mothurOut(". I will use " + lastLabel + "."); m->mothurOutEndLine();
169                                 needToRun = true;
170                         }else {
171                                 m->mothurOut(". Please refer to " + lastLabel + ".");  m->mothurOutEndLine();
172                         }
173                 }
174                 
175                 //run last label if you need to
176                 if (needToRun == true)  {
177                         if (list != NULL) {             delete list;    }
178                         list = input->getListVector(lastLabel);
179                                 
180                         process(list);                  
181                         delete list;  
182                 }
183                 
184                 delete read;
185                 globaldata->gListVector = NULL;
186                 
187                 m->mothurOutEndLine();
188                 m->mothurOut("Output File Names: "); m->mothurOutEndLine();
189                 for (int i = 0; i < outputNames.size(); i++) {  m->mothurOut(outputNames[i]); m->mothurOutEndLine();    }
190                 m->mothurOutEndLine();
191                 
192                 return 0;
193         }
194         catch(exception& e) {
195                 m->errorOut(e, "GetListCountCommand", "execute");
196                 exit(1);
197         }
198 }
199
200 //**********************************************************************************************************************
201 //return 1 if error, 0 otherwise
202 void GetListCountCommand::process(ListVector* list) {
203         try {
204                 string binnames, name, sequence;
205                 if (outputDir == "") { outputDir += hasPath(listfile); }
206                 string outputFileName = outputDir + getRootName(getSimpleName(listfile)) + list->getLabel() + ".otu";
207                 openOutputFile(outputFileName, out);
208                 outputNames.push_back(outputFileName);
209                 
210                 m->mothurOut(list->getLabel()); m->mothurOutEndLine();
211                 
212                 //for each bin in the list vector
213                 for (int i = 0; i < list->getNumBins(); i++) {
214                         binnames = list->get(i);
215                         out << i+1 << '\t' << binnames << endl;
216                 }
217                 
218                 out.close();
219         }
220         catch(exception& e) {
221                 m->errorOut(e, "GetListCountCommand", "process");
222                 exit(1);
223         }
224 }
225 //**********************************************************************************************************************
226
227