2 * removeotuscommand.cpp
5 * Created by westcott on 11/12/10.
6 * Copyright 2010 Schloss Lab. All rights reserved.
10 #include "removeotuscommand.h"
11 #include "inputdata.h"
12 #include "sharedutilities.h"
15 //**********************************************************************************************************************
16 vector<string> RemoveOtusCommand::getValidParameters(){
18 string Array[] = { "group", "accnos","label", "groups","list","outputdir","inputdir" };
19 vector<string> myArray (Array, Array+(sizeof(Array)/sizeof(string)));
23 m->errorOut(e, "RemoveOtusCommand", "getValidParameters");
27 //**********************************************************************************************************************
28 RemoveOtusCommand::RemoveOtusCommand(){
31 //initialize outputTypes
32 vector<string> tempOutNames;
33 outputTypes["group"] = tempOutNames;
34 outputTypes["list"] = tempOutNames;
37 m->errorOut(e, "RemoveOtusCommand", "RemoveOtusCommand");
41 //**********************************************************************************************************************
42 vector<string> RemoveOtusCommand::getRequiredParameters(){
44 string Array[] = {"group","label", "list"};
45 vector<string> myArray (Array, Array+(sizeof(Array)/sizeof(string)));
49 m->errorOut(e, "RemoveOtusCommand", "getRequiredParameters");
53 //**********************************************************************************************************************
54 vector<string> RemoveOtusCommand::getRequiredFiles(){
56 vector<string> myArray;
60 m->errorOut(e, "RemoveOtusCommand", "getRequiredFiles");
64 //**********************************************************************************************************************
65 RemoveOtusCommand::RemoveOtusCommand(string option) {
69 //allow user to run help
70 if(option == "help") { help(); abort = true; }
73 //valid paramters for this command
74 string Array[] = { "group", "accnos","label", "groups", "list","outputdir","inputdir" };
75 vector<string> myArray (Array, Array+(sizeof(Array)/sizeof(string)));
77 OptionParser parser(option);
78 map<string,string> parameters = parser.getParameters();
80 ValidParameters validParameter;
81 map<string,string>::iterator it;
83 //check to make sure all parameters are valid for command
84 for (it = parameters.begin(); it != parameters.end(); it++) {
85 if (validParameter.isValidParameter(it->first, myArray, it->second) != true) { abort = true; }
88 //initialize outputTypes
89 vector<string> tempOutNames;
90 outputTypes["group"] = tempOutNames;
91 outputTypes["list"] = tempOutNames;
94 //if the user changes the output directory command factory will send this info to us in the output parameter
95 outputDir = validParameter.validFile(parameters, "outputdir", false); if (outputDir == "not found"){ outputDir = ""; }
97 //if the user changes the input directory command factory will send this info to us in the output parameter
98 string inputDir = validParameter.validFile(parameters, "inputdir", false);
99 if (inputDir == "not found"){ inputDir = ""; }
102 it = parameters.find("accnos");
103 //user has given a template file
104 if(it != parameters.end()){
105 path = m->hasPath(it->second);
106 //if the user has not given a path then, add inputdir. else leave path alone.
107 if (path == "") { parameters["accnos"] = inputDir + it->second; }
110 it = parameters.find("list");
111 //user has given a template file
112 if(it != parameters.end()){
113 path = m->hasPath(it->second);
114 //if the user has not given a path then, add inputdir. else leave path alone.
115 if (path == "") { parameters["list"] = inputDir + it->second; }
118 it = parameters.find("group");
119 //user has given a template file
120 if(it != parameters.end()){
121 path = m->hasPath(it->second);
122 //if the user has not given a path then, add inputdir. else leave path alone.
123 if (path == "") { parameters["group"] = inputDir + it->second; }
128 //check for required parameters
129 accnosfile = validParameter.validFile(parameters, "accnos", true);
130 if (accnosfile == "not open") { abort = true; }
131 else if (accnosfile == "not found") { accnosfile = ""; }
133 groupfile = validParameter.validFile(parameters, "group", true);
134 if (groupfile == "not open") { abort = true; }
135 else if (groupfile == "not found") { groupfile = ""; m->mothurOut("You must provide a group file."); m->mothurOutEndLine(); abort = true; }
137 listfile = validParameter.validFile(parameters, "list", true);
138 if (listfile == "not open") { abort = true; }
139 else if (listfile == "not found") { listfile = ""; m->mothurOut("You must provide a list file."); m->mothurOutEndLine(); abort = true; }
141 groups = validParameter.validFile(parameters, "groups", false);
142 if (groups == "not found") { groups = ""; }
144 m->splitAtDash(groups, Groups);
147 label = validParameter.validFile(parameters, "label", false);
148 if (label == "not found") { label = ""; m->mothurOut("You must provide a label to process."); m->mothurOutEndLine(); abort = true; }
150 if ((accnosfile == "") && (Groups.size() == 0)) { m->mothurOut("You must provide an accnos file or specify groups using the groups parameter."); m->mothurOutEndLine(); abort = true; }
154 catch(exception& e) {
155 m->errorOut(e, "RemoveOtusCommand", "RemoveOtusCommand");
159 //**********************************************************************************************************************
161 void RemoveOtusCommand::help(){
163 m->mothurOut("The remove.otus command removes otus containing sequences from a specfic group or set of groups.\n");
164 m->mothurOut("It outputs a new list file containing the otus containing sequences NOT from in the those specified groups.\n");
165 m->mothurOut("The remove.otus command parameters are accnos, group, list, label and groups. The group, list and label parameters are required.\n");
166 m->mothurOut("You must also provide an accnos containing the list of groups to get or set the groups parameter to the groups you wish to select.\n");
167 m->mothurOut("The groups parameter allows you to specify which of the groups in your groupfile you would like. You can separate group names with dashes.\n");
168 m->mothurOut("The label parameter allows you to specify which distance you want to process.\n");
169 m->mothurOut("The remove.otus command should be in the following format: remove.otus(accnos=yourAccnos, list=yourListFile, group=yourGroupFile, label=yourLabel).\n");
170 m->mothurOut("Example remove.otus(accnos=amazon.accnos, list=amazon.fn.list, group=amazon.groups, label=0.03).\n");
171 m->mothurOut("or remove.otus(groups=pasture, list=amazon.fn.list, amazon.groups, label=0.03).\n");
172 m->mothurOut("Note: No spaces between parameter labels (i.e. list), '=' and parameters (i.e.yourListFile).\n\n");
174 catch(exception& e) {
175 m->errorOut(e, "RemoveOtusCommand", "help");
180 //**********************************************************************************************************************
182 int RemoveOtusCommand::execute(){
185 if (abort == true) { return 0; }
187 groupMap = new GroupMap(groupfile);
190 //get groups you want to remove
191 if (accnosfile != "") { readAccnos(); }
193 //make sure groups are valid
194 //takes care of user setting groupNames that are invalid or setting groups=all
195 SharedUtil* util = new SharedUtil();
196 util->setGroups(Groups, groupMap->namesOfGroups);
199 if (m->control_pressed) { delete groupMap; return 0; }
201 //read through the list file keeping any otus that contain any sequence from the groups selected
204 if (m->control_pressed) { for (int i = 0; i < outputNames.size(); i++) { remove(outputNames[i].c_str()); } return 0; }
206 if (outputNames.size() != 0) {
207 m->mothurOutEndLine();
208 m->mothurOut("Output File names: "); m->mothurOutEndLine();
209 for (int i = 0; i < outputNames.size(); i++) { m->mothurOut(outputNames[i]); m->mothurOutEndLine(); }
210 m->mothurOutEndLine();
216 catch(exception& e) {
217 m->errorOut(e, "RemoveOtusCommand", "execute");
221 //**********************************************************************************************************************
222 int RemoveOtusCommand::readListGroup(){
224 string thisOutputDir = outputDir;
225 if (outputDir == "") { thisOutputDir += m->hasPath(listfile); }
226 string outputFileName = thisOutputDir + m->getRootName(m->getSimpleName(listfile)) + "pick." + label + m->getExtension(listfile);
229 m->openOutputFile(outputFileName, out);
231 string GroupOutputDir = outputDir;
232 if (outputDir == "") { GroupOutputDir += m->hasPath(groupfile); }
233 string outputGroupFileName = GroupOutputDir + m->getRootName(m->getSimpleName(groupfile)) + "pick." + label + m->getExtension(groupfile);
236 m->openOutputFile(outputGroupFileName, outGroup);
238 InputData* input = new InputData(listfile, "list");
239 ListVector* list = input->getListVector();
240 string lastLabel = list->getLabel();
242 //if the users enters label "0.06" and there is no "0.06" in their file use the next lowest label.
243 set<string> labels; labels.insert(label);
244 set<string> processedLabels;
245 set<string> userLabels = labels;
247 bool wroteSomething = false;
249 //as long as you are not at the end of the file or done wih the lines you want
250 while((list != NULL) && (userLabels.size() != 0)) {
252 if (m->control_pressed) { delete list; delete input; out.close(); outGroup.close(); remove(outputFileName.c_str()); remove(outputGroupFileName.c_str());return 0; }
254 if(labels.count(list->getLabel()) == 1){
255 processList(list, groupMap, out, outGroup, wroteSomething);
257 processedLabels.insert(list->getLabel());
258 userLabels.erase(list->getLabel());
261 if ((m->anyLabelsToProcess(list->getLabel(), userLabels, "") == true) && (processedLabels.count(lastLabel) != 1)) {
262 string saveLabel = list->getLabel();
266 list = input->getListVector(lastLabel);
268 processList(list, groupMap, out, outGroup, wroteSomething);
270 processedLabels.insert(list->getLabel());
271 userLabels.erase(list->getLabel());
273 //restore real lastlabel to save below
274 list->setLabel(saveLabel);
277 lastLabel = list->getLabel();
279 delete list; list = NULL;
281 //get next line to process
282 list = input->getListVector();
286 if (m->control_pressed) { if (list != NULL) { delete list; } delete input; out.close(); outGroup.close(); remove(outputFileName.c_str()); remove(outputGroupFileName.c_str()); return 0; }
288 //output error messages about any remaining user labels
289 set<string>::iterator it;
290 bool needToRun = false;
291 for (it = userLabels.begin(); it != userLabels.end(); it++) {
292 m->mothurOut("Your file does not include the label " + *it);
293 if (processedLabels.count(lastLabel) != 1) {
294 m->mothurOut(". I will use " + lastLabel + "."); m->mothurOutEndLine();
297 m->mothurOut(". Please refer to " + lastLabel + "."); m->mothurOutEndLine();
301 //run last label if you need to
302 if (needToRun == true) {
303 if (list != NULL) { delete list; }
305 list = input->getListVector(lastLabel);
307 processList(list, groupMap, out, outGroup, wroteSomething);
309 delete list; list = NULL;
315 if (wroteSomething == false) { m->mothurOut("At distance " + label + " your file ONLY contains otus containing sequences from the groups you wish to remove."); m->mothurOutEndLine(); }
316 outputTypes["list"].push_back(outputFileName); outputNames.push_back(outputFileName);
317 outputTypes["group"].push_back(outputGroupFileName); outputNames.push_back(outputGroupFileName);
322 catch(exception& e) {
323 m->errorOut(e, "RemoveOtusCommand", "readList");
327 //**********************************************************************************************************************
328 int RemoveOtusCommand::processList(ListVector*& list, GroupMap*& groupMap, ofstream& out, ofstream& outGroup, bool& wroteSomething){
331 //make a new list vector
333 newList.setLabel(list->getLabel());
337 for (int i = 0; i < list->getNumBins(); i++) {
338 if (m->control_pressed) { return 0; }
340 //parse out names that are in accnos file
341 string binnames = list->get(i);
343 bool removeBin = false;
344 string groupFileOutput = "";
347 string individual = "";
348 int length = binnames.length();
349 for(int j=0;j<length;j++){
350 if(binnames[j] == ','){
351 string group = groupMap->getGroup(individual);
352 if (group == "not found") { m->mothurOut("[ERROR]: " + individual + " is not in your groupfile. please correct."); m->mothurOutEndLine(); group = "NOTFOUND"; }
354 if (m->inUsersGroups(group, Groups)) { removeBin = true; break; }
355 groupFileOutput += individual + "\t" + group + "\n";
359 else{ individual += binnames[j]; }
364 string group = groupMap->getGroup(individual);
365 if (group == "not found") { m->mothurOut("[ERROR]: " + individual + " is not in your groupfile. please correct."); m->mothurOutEndLine(); group = "NOTFOUND"; }
367 if (m->inUsersGroups(group, Groups)) { removeBin = true; }
368 groupFileOutput += individual + "\t" + group + "\n";
371 //if there are no sequences from the groups we want to remove in this bin add to new list, output to groupfile
372 newList.push_back(binnames);
373 outGroup << groupFileOutput;
383 //print new listvector
384 if (newList.getNumBins() != 0) {
385 wroteSomething = true;
389 m->mothurOut(newList.getLabel() + " - removed " + toString(numOtus) + " of the " + toString(list->getNumBins()) + " OTUs."); m->mothurOutEndLine();
394 catch(exception& e) {
395 m->errorOut(e, "RemoveOtusCommand", "processList");
399 //**********************************************************************************************************************
400 void RemoveOtusCommand::readAccnos(){
405 m->openInputFile(accnosfile, in);
411 Groups.push_back(name);
418 catch(exception& e) {
419 m->errorOut(e, "RemoveOtusCommand", "readAccnos");
423 //**********************************************************************************************************************