]> git.donarmstrong.com Git - mothur.git/blob - parselistscommand.cpp
ce014fcaf439d2d838cd630cbb5b012f2c8b8efe
[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 == "")) { mothurOut("You must enter both a listfile and groupfile for the parse.list command. "); 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                 errorOut(e, "ParseListCommand", "ParseListCommand");
94                 exit(1);
95         }
96 }
97 //**********************************************************************************************************************
98 void ParseListCommand::help(){
99         try {
100                 mothurOut("The parse.list command reads a list and group file and generates a list file for each group in the groupfile \n");
101                 mothurOut("The parse.list command parameters are list, group and label.\n");
102                 mothurOut("The list and group parameters are required.\n");
103                 mothurOut("The label parameter is used to read specific labels in your input you want to use.\n");
104                 mothurOut("The parse.list command should be used in the following format: parse.list(list=yourListFile, group=yourGroupFile, label=yourLabels).\n");
105                 mothurOut("Example: parse.list(list=abrecovery.fn.list, group=abrecovery.groups, label=0.03).\n");
106                 mothurOut("Note: No spaces between parameter labels (i.e. list), '=' and parameters (i.e.yourListfile).\n\n");
107
108         }
109         catch(exception& e) {
110                 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                 
125                 //fill filehandles with neccessary ofstreams
126                 int i;
127                 ofstream* temp;
128                 for (i=0; i<groupMap->namesOfGroups.size(); i++) {
129                         temp = new ofstream;
130                         filehandles[groupMap->namesOfGroups[i]] = temp;
131                         
132                         string filename = fileroot +  groupMap->namesOfGroups[i] + ".list";
133                         openOutputFile(filename, *temp);
134                 }
135                 
136                 //if the users enters label "0.06" and there is no "0.06" in their file use the next lowest label.
137                 set<string> processedLabels;
138                 set<string> userLabels = labels;        
139         
140                 input = new InputData(listfile, "list");
141                 list = input->getListVector();
142                 string lastLabel = list->getLabel();
143                 
144                 while((list != NULL) && ((allLines == 1) || (userLabels.size() != 0))) {
145                         
146                         if(allLines == 1 || labels.count(list->getLabel()) == 1){
147                                         
148                                         parse(list);
149                                         mothurOut(list->getLabel()); mothurOutEndLine();
150                                         
151                                         processedLabels.insert(list->getLabel());
152                                         userLabels.erase(list->getLabel());
153                         }
154                         
155                         if ((anyLabelsToProcess(list->getLabel(), userLabels, "") == true) && (processedLabels.count(lastLabel) != 1)) {
156                                         string saveLabel = list->getLabel();
157                                         
158                                         delete list;
159                                         list = input->getListVector(lastLabel); //get new list vector to process
160                                         
161                                         parse(list);
162                                         mothurOut(list->getLabel()); mothurOutEndLine();
163                                         
164                                         processedLabels.insert(list->getLabel());
165                                         userLabels.erase(list->getLabel());
166                                         
167                                         //restore real lastlabel to save below
168                                         list->setLabel(saveLabel);
169                         }
170                         
171                 
172                         lastLabel = list->getLabel();
173                                 
174                         delete list;
175                         list = input->getListVector(); //get new list vector to process
176                 }
177                 
178                 //output error messages about any remaining user labels
179                 set<string>::iterator it;
180                 bool needToRun = false;
181                 for (it = userLabels.begin(); it != userLabels.end(); it++) {  
182                         mothurOut("Your file does not include the label " + *it); 
183                         if (processedLabels.count(lastLabel) != 1) {
184                                 mothurOut(". I will use " + lastLabel + "."); mothurOutEndLine();
185                                 needToRun = true;
186                         }else {
187                                 mothurOut(". Please refer to " + lastLabel + "."); mothurOutEndLine();
188                         }
189
190                 }
191                 
192                 //run last label if you need to
193                 if (needToRun == true)  {
194                         if (list != NULL) {     delete list;    }
195                         list = input->getListVector(lastLabel); //get new list vector to process
196                         
197                         parse(list);            
198                         mothurOut(list->getLabel()); mothurOutEndLine();
199                         
200                         delete list;
201                 }
202                 
203                 for (it3 = filehandles.begin(); it3 != filehandles.end(); it3++) {
204                         (*(filehandles[it3->first])).close();
205                         delete it3->second;
206                 }
207                 
208                 delete groupMap;
209                 
210                 return 0;
211         }
212         catch(exception& e) {
213                 errorOut(e, "ParseListCommand", "execute");
214                 exit(1);
215         }
216 }
217 /**********************************************************************************************************************/
218 void ParseListCommand::parse(ListVector* thisList) {
219         try {
220         
221                 map<string, string> groupVector;
222                 map<string, string>::iterator itGroup;
223                 map<string, int> groupNumBins;
224                 
225                 //print label
226                 for (it3 = filehandles.begin(); it3 != filehandles.end(); it3++) {
227                         groupNumBins[it3->first] = 0;
228                         groupVector[it3->first] = "";
229                 }
230
231                 
232                 for (int i = 0; i < thisList->getNumBins(); i++) {
233                         
234                         map<string, string> groupBins;
235                         string bin = list->get(i); 
236                         
237                         vector<string> names;
238                         splitAtComma(bin, names);  //parses bin into individual sequence names
239                         
240                         //parse bin into list of sequences in each group
241                         for (int j = 0; j < names.size(); j++) {
242                                 string group = groupMap->getGroup(names[j]);
243                                 
244                                 if (group == "not found") { mothurOut(names[j] + " is not in your groupfile. please correct."); mothurOutEndLine(); exit(1); }
245                                 
246                                 itGroup = groupBins.find(group);
247                                 if(itGroup == groupBins.end()) {
248                                         groupBins[group] = names[j];  //add first name
249                                         groupNumBins[group]++;
250                                 }else{ //add another name
251                                         groupBins[group] = groupBins[group] + "," + names[j];
252                                 }
253                         }
254                         
255                         //print parsed bin info to files
256                         for (itGroup = groupBins.begin(); itGroup != groupBins.end(); itGroup++) {
257                                 groupVector[itGroup->first] +=  itGroup->second + '\t'; 
258                         }
259                 
260                 }
261                 
262                 //end list vector
263                 for (it3 = filehandles.begin(); it3 != filehandles.end(); it3++) {
264                         (*(filehandles[it3->first])) << thisList->getLabel() << '\t' << groupNumBins[it3->first] << '\t' << groupVector[it3->first] << endl;  // label numBins  listvector for that group
265                 }
266
267
268         }
269         catch(exception& e) {
270                 errorOut(e, "ParseListCommand", "parse");
271                 exit(1);
272         }
273 }
274
275 /**********************************************************************************************************************/
276
277