5 * Created by Sarah Westcott on 1/2/09.
6 * Copyright 2009 Schloss Lab UMASS Amherst. All rights reserved.
10 #include "sharedcommand.h"
12 //**********************************************************************************************************************
14 SharedCommand::SharedCommand(){
16 globaldata = GlobalData::getInstance();
18 //getting output filename
19 filename = globaldata->inputFileName;
20 filename = getRootName(filename);
21 filename = filename + "shared";
22 openOutputFile(filename, out);
25 groupMap = globaldata->gGroupmap;
27 //if hte user has not specified any groups then use them all
28 if (globaldata->Groups.size() == 0) {
29 groups = groupMap->namesOfGroups;
30 }else{ //they have specified groups
31 groups = globaldata->Groups;
35 //fill filehandles with neccessary ofstreams
38 for (i=0; i<groups.size(); i++) {
40 filehandles[groups[i]] = temp;
44 fileroot = getRootName(globaldata->getListFile());
46 //clears file before we start to write to it below
47 for (int i=0; i<groups.size(); i++) {
48 remove((fileroot + groups[i] + ".rabund").c_str());
53 errorOut(e, "SharedCommand", "SharedCommand");
57 //**********************************************************************************************************************
59 int SharedCommand::execute(){
63 string errorOff = "no error";
67 read = new ReadOTUFile(globaldata->inputFileName);
68 read->read(&*globaldata);
71 input = globaldata->ginput;
72 SharedList = globaldata->gSharedList;
73 string lastLabel = SharedList->getLabel();
74 vector<SharedRAbundVector*> lookup;
76 if ((globaldata->Groups.size() == 0) && (SharedList->getNumSeqs() != groupMap->getNumSeqs())) { //if the user has not specified any groups and their files don't match exit with error
77 mothurOut("Your group file contains " + toString(groupMap->getNumSeqs()) + " sequences and list file contains " + toString(SharedList->getNumSeqs()) + " sequences. Please correct."); mothurOutEndLine();
80 remove(filename.c_str()); //remove blank shared file you made
85 for (it3 = filehandles.begin(); it3 != filehandles.end(); it3++) {
89 globaldata->gSharedList = NULL;
94 //if user has specified groups make new groupfile for them
95 if (globaldata->Groups.size() != 0) { //make new group file
97 for (int i = 0; i < globaldata->Groups.size(); i++) {
98 groups += globaldata->Groups[i] + ".";
101 string newGroupFile = getRootName(globaldata->inputFileName) + groups + "groups";
103 openOutputFile(newGroupFile, outGroups);
105 vector<string> names = groupMap->getNamesSeqs();
107 for (int i = 0; i < names.size(); i++) {
108 groupName = groupMap->getGroup(names[i]);
109 if (isValidGroup(groupName, globaldata->Groups)) {
110 outGroups << names[i] << '\t' << groupName << endl;
116 //if the users enters label "0.06" and there is no "0.06" in their file use the next lowest label.
117 set<string> processedLabels;
118 set<string> userLabels = globaldata->labels;
120 while((SharedList != NULL) && ((globaldata->allLines == 1) || (userLabels.size() != 0))) {
122 if(globaldata->allLines == 1 || globaldata->labels.count(SharedList->getLabel()) == 1){
124 lookup = SharedList->getSharedRAbundVector();
125 if (pickedGroups) { //check for otus with no seqs in them
126 eliminateZeroOTUS(lookup);
128 mothurOut(lookup[0]->getLabel()); mothurOutEndLine();
130 printSharedData(lookup); //prints info to the .shared file
131 for (int i = 0; i < lookup.size(); i++) { delete lookup[i]; }
133 processedLabels.insert(SharedList->getLabel());
134 userLabels.erase(SharedList->getLabel());
137 if ((anyLabelsToProcess(SharedList->getLabel(), userLabels, errorOff) == true) && (processedLabels.count(lastLabel) != 1)) {
138 string saveLabel = SharedList->getLabel();
141 SharedList = input->getSharedListVector(lastLabel); //get new list vector to process
143 lookup = SharedList->getSharedRAbundVector();
144 if (pickedGroups) { //check for otus with no seqs in them
145 eliminateZeroOTUS(lookup);
147 mothurOut(lookup[0]->getLabel()); mothurOutEndLine();
149 printSharedData(lookup); //prints info to the .shared file
150 for (int i = 0; i < lookup.size(); i++) { delete lookup[i]; }
152 processedLabels.insert(SharedList->getLabel());
153 userLabels.erase(SharedList->getLabel());
155 //restore real lastlabel to save below
156 SharedList->setLabel(saveLabel);
160 lastLabel = SharedList->getLabel();
163 SharedList = input->getSharedListVector(); //get new list vector to process
166 //output error messages about any remaining user labels
167 set<string>::iterator it;
168 bool needToRun = false;
169 for (it = userLabels.begin(); it != userLabels.end(); it++) {
170 if (processedLabels.count(lastLabel) != 1) {
175 //run last label if you need to
176 if (needToRun == true) {
177 if (SharedList != NULL) { delete SharedList; }
178 SharedList = input->getSharedListVector(lastLabel); //get new list vector to process
180 lookup = SharedList->getSharedRAbundVector();
181 if (pickedGroups) { //check for otus with no seqs in them
182 eliminateZeroOTUS(lookup);
184 mothurOut(lookup[0]->getLabel()); mothurOutEndLine();
186 printSharedData(lookup); //prints info to the .shared file
187 for (int i = 0; i < lookup.size(); i++) { delete lookup[i]; }
191 globaldata->gSharedList = NULL;
195 for (it3 = filehandles.begin(); it3 != filehandles.end(); it3++) {
202 catch(exception& e) {
203 errorOut(e, "SharedCommand", "execute");
207 //**********************************************************************************************************************
208 void SharedCommand::printSharedData(vector<SharedRAbundVector*> thislookup) {
211 //initialize bin values
212 for (int i = 0; i < thislookup.size(); i++) {
213 //cout << "in printData " << thislookup[i]->getLabel() << '\t' << thislookup[i]->getGroup() << endl;
214 out << thislookup[i]->getLabel() << '\t' << thislookup[i]->getGroup() << '\t';
215 thislookup[i]->print(out);
217 RAbundVector rav = thislookup[i]->getRAbundVector();
218 openOutputFileAppend(fileroot + thislookup[i]->getGroup() + ".rabund", *(filehandles[thislookup[i]->getGroup()]));
219 rav.print(*(filehandles[thislookup[i]->getGroup()]));
220 (*(filehandles[thislookup[i]->getGroup()])).close();
224 catch(exception& e) {
225 errorOut(e, "SharedCommand", "printSharedData");
229 //**********************************************************************************************************************
230 void SharedCommand::eliminateZeroOTUS(vector<SharedRAbundVector*>& thislookup) {
233 vector<SharedRAbundVector*> newLookup;
234 for (int i = 0; i < thislookup.size(); i++) {
235 SharedRAbundVector* temp = new SharedRAbundVector();
236 temp->setLabel(thislookup[i]->getLabel());
237 temp->setGroup(thislookup[i]->getGroup());
238 newLookup.push_back(temp);
242 for (int i = 0; i < thislookup[0]->getNumBins(); i++) {
244 //look at each sharedRabund and make sure they are not all zero
246 for (int j = 0; j < thislookup.size(); j++) {
247 if (thislookup[j]->getAbundance(i) != 0) { allZero = false; break; }
250 //if they are not all zero add this bin
252 for (int j = 0; j < thislookup.size(); j++) {
253 newLookup[j]->push_back(thislookup[j]->getAbundance(i), thislookup[j]->getGroup());
256 //else{ cout << "bin # " << i << " is all zeros" << endl; }
259 for (int j = 0; j < thislookup.size(); j++) { delete thislookup[j]; }
260 thislookup = newLookup;
264 catch(exception& e) {
265 errorOut(e, "SharedCommand", "eliminateZeroOTUS");
269 //**********************************************************************************************************************
270 void SharedCommand::createMisMatchFile() {
272 ofstream outMisMatch;
273 string outputMisMatchName = getRootName(globaldata->inputFileName);
275 //you have sequences in your list file that are not in your group file
276 if (SharedList->getNumSeqs() > groupMap->getNumSeqs()) {
277 outputMisMatchName += "missing.group";
278 mothurOut("For a list of names that are in your list file and not in your group file, please refer to " + outputMisMatchName + "."); mothurOutEndLine();
280 openOutputFile(outputMisMatchName, outMisMatch);
282 //go through list and if group returns "not found" output it
283 for (int i = 0; i < SharedList->getNumBins(); i++) {
285 string names = SharedList->get(i);
287 while (names.find_first_of(',') != -1) {
288 string name = names.substr(0,names.find_first_of(','));
289 names = names.substr(names.find_first_of(',')+1, names.length());
290 string group = groupMap->getGroup(name);
292 if(group == "not found") { outMisMatch << name << endl; }
296 string group = groupMap->getGroup(names);
297 if(group == "not found") { outMisMatch << names << endl; }
303 }else {//you have sequences in your group file that are not in you list file
305 outputMisMatchName += "missing.name";
306 mothurOut("For a list of names that are in your group file and not in your list file, please refer to " + outputMisMatchName + "."); mothurOutEndLine();
308 map<string, string> namesInList;
310 //go through listfile and get names
311 for (int i = 0; i < SharedList->getNumBins(); i++) {
313 string names = SharedList->get(i);
315 while (names.find_first_of(',') != -1) {
316 string name = names.substr(0,names.find_first_of(','));
317 names = names.substr(names.find_first_of(',')+1, names.length());
319 namesInList[name] = name;
323 namesInList[names] = names;
326 //get names of sequences in groupfile
327 vector<string> seqNames = groupMap->getNamesSeqs();
329 map<string, string>::iterator itMatch;
331 openOutputFile(outputMisMatchName, outMisMatch);
333 //loop through names in seqNames and if they aren't in namesIn list output them
334 for (int i = 0; i < seqNames.size(); i++) {
336 itMatch = namesInList.find(seqNames[i]);
338 if (itMatch == namesInList.end()) {
340 outMisMatch << seqNames[i] << endl;
347 catch(exception& e) {
348 errorOut(e, "SharedCommand", "createMisMatchFile");
353 //**********************************************************************************************************************
355 SharedCommand::~SharedCommand(){
361 //**********************************************************************************************************************
363 bool SharedCommand::isValidGroup(string groupname, vector<string> groups) {
365 for (int i = 0; i < groups.size(); i++) {
366 if (groupname == groups[i]) { return true; }
371 catch(exception& e) {
372 errorOut(e, "SharedCommand", "isValidGroup");
376 /************************************************************/