]> git.donarmstrong.com Git - mothur.git/blob - getlistcountcommand.cpp
moved utilities out of mothur.h and into mothurOut class.
[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","sort","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 = m->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                         sort = validParameter.validFile(parameters, "sort", false);       if (sort == "not found") { sort = "otu"; }
68                         if ((sort != "otu") && (sort != "name")) { m->mothurOut( sort + " is not a valid sort option. Options are otu and name. I will use otu."); m->mothurOutEndLine(); sort = "otu"; }
69                         
70                         label = validParameter.validFile(parameters, "label", false);                   
71                         if (label == "not found") { label = ""; }
72                         else { 
73                                 if(label != "all") {  m->splitAtDash(label, labels);  allLines = 0;  }
74                                 else { allLines = 1;  }
75                         }
76                         
77                         //if the user has not specified any labels use the ones from read.otu
78                         if ((label == "") && (ranRead != "")) {  
79                                 allLines = globaldata->allLines; 
80                                 labels = globaldata->labels; 
81                         }
82                 }
83         }
84         catch(exception& e) {
85                 m->errorOut(e, "GetListCountCommand", "GetListCountCommand");
86                 exit(1);
87         }
88 }
89 //**********************************************************************************************************************
90
91 void GetListCountCommand::help(){
92         try {
93                 m->mothurOut("The get.otulist command can only be executed after a successful read.otu command of a listfile or providing a list file using the list parameter.\n");
94                 m->mothurOut("The get.otulist command parameters are list, sort and label.  No parameters are required.\n");
95                 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");
96                 m->mothurOut("The sort parameter allows you to select how you want the output displayed. Options are otu and name.\n");
97                 m->mothurOut("If otu is selected the output will be otu number followed by the list of names in that otu.\n");
98                 m->mothurOut("If name is selected the output will be a sequence name followed by its otu number.\n");
99                 m->mothurOut("The get.otulist command should be in the following format: get.otulist(list=yourlistFile, label=yourLabels).\n");
100                 m->mothurOut("Example get.otulist(list=amazon.fn.list, label=0.10).\n");
101                 m->mothurOut("The default value for label is all lines in your inputfile.\n");
102                 m->mothurOut("The get.otulist command outputs a .otu file for each distance you specify listing the bin number and the names of the sequences in that bin.\n");
103                 m->mothurOut("Note: No spaces between parameter labels (i.e. list), '=' and parameters (i.e.yourListFile).\n\n");
104         }
105         catch(exception& e) {
106                 m->errorOut(e, "GetListCountCommand", "help");
107                 exit(1);
108         }
109 }
110
111 //**********************************************************************************************************************
112
113 GetListCountCommand::~GetListCountCommand(){}
114
115 //**********************************************************************************************************************
116
117 int GetListCountCommand::execute(){
118         try {
119                 if (abort == true) {    return 0;       }
120
121                 globaldata->setFormat("list");
122                 
123                 //read list file
124                 read = new ReadOTUFile(listfile);       
125                 read->read(&*globaldata); 
126                 
127                 input = globaldata->ginput;
128                 list = globaldata->gListVector;
129                 string lastLabel = list->getLabel();
130
131                 //if the users enters label "0.06" and there is no "0.06" in their file use the next lowest label.
132                 set<string> processedLabels;
133                 set<string> userLabels = labels;
134                 
135                 if (m->control_pressed) { 
136                         delete read;
137                         delete input;
138                         delete list;
139                         globaldata->gListVector = NULL;  
140                         for (int i = 0; i < outputNames.size(); i++) {  remove(outputNames[i].c_str()); }
141                         return 0; 
142                 }
143                 
144                 while((list != NULL) && ((allLines == 1) || (userLabels.size() != 0))) {
145                         
146                         if(allLines == 1 || labels.count(list->getLabel()) == 1){
147                         
148                                 process(list);
149                                 
150                                 if (m->control_pressed) { 
151                                         delete read;
152                                         delete input;
153                                         delete list;
154                                         globaldata->gListVector = NULL;  
155                                         for (int i = 0; i < outputNames.size(); i++) {  remove(outputNames[i].c_str()); }
156                                         return 0; 
157                                 }
158                                                         
159                                 processedLabels.insert(list->getLabel());
160                                 userLabels.erase(list->getLabel());
161                         }
162                         
163                         if ((m->anyLabelsToProcess(list->getLabel(), userLabels, "") == true) && (processedLabels.count(lastLabel) != 1)) {
164                                 string saveLabel = list->getLabel();
165                                 
166                                 delete list;
167                                 list = input->getListVector(lastLabel);
168                                 
169                                 process(list);
170                                 
171                                 if (m->control_pressed) { 
172                                         delete read;
173                                         delete input;
174                                         delete list;
175                                         globaldata->gListVector = NULL;  
176                                         for (int i = 0; i < outputNames.size(); i++) {  remove(outputNames[i].c_str()); }
177                                         return 0; 
178                                 }
179                                                                                                         
180                                 processedLabels.insert(list->getLabel());
181                                 userLabels.erase(list->getLabel());
182                                 
183                                 //restore real lastlabel to save below
184                                 list->setLabel(saveLabel);
185                         }
186                         
187                         lastLabel = list->getLabel();                   
188                         
189                         delete list;
190                         list = input->getListVector();
191                 }
192                 
193                 
194                 //output error messages about any remaining user labels
195                 set<string>::iterator it;
196                 bool needToRun = false;
197                 for (it = userLabels.begin(); it != userLabels.end(); it++) {  
198                         m->mothurOut("Your file does not include the label " + *it); 
199                         if (processedLabels.count(lastLabel) != 1) {
200                                 m->mothurOut(". I will use " + lastLabel + "."); m->mothurOutEndLine();
201                                 needToRun = true;
202                         }else {
203                                 m->mothurOut(". Please refer to " + lastLabel + ".");  m->mothurOutEndLine();
204                         }
205                 }
206                 
207                 //run last label if you need to
208                 if (needToRun == true)  {
209                         if (list != NULL) {             delete list;    }
210                         list = input->getListVector(lastLabel);
211                                 
212                         process(list);  
213                         
214                         if (m->control_pressed) { 
215                                         delete read;
216                                         delete input;
217                                         delete list;
218                                         globaldata->gListVector = NULL;  
219                                         for (int i = 0; i < outputNames.size(); i++) {  remove(outputNames[i].c_str()); }
220                                         return 0; 
221                         }
222                         
223                         delete list;  
224                 }
225                 
226                 delete read;
227                 delete input;
228                 globaldata->gListVector = NULL;
229                 
230                 m->mothurOutEndLine();
231                 m->mothurOut("Output File Names: "); m->mothurOutEndLine();
232                 for (int i = 0; i < outputNames.size(); i++) {  m->mothurOut(outputNames[i]); m->mothurOutEndLine();    }
233                 m->mothurOutEndLine();
234                 
235                 return 0;
236         }
237         catch(exception& e) {
238                 m->errorOut(e, "GetListCountCommand", "execute");
239                 exit(1);
240         }
241 }
242
243 //**********************************************************************************************************************
244 //return 1 if error, 0 otherwise
245 void GetListCountCommand::process(ListVector* list) {
246         try {
247                 string binnames;
248                 if (outputDir == "") { outputDir += m->hasPath(listfile); }
249                 string outputFileName = outputDir + m->getRootName(m->getSimpleName(listfile)) + list->getLabel() + ".otu";
250                 m->openOutputFile(outputFileName, out);
251                 outputNames.push_back(outputFileName);
252                 
253                 m->mothurOut(list->getLabel()); m->mothurOutEndLine();
254                 
255                 //for each bin in the list vector
256                 for (int i = 0; i < list->getNumBins(); i++) {
257                         if (m->control_pressed) { break; }
258                         
259                         binnames = list->get(i);
260                         
261                         if (sort == "otu") {
262                                 out << i+1 << '\t' << binnames << endl;
263                         }else{ //sort = name
264                                 vector<string> names;
265                                 m->splitAtComma(binnames, names);
266                                 
267                                 for (int j = 0; j < names.size(); j++) {
268                                         out << names[j] << '\t' << i+1 << endl;
269                                 }
270                         }
271                 }
272                 
273                 out.close();
274         }
275         catch(exception& e) {
276                 m->errorOut(e, "GetListCountCommand", "process");
277                 exit(1);
278         }
279 }
280 //**********************************************************************************************************************
281
282