5 * Created by Sarah Westcott on 6/2/09.
6 * Copyright 2009 Schloss Lab Umass Amherst. All rights reserved.
10 #include "getrabundcommand.h"
12 //**********************************************************************************************************************
13 vector<string> GetRAbundCommand::setParameters(){
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);
23 vector<string> myArray;
24 for (int i = 0; i < parameters.size(); i++) { myArray.push_back(parameters[i].name); }
28 m->errorOut(e, "GetRAbundCommand", "setParameters");
32 //**********************************************************************************************************************
33 string GetRAbundCommand::getHelpString(){
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";
48 m->errorOut(e, "GetRAbundCommand", "getHelpString");
52 //**********************************************************************************************************************
53 string GetRAbundCommand::getOutputPattern(string type) {
57 if (type == "rabund") { pattern = "[filename],rabund"; }
58 else { m->mothurOut("[ERROR]: No definition for type " + type + " output pattern.\n"); m->control_pressed = true; }
63 m->errorOut(e, "GetRAbundCommand", "getOutputPattern");
68 //**********************************************************************************************************************
69 GetRAbundCommand::GetRAbundCommand(){
71 abort = true; calledHelp = true;
73 vector<string> tempOutNames;
74 outputTypes["rabund"] = tempOutNames;
77 m->errorOut(e, "GetRAbundCommand", "GetRAbundCommand");
81 //**********************************************************************************************************************
82 GetRAbundCommand::GetRAbundCommand(string option) {
84 abort = false; calledHelp = false;
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;}
92 vector<string> myArray = setParameters();
94 OptionParser parser(option);
95 map<string,string> parameters = parser.getParameters();
96 map<string,string>::iterator it;
98 ValidParameters validParameter;
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; }
105 //initialize outputTypes
106 vector<string> tempOutNames;
107 outputTypes["rabund"] = tempOutNames;
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 = ""; }
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; }
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; }
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; }
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); }
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); }
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); }
157 //check for optional parameter and set defaults
158 // ...at some point should added some additional type checking...
160 temp = validParameter.validFile(parameters, "sorted", false); if (temp == "not found") { temp = "T"; }
161 sorted = m->isTrue(temp);
163 label = validParameter.validFile(parameters, "label", false);
164 if (label == "not found") { label = ""; }
166 if(label != "all") { m->splitAtDash(label, labels); allLines = 0; }
167 else { allLines = 1; }
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(); }
177 sabundfile = m->getSabundFile();
178 if (sabundfile != "") { inputfile = sabundfile; format = "sabund"; m->mothurOut("Using " + sabundfile + " as input file for the sabund parameter."); m->mothurOutEndLine(); }
180 m->mothurOut("No valid current files. You must provide a list or sabund file."); m->mothurOutEndLine();
186 if ((countfile != "") && (listfile == "")) { m->mothurOut("[ERROR]: You can only use the count file with a list file, aborting.\n"); abort = true; }
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); }
195 catch(exception& e) {
196 m->errorOut(e, "GetRAbundCommand", "GetRAbundCommand");
200 //**********************************************************************************************************************
202 int GetRAbundCommand::execute(){
205 if (abort == true) { if (calledHelp) { return 0; } return 2; }
207 map<string, string> variables;
208 variables["[filename]"] = outputDir + m->getRootName(m->getSimpleName(inputfile));
209 filename = getOutputFileName("rabund", variables);
210 m->openOutputFile(filename, out);
212 if (countfile != "") {
215 InputData input(inputfile, format);
216 RAbundVector* rabund = input.getRAbundVector();
217 string lastLabel = rabund->getLabel();
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;
223 if (m->control_pressed) { outputTypes.clear(); out.close(); m->mothurRemove(filename); delete rabund; return 0; }
225 while((rabund != NULL) && ((allLines == 1) || (userLabels.size() != 0))) {
227 if(allLines == 1 || labels.count(rabund->getLabel()) == 1){
228 m->mothurOut(rabund->getLabel()); m->mothurOutEndLine();
230 if (m->control_pressed) { outputTypes.clear(); out.close(); m->mothurRemove(filename); delete rabund; return 0; }
232 if(sorted) { rabund->print(out); }
233 else { rabund->nonSortedPrint(out); }
235 processedLabels.insert(rabund->getLabel());
236 userLabels.erase(rabund->getLabel());
239 if ((m->anyLabelsToProcess(rabund->getLabel(), userLabels, "") == true) && (processedLabels.count(lastLabel) != 1)) {
240 string saveLabel = rabund->getLabel();
243 rabund = input.getRAbundVector(lastLabel);
245 m->mothurOut(rabund->getLabel()); m->mothurOutEndLine();
247 if (m->control_pressed) { outputTypes.clear(); out.close(); m->mothurRemove(filename); delete rabund; return 0; }
249 if(sorted) { rabund->print(out); }
250 else { rabund->nonSortedPrint(out); }
252 processedLabels.insert(rabund->getLabel());
253 userLabels.erase(rabund->getLabel());
255 //restore real lastlabel to save below
256 rabund->setLabel(saveLabel);
259 lastLabel = rabund->getLabel();
262 rabund = input.getRAbundVector();
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();
274 m->mothurOut(". Please refer to " + lastLabel + "."); m->mothurOutEndLine();
278 //run last label if you need to
279 if (needToRun == true) {
280 if (rabund != NULL) { delete rabund; }
281 rabund = input.getRAbundVector(lastLabel);
283 m->mothurOut(rabund->getLabel()); m->mothurOutEndLine();
285 if (m->control_pressed) { outputTypes.clear(); out.close(); m->mothurRemove(filename); delete rabund; return 0; }
287 if(sorted) { rabund->print(out); }
288 else { rabund->nonSortedPrint(out); }
294 if (m->control_pressed) { outputTypes.clear(); out.close(); m->mothurRemove(filename); return 0; }
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();
303 //set rabund file as new current rabundfile
305 itTypes = outputTypes.find("rabund");
306 if (itTypes != outputTypes.end()) {
307 if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setRabundFile(current); }
313 catch(exception& e) {
314 m->errorOut(e, "GetRAbundCommand", "execute");
318 //**********************************************************************************************************************
319 int GetRAbundCommand::processList(ofstream& out){
322 ct.readTable(countfile, false);
324 InputData input(inputfile, format);
325 ListVector* list = input.getListVector();
326 string lastLabel = list->getLabel();
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;
332 if (m->control_pressed) { delete list; return 0; }
334 while((list != NULL) && ((allLines == 1) || (userLabels.size() != 0))) {
336 if(allLines == 1 || labels.count(list->getLabel()) == 1){
337 m->mothurOut(list->getLabel()); m->mothurOutEndLine();
339 if (m->control_pressed) { delete list; return 0; }
341 RAbundVector* rabund = new RAbundVector();
342 createRabund(ct, list, rabund);
344 if(sorted) { rabund->print(out); }
345 else { rabund->nonSortedPrint(out); }
348 processedLabels.insert(list->getLabel());
349 userLabels.erase(list->getLabel());
352 if ((m->anyLabelsToProcess(list->getLabel(), userLabels, "") == true) && (processedLabels.count(lastLabel) != 1)) {
353 string saveLabel = list->getLabel();
356 list = input.getListVector(lastLabel);
358 m->mothurOut(list->getLabel()); m->mothurOutEndLine();
360 if (m->control_pressed) { delete list; return 0; }
362 RAbundVector* rabund = new RAbundVector();
363 createRabund(ct, list, rabund);
365 if(sorted) { rabund->print(out); }
366 else { rabund->nonSortedPrint(out); }
369 processedLabels.insert(list->getLabel());
370 userLabels.erase(list->getLabel());
372 //restore real lastlabel to save below
373 list->setLabel(saveLabel);
376 lastLabel = list->getLabel();
379 list = input.getListVector();
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();
391 m->mothurOut(". Please refer to " + lastLabel + "."); m->mothurOutEndLine();
395 //run last label if you need to
396 if (needToRun == true) {
397 if (list != NULL) { delete list; }
398 list = input.getListVector(lastLabel);
400 m->mothurOut(list->getLabel()); m->mothurOutEndLine();
402 if (m->control_pressed) { delete list; return 0; }
404 RAbundVector* rabund = new RAbundVector();
405 createRabund(ct, list, rabund);
407 if(sorted) { rabund->print(out); }
408 else { rabund->nonSortedPrint(out); }
416 catch(exception& e) {
417 m->errorOut(e, "GetRAbundCommand", "processList");
421 //**********************************************************************************************************************
423 int GetRAbundCommand::createRabund(CountTable& ct, ListVector*& list, RAbundVector*& rabund){
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);
433 for (int j = 0; j < binNames.size(); j++) {
434 total += ct.getNumSeqs(binNames[j]);
436 rabund->push_back(total);
441 catch(exception& e) {
442 m->errorOut(e, "GetRAbundCommand", "createRabund");
448 //**********************************************************************************************************************