]> git.donarmstrong.com Git - mothur.git/blob - parselistscommand.cpp
created mothurOut class to handle logfiles
[mothur.git] / parselistscommand.cpp
1 /*
2  *  parselistcommand.cpp
3  *  Mothur
4  *
5  *  Created by westcott on 2/24/10.
6  *  Copyright 2010 Schloss Lab. All rights reserved.
7  *
8  */
9
10 #include "parselistscommand.h"
11
12 //**********************************************************************************************************************
13 ParseListCommand::ParseListCommand(string option)  {
14         try {
15                 abort = false;
16                 allLines = 1;
17                         
18                 //allow user to run help
19                 if(option == "help") { help(); abort = true; }
20                 
21                 else {
22                         //valid paramters for this command
23                         string Array[] =  {"list","group", "label", "outputdir","inputdir"};
24                         vector<string> myArray (Array, Array+(sizeof(Array)/sizeof(string)));
25                         
26                         OptionParser parser(option);
27                         map<string, string> parameters = parser.getParameters();
28                         
29                         ValidParameters validParameter;
30                         map<string, string>::iterator it;
31                 
32                         //check to make sure all parameters are valid for command
33                         for (it = parameters.begin(); it != parameters.end(); it++) { 
34                                 if (validParameter.isValidParameter(it->first, myArray, it->second) != true) {  abort = true;  }
35                         }
36                                                 
37                         //if the user changes the input directory command factory will send this info to us in the output parameter 
38                         string inputDir = validParameter.validFile(parameters, "inputdir", false);              
39                         if (inputDir == "not found"){   inputDir = "";          }
40                         else {
41                                 string path;
42                                 it = parameters.find("list");
43                                 //user has given a template file
44                                 if(it != parameters.end()){ 
45                                         path = hasPath(it->second);
46                                         //if the user has not given a path then, add inputdir. else leave path alone.
47                                         if (path == "") {       parameters["list"] = inputDir + it->second;             }
48                                 }
49                                 
50                                 it = parameters.find("group");
51                                 //user has given a template file
52                                 if(it != parameters.end()){ 
53                                         path = hasPath(it->second);
54                                         //if the user has not given a path then, add inputdir. else leave path alone.
55                                         if (path == "") {       parameters["group"] = inputDir + it->second;            }
56                                 }
57                         }
58
59                         
60                         //if the user changes the output directory command factory will send this info to us in the output parameter 
61                         outputDir = validParameter.validFile(parameters, "outputdir", false);           if (outputDir == "not found"){  outputDir = ""; }
62
63                         //check for required parameters
64                         listfile = validParameter.validFile(parameters, "list", true);
65                         if (listfile == "not open") { abort = true; }
66                         else if (listfile == "not found") { listfile = ""; }    
67                         
68                         groupfile = validParameter.validFile(parameters, "group", true);
69                         if (groupfile == "not open") { abort = true; }  
70                         else if (groupfile == "not found") { groupfile = ""; }
71                         else {  
72                                 groupMap = new GroupMap(groupfile);
73                                 
74                                 int error = groupMap->readMap();
75                                 if (error == 1) { abort = true; }
76                         }
77                         
78                         //do you have all files needed
79                         if ((listfile == "") || (groupfile == "")) { m->mothurOut("You must enter both a listfile and groupfile for the parse.list command. "); m->mothurOutEndLine(); abort = true;  }
80                         
81                         //check for optional parameter and set defaults
82                         // ...at some point should added some additional type checking...
83                         label = validParameter.validFile(parameters, "label", false);                   
84                         if (label == "not found") { label = "";  allLines = 1; }
85                         else { 
86                                 if(label != "all") {  splitAtDash(label, labels);  allLines = 0;  }
87                                 else { allLines = 1;  }
88                         }
89                 }
90
91         }
92         catch(exception& e) {
93                 m->errorOut(e, "ParseListCommand", "ParseListCommand");
94                 exit(1);
95         }
96 }
97 //**********************************************************************************************************************
98 void ParseListCommand::help(){
99         try {
100                 m->mothurOut("The parse.list command reads a list and group file and generates a list file for each group in the groupfile \n");
101                 m->mothurOut("The parse.list command parameters are list, group and label.\n");
102                 m->mothurOut("The list and group parameters are required.\n");
103                 m->mothurOut("The label parameter is used to read specific labels in your input you want to use.\n");
104                 m->mothurOut("The parse.list command should be used in the following format: parse.list(list=yourListFile, group=yourGroupFile, label=yourLabels).\n");
105                 m->mothurOut("Example: parse.list(list=abrecovery.fn.list, group=abrecovery.groups, label=0.03).\n");
106                 m->mothurOut("Note: No spaces between parameter labels (i.e. list), '=' and parameters (i.e.yourListfile).\n\n");
107
108         }
109         catch(exception& e) {
110                 m->errorOut(e, "ParseListCommand", "help");
111                 exit(1);
112         }
113 }
114 //**********************************************************************************************************************
115 ParseListCommand::~ParseListCommand(){}
116 //**********************************************************************************************************************
117 int ParseListCommand::execute(){
118         try {
119         
120                 if (abort == true) {    return 0;       }
121                 
122                 //set fileroot
123                 string fileroot = outputDir + getRootName(getSimpleName(listfile));
124                 vector<string> outputNames;
125                 
126                 //fill filehandles with neccessary ofstreams
127                 int i;
128                 ofstream* temp;
129                 for (i=0; i<groupMap->namesOfGroups.size(); i++) {
130                         temp = new ofstream;
131                         filehandles[groupMap->namesOfGroups[i]] = temp;
132                         
133                         string filename = fileroot +  groupMap->namesOfGroups[i] + ".list";
134                         outputNames.push_back(filename);
135                         openOutputFile(filename, *temp);
136                 }
137                 
138                 //if the users enters label "0.06" and there is no "0.06" in their file use the next lowest label.
139                 set<string> processedLabels;
140                 set<string> userLabels = labels;        
141         
142                 input = new InputData(listfile, "list");
143                 list = input->getListVector();
144                 string lastLabel = list->getLabel();
145                 
146                 while((list != NULL) && ((allLines == 1) || (userLabels.size() != 0))) {
147                         
148                         if(allLines == 1 || labels.count(list->getLabel()) == 1){
149                                         
150                                         parse(list);
151                                         m->mothurOut(list->getLabel()); m->mothurOutEndLine();
152                                         
153                                         processedLabels.insert(list->getLabel());
154                                         userLabels.erase(list->getLabel());
155                         }
156                         
157                         if ((anyLabelsToProcess(list->getLabel(), userLabels, "") == true) && (processedLabels.count(lastLabel) != 1)) {
158                                         string saveLabel = list->getLabel();
159                                         
160                                         delete list;
161                                         list = input->getListVector(lastLabel); //get new list vector to process
162                                         
163                                         parse(list);
164                                         m->mothurOut(list->getLabel()); m->mothurOutEndLine();
165                                         
166                                         processedLabels.insert(list->getLabel());
167                                         userLabels.erase(list->getLabel());
168                                         
169                                         //restore real lastlabel to save below
170                                         list->setLabel(saveLabel);
171                         }
172                         
173                 
174                         lastLabel = list->getLabel();
175                                 
176                         delete list;
177                         list = input->getListVector(); //get new list vector to process
178                 }
179                 
180                 //output error messages about any remaining user labels
181                 set<string>::iterator it;
182                 bool needToRun = false;
183                 for (it = userLabels.begin(); it != userLabels.end(); it++) {  
184                         m->mothurOut("Your file does not include the label " + *it); 
185                         if (processedLabels.count(lastLabel) != 1) {
186                                 m->mothurOut(". I will use " + lastLabel + "."); m->mothurOutEndLine();
187                                 needToRun = true;
188                         }else {
189                                 m->mothurOut(". Please refer to " + lastLabel + "."); m->mothurOutEndLine();
190                         }
191
192                 }
193                 
194                 //run last label if you need to
195                 if (needToRun == true)  {
196                         if (list != NULL) {     delete list;    }
197                         list = input->getListVector(lastLabel); //get new list vector to process
198                         
199                         parse(list);            
200                         m->mothurOut(list->getLabel()); m->mothurOutEndLine();
201                         
202                         delete list;
203                 }
204                 
205                 for (it3 = filehandles.begin(); it3 != filehandles.end(); it3++) {
206                         (*(filehandles[it3->first])).close();
207                         delete it3->second;
208                 }
209                 
210                 delete groupMap;
211                 
212                 m->mothurOutEndLine();
213                 m->mothurOut("Output File Names: "); m->mothurOutEndLine();
214                 for (int i = 0; i < outputNames.size(); i++) {  m->mothurOut(outputNames[i]); m->mothurOutEndLine();    }
215                 m->mothurOutEndLine();
216                 
217                 return 0;
218         }
219         catch(exception& e) {
220                 m->errorOut(e, "ParseListCommand", "execute");
221                 exit(1);
222         }
223 }
224 /**********************************************************************************************************************/
225 void ParseListCommand::parse(ListVector* thisList) {
226         try {
227         
228                 map<string, string> groupVector;
229                 map<string, string>::iterator itGroup;
230                 map<string, int> groupNumBins;
231                 
232                 //print label
233                 for (it3 = filehandles.begin(); it3 != filehandles.end(); it3++) {
234                         groupNumBins[it3->first] = 0;
235                         groupVector[it3->first] = "";
236                 }
237
238                 
239                 for (int i = 0; i < thisList->getNumBins(); i++) {
240                         
241                         map<string, string> groupBins;
242                         string bin = list->get(i); 
243                         
244                         vector<string> names;
245                         splitAtComma(bin, names);  //parses bin into individual sequence names
246                         
247                         //parse bin into list of sequences in each group
248                         for (int j = 0; j < names.size(); j++) {
249                                 string group = groupMap->getGroup(names[j]);
250                                 
251                                 if (group == "not found") { m->mothurOut(names[j] + " is not in your groupfile. please correct."); m->mothurOutEndLine(); exit(1); }
252                                 
253                                 itGroup = groupBins.find(group);
254                                 if(itGroup == groupBins.end()) {
255                                         groupBins[group] = names[j];  //add first name
256                                         groupNumBins[group]++;
257                                 }else{ //add another name
258                                         groupBins[group] = groupBins[group] + "," + names[j];
259                                 }
260                         }
261                         
262                         //print parsed bin info to files
263                         for (itGroup = groupBins.begin(); itGroup != groupBins.end(); itGroup++) {
264                                 groupVector[itGroup->first] +=  itGroup->second + '\t'; 
265                         }
266                 
267                 }
268                 
269                 //end list vector
270                 for (it3 = filehandles.begin(); it3 != filehandles.end(); it3++) {
271                         (*(filehandles[it3->first])) << thisList->getLabel() << '\t' << groupNumBins[it3->first] << '\t' << groupVector[it3->first] << endl;  // label numBins  listvector for that group
272                 }
273
274
275         }
276         catch(exception& e) {
277                 m->errorOut(e, "ParseListCommand", "parse");
278                 exit(1);
279         }
280 }
281
282 /**********************************************************************************************************************/
283
284