5 * Created by Sarah Westcott on 6/2/09.
6 * Copyright 2009 Schloss Lab UMASS Amherst. All rights reserved.
10 #include "getsabundcommand.h"
12 //**********************************************************************************************************************
13 vector<string> GetSAbundCommand::setParameters(){
15 CommandParameter plist("list", "InputTypes", "", "", "LRSS", "LRSS", "none","sabund",false,false, true); parameters.push_back(plist);
16 CommandParameter pcount("count", "InputTypes", "", "", "none", "none", "none","",false,false, false); parameters.push_back(pcount);
17 CommandParameter prabund("rabund", "InputTypes", "", "", "LRSS", "LRSS", "none","sabund",false,false, true); parameters.push_back(prabund);
18 CommandParameter plabel("label", "String", "", "", "", "", "","",false,false); parameters.push_back(plabel);
19 CommandParameter pinputdir("inputdir", "String", "", "", "", "", "","",false,false); parameters.push_back(pinputdir);
20 CommandParameter poutputdir("outputdir", "String", "", "", "", "", "","",false,false); parameters.push_back(poutputdir);
22 vector<string> myArray;
23 for (int i = 0; i < parameters.size(); i++) { myArray.push_back(parameters[i].name); }
27 m->errorOut(e, "GetSAbundCommand", "setParameters");
31 //**********************************************************************************************************************
32 string GetSAbundCommand::getHelpString(){
34 string helpString = "";
35 helpString += "The get.sabund command parameters is list, rabund, count and label. list or rabund is required unless a valid current file exists.\n";
36 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 sabund file, providing the count file allows you to do so.\n";
37 helpString += "The label parameter allows you to select what distance levels you would like included in your .sabund file, and are separated by dashes.\n";
38 helpString += "The get.sabund command should be in the following format: get.sabund(label=yourLabels).\n";
39 helpString += "Example get.sabund().\n";
40 helpString += "The default value for label is all labels in your inputfile.\n";
41 helpString += "The get.sabund command outputs a .sabund file containing the labels you selected.\n";
42 helpString += "Note: No spaces between parameter labels (i.e. label), '=' and parameters (i.e.yourLabel).\n";
46 m->errorOut(e, "GetSAbundCommand", "getHelpString");
50 //**********************************************************************************************************************
51 string GetSAbundCommand::getOutputPattern(string type) {
55 if (type == "sabund") { pattern = "[filename],sabund"; }
56 else { m->mothurOut("[ERROR]: No definition for type " + type + " output pattern.\n"); m->control_pressed = true; }
61 m->errorOut(e, "GetRAbundCommand", "getOutputPattern");
65 //**********************************************************************************************************************
66 GetSAbundCommand::GetSAbundCommand(){
68 abort = true; calledHelp = true;
70 vector<string> tempOutNames;
71 outputTypes["sabund"] = tempOutNames;
74 m->errorOut(e, "GetSAbundCommand", "GetSAbundCommand");
78 //**********************************************************************************************************************
79 GetSAbundCommand::GetSAbundCommand(string option) {
81 abort = false; calledHelp = false;
84 //allow user to run help
85 if(option == "help") { help(); abort = true; calledHelp = true; }
86 else if(option == "citation") { citation(); abort = true; calledHelp = true;}
89 vector<string> myArray = setParameters();
91 OptionParser parser(option);
92 map<string,string> parameters = parser.getParameters();
93 map<string,string>::iterator it;
95 ValidParameters validParameter;
97 //check to make sure all parameters are valid for command
98 for (it = parameters.begin(); it != parameters.end(); it++) {
99 if (validParameter.isValidParameter(it->first, myArray, it->second) != true) { abort = true; }
102 //initialize outputTypes
103 vector<string> tempOutNames;
104 outputTypes["sabund"] = tempOutNames;
106 //if the user changes the input directory command factory will send this info to us in the output parameter
107 string inputDir = validParameter.validFile(parameters, "inputdir", false);
108 if (inputDir == "not found"){ inputDir = ""; }
111 it = parameters.find("list");
112 //user has given a template file
113 if(it != parameters.end()){
114 path = m->hasPath(it->second);
115 //if the user has not given a path then, add inputdir. else leave path alone.
116 if (path == "") { parameters["list"] = inputDir + it->second; }
119 it = parameters.find("rabund");
120 //user has given a template file
121 if(it != parameters.end()){
122 path = m->hasPath(it->second);
123 //if the user has not given a path then, add inputdir. else leave path alone.
124 if (path == "") { parameters["rabund"] = inputDir + it->second; }
127 it = parameters.find("count");
128 //user has given a template file
129 if(it != parameters.end()){
130 path = m->hasPath(it->second);
131 //if the user has not given a path then, add inputdir. else leave path alone.
132 if (path == "") { parameters["count"] = inputDir + it->second; }
137 //check for required parameters
138 listfile = validParameter.validFile(parameters, "list", true);
139 if (listfile == "not open") { listfile = ""; abort = true; }
140 else if (listfile == "not found") { listfile = ""; }
141 else { format = "list"; inputfile = listfile; m->setListFile(listfile); }
143 rabundfile = validParameter.validFile(parameters, "rabund", true);
144 if (rabundfile == "not open") { rabundfile = ""; abort = true; }
145 else if (rabundfile == "not found") { rabundfile = ""; }
146 else { format = "rabund"; inputfile = rabundfile; m->setRabundFile(rabundfile); }
148 countfile = validParameter.validFile(parameters, "count", true);
149 if (countfile == "not open") { countfile = ""; abort = true; }
150 else if (countfile == "not found") { countfile = ""; }
151 else { m->setCountTableFile(countfile); }
153 //check for optional parameter and set defaults
154 // ...at some point should added some additional type checking...
155 label = validParameter.validFile(parameters, "label", false);
156 if (label == "not found") { label = ""; }
158 if(label != "all") { m->splitAtDash(label, labels); allLines = 0; }
159 else { allLines = 1; }
162 if ((listfile == "") && (rabundfile == "")) {
163 //is there are current file available for any of these?
164 //give priority to shared, then list, then rabund, then sabund
165 //if there is a current shared file, use it
166 listfile = m->getListFile();
167 if (listfile != "") { inputfile = listfile; format = "list"; m->mothurOut("Using " + listfile + " as input file for the list parameter."); m->mothurOutEndLine(); }
169 rabundfile = m->getRabundFile();
170 if (rabundfile != "") { inputfile = rabundfile; format = "rabund"; m->mothurOut("Using " + rabundfile + " as input file for the rabund parameter."); m->mothurOutEndLine(); }
172 m->mothurOut("No valid current files. You must provide a list or rabund file."); m->mothurOutEndLine();
178 if ((countfile != "") && (listfile == "")) { m->mothurOut("[ERROR]: You can only use the count file with a list file, aborting.\n"); abort = true; }
180 //if the user changes the output directory command factory will send this info to us in the output parameter
181 outputDir = validParameter.validFile(parameters, "outputdir", false); if (outputDir == "not found"){ outputDir = m->hasPath(inputfile); }
187 catch(exception& e) {
188 m->errorOut(e, "GetSAbundCommand", "GetSAbundCommand");
192 //**********************************************************************************************************************
194 int GetSAbundCommand::execute(){
197 if (abort == true) { if (calledHelp) { return 0; } return 2; }
198 map<string, string> variables;
199 variables["[filename]"] = outputDir + m->getRootName(m->getSimpleName(inputfile));
200 filename = getOutputFileName("sabund", variables);
201 m->openOutputFile(filename, out);
203 if (countfile != "") {
206 InputData input(inputfile, format);
207 SAbundVector* sabund = input.getSAbundVector();
208 string lastLabel = sabund->getLabel();
211 //if the users enters label "0.06" and there is no "0.06" in their file use the next lowest label.
212 set<string> processedLabels;
213 set<string> userLabels = labels;
215 if (m->control_pressed) { outputTypes.clear(); out.close(); m->mothurRemove(filename); delete sabund; return 0; }
218 while((sabund != NULL) && ((allLines == 1) || (userLabels.size() != 0))) {
220 if(allLines == 1 || labels.count(sabund->getLabel()) == 1){
221 m->mothurOut(sabund->getLabel()); m->mothurOutEndLine();
225 if (m->control_pressed) { outputTypes.clear(); out.close(); m->mothurRemove(filename); delete sabund; return 0; }
227 processedLabels.insert(sabund->getLabel());
228 userLabels.erase(sabund->getLabel());
231 if ((m->anyLabelsToProcess(sabund->getLabel(), userLabels, "") == true) && (processedLabels.count(lastLabel) != 1)) {
232 string saveLabel = sabund->getLabel();
235 sabund = (input.getSAbundVector(lastLabel));
237 m->mothurOut(sabund->getLabel()); m->mothurOutEndLine();
240 if (m->control_pressed) { outputTypes.clear(); out.close(); m->mothurRemove(filename); delete sabund; return 0; }
242 processedLabels.insert(sabund->getLabel());
243 userLabels.erase(sabund->getLabel());
245 //restore real lastlabel to save below
246 sabund->setLabel(saveLabel);
250 lastLabel = sabund->getLabel();
253 sabund = (input.getSAbundVector());
256 //output error messages about any remaining user labels
257 set<string>::iterator it;
258 bool needToRun = false;
259 for (it = userLabels.begin(); it != userLabels.end(); it++) {
260 m->mothurOut("Your file does not include the label " + *it);
261 if (processedLabels.count(lastLabel) != 1) {
262 m->mothurOut(". I will use " + lastLabel + "."); m->mothurOutEndLine();
265 m->mothurOut(". Please refer to " + lastLabel + "."); m->mothurOutEndLine();
269 //run last label if you need to
270 if (needToRun == true) {
271 if (sabund != NULL) { delete sabund; }
272 sabund = (input.getSAbundVector(lastLabel));
274 m->mothurOut(sabund->getLabel()); m->mothurOutEndLine();
278 if (m->control_pressed) { outputTypes.clear(); out.close(); m->mothurRemove(filename); return 0; }
284 if (m->control_pressed) { outputTypes.clear(); m->mothurRemove(filename); return 0; }
286 m->mothurOutEndLine();
287 m->mothurOut("Output File Names: "); m->mothurOutEndLine();
288 m->mothurOut(filename); m->mothurOutEndLine(); outputNames.push_back(filename); outputTypes["sabund"].push_back(filename);
289 m->mothurOutEndLine();
291 //set sabund file as new current sabundfile
293 itTypes = outputTypes.find("sabund");
294 if (itTypes != outputTypes.end()) {
295 if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setSabundFile(current); }
301 catch(exception& e) {
302 m->errorOut(e, "GetSAbundCommand", "execute");
306 //**********************************************************************************************************************
307 int GetSAbundCommand::processList(ofstream& out){
310 ct.readTable(countfile);
312 InputData input(inputfile, format);
313 ListVector* list = input.getListVector();
314 string lastLabel = list->getLabel();
316 //if the users enters label "0.06" and there is no "0.06" in their file use the next lowest label.
317 set<string> processedLabels;
318 set<string> userLabels = labels;
320 if (m->control_pressed) { delete list; return 0; }
322 while((list != NULL) && ((allLines == 1) || (userLabels.size() != 0))) {
324 if(allLines == 1 || labels.count(list->getLabel()) == 1){
325 m->mothurOut(list->getLabel()); m->mothurOutEndLine();
327 if (m->control_pressed) { delete list; return 0; }
329 RAbundVector* rabund = new RAbundVector();
330 createRabund(ct, list, rabund);
331 SAbundVector sabund = rabund->getSAbundVector();
335 processedLabels.insert(list->getLabel());
336 userLabels.erase(list->getLabel());
339 if ((m->anyLabelsToProcess(list->getLabel(), userLabels, "") == true) && (processedLabels.count(lastLabel) != 1)) {
340 string saveLabel = list->getLabel();
343 list = input.getListVector(lastLabel);
345 m->mothurOut(list->getLabel()); m->mothurOutEndLine();
347 if (m->control_pressed) { delete list; return 0; }
349 RAbundVector* rabund = new RAbundVector();
350 createRabund(ct, list, rabund);
351 SAbundVector sabund = rabund->getSAbundVector();
355 processedLabels.insert(list->getLabel());
356 userLabels.erase(list->getLabel());
358 //restore real lastlabel to save below
359 list->setLabel(saveLabel);
362 lastLabel = list->getLabel();
365 list = input.getListVector();
368 //output error messages about any remaining user labels
369 set<string>::iterator it;
370 bool needToRun = false;
371 for (it = userLabels.begin(); it != userLabels.end(); it++) {
372 m->mothurOut("Your file does not include the label " + *it);
373 if (processedLabels.count(lastLabel) != 1) {
374 m->mothurOut(". I will use " + lastLabel + "."); m->mothurOutEndLine();
377 m->mothurOut(". Please refer to " + lastLabel + "."); m->mothurOutEndLine();
381 //run last label if you need to
382 if (needToRun == true) {
383 if (list != NULL) { delete list; }
384 list = input.getListVector(lastLabel);
386 m->mothurOut(list->getLabel()); m->mothurOutEndLine();
388 if (m->control_pressed) { delete list; return 0; }
390 RAbundVector* rabund = new RAbundVector();
391 createRabund(ct, list, rabund);
392 SAbundVector sabund = rabund->getSAbundVector();
401 catch(exception& e) {
402 m->errorOut(e, "GetSAbundCommand", "processList");
406 //**********************************************************************************************************************
408 int GetSAbundCommand::createRabund(CountTable& ct, ListVector*& list, RAbundVector*& rabund){
411 rabund->setLabel(list->getLabel());
412 for(int i = 0; i < list->getNumBins(); i++) {
413 if (m->control_pressed) { return 0; }
414 vector<string> binNames;
415 string bin = list->get(i);
416 m->splitAtComma(bin, binNames);
418 for (int j = 0; j < binNames.size(); j++) {
419 total += ct.getNumSeqs(binNames[j]);
421 rabund->push_back(total);
426 catch(exception& e) {
427 m->errorOut(e, "GetSAbundCommand", "createRabund");
433 //**********************************************************************************************************************