]> git.donarmstrong.com Git - mothur.git/blob - counttable.cpp
Merge remote-tracking branch 'mothur/master'
[mothur.git] / counttable.cpp
1 //
2 //  counttable.cpp
3 //  Mothur
4 //
5 //  Created by Sarah Westcott on 6/26/12.
6 //  Copyright (c) 2012 Schloss Lab. All rights reserved.
7 //
8
9 #include "counttable.h"
10
11 /************************************************************/
12 int CountTable::createTable(set<string>& n, map<string, string>& g, set<string>& gs) {
13     try {
14         int numGroups = 0;
15         groups.clear();
16         totalGroups.clear();
17         indexGroupMap.clear();
18         indexNameMap.clear();
19         counts.clear();
20         for (set<string>::iterator it = gs.begin(); it != gs.end(); it++) { groups.push_back(*it);  hasGroups = true; }
21         numGroups = groups.size();
22         totalGroups.resize(numGroups, 0);
23         
24                 //sort groups to keep consistent with how we store the groups in groupmap
25         sort(groups.begin(), groups.end());
26         for (int i = 0; i < groups.size(); i++) {  indexGroupMap[groups[i]] = i; }
27         m->setAllGroups(groups);
28         
29         uniques = 0;
30         total = 0;
31         for (set<string>::iterator it = n.begin(); it != n.end(); it++) {
32             
33             if (m->control_pressed) { break; }
34             
35             string seqName = *it;
36             
37             vector<int> groupCounts; groupCounts.resize(numGroups, 0);
38             map<string, string>::iterator itGroup = g.find(seqName);
39             
40             if (itGroup != g.end()) {   
41                 groupCounts[indexGroupMap[itGroup->second]] = 1; 
42                 totalGroups[indexGroupMap[itGroup->second]]++;
43             }else { m->mothurOut("[ERROR]: Your group file does not contain " + seqName + ". Please correct."); m->mothurOutEndLine(); }
44             
45             map<string, int>::iterator it2 = indexNameMap.find(seqName);
46             if (it2 == indexNameMap.end()) {
47                 if (hasGroups) {  counts.push_back(groupCounts);  }
48                 indexNameMap[seqName] = uniques;
49                 totals.push_back(1);
50                 total++;
51                 uniques++;
52             }
53         }
54         
55         if (hasGroups) {
56             for (int i = 0; i < totalGroups.size(); i++) {
57                 if (totalGroups[i] == 0) { m->mothurOut("\nRemoving group: " + groups[i] + " because all sequences have been removed.\n"); removeGroup(groups[i]); i--; }
58             }
59         }
60
61         return 0;
62     }
63         catch(exception& e) {
64                 m->errorOut(e, "CountTable", "createTable");
65                 exit(1);
66         }
67 }
68 /************************************************************/
69 bool CountTable::testGroups(string file) {
70     try {
71         m = MothurOut::getInstance(); hasGroups = false; total = 0;
72         ifstream in;
73         m->openInputFile(file, in);
74     
75         string headers = m->getline(in); m->gobble(in);
76         vector<string> columnHeaders = m->splitWhiteSpace(headers);
77         if (columnHeaders.size() > 2) { hasGroups = true;   }
78         return hasGroups;
79     }
80         catch(exception& e) {
81                 m->errorOut(e, "CountTable", "readTable");
82                 exit(1);
83         }
84 }
85 /************************************************************/
86 int CountTable::createTable(string namefile, string groupfile, bool createGroup) {
87     try {
88         
89         if (namefile == "") { m->mothurOut("[ERROR]: namefile cannot be blank when creating a count table.\n"); m->control_pressed = true; }
90                                            
91         GroupMap* groupMap;
92         int numGroups = 0;
93         groups.clear();
94         totalGroups.clear();
95         indexGroupMap.clear();
96         indexNameMap.clear();
97         counts.clear();
98         map<int, string> originalGroupIndexes;
99         
100         if (groupfile != "") { 
101             hasGroups = true;
102             groupMap = new GroupMap(groupfile); groupMap->readMap();
103             numGroups = groupMap->getNumGroups();
104             groups = groupMap->getNamesOfGroups();
105             totalGroups.resize(numGroups, 0);
106         }else if(createGroup) {
107             hasGroups = true;
108             numGroups = 1;
109             groups.push_back("Group1");
110             totalGroups.resize(numGroups, 0);
111         }
112                 //sort groups to keep consistent with how we store the groups in groupmap
113         sort(groups.begin(), groups.end());
114         for (int i = 0; i < groups.size(); i++) {  indexGroupMap[groups[i]] = i; }
115         m->setAllGroups(groups);
116         
117         bool error = false;
118         string name;
119         uniques = 0;
120         total = 0;
121         
122         
123         //open input file
124         ifstream in;
125         m->openInputFile(namefile, in);
126         
127         int total = 0;
128         while (!in.eof()) {
129             if (m->control_pressed) { break; }
130             
131             string firstCol, secondCol;
132             in >> firstCol; m->gobble(in); in >> secondCol; m->gobble(in);
133             
134             m->checkName(firstCol);
135             m->checkName(secondCol);
136             
137             vector<string> names;
138             m->splitAtChar(secondCol, names, ',');
139             
140             map<string, int> groupCounts;
141             int thisTotal = 0;
142             if (groupfile != "") {
143                 //set to 0
144                 for (int i = 0; i < groups.size(); i++) { groupCounts[groups[i]] = 0; }
145                 
146                 //get counts for each of the users groups
147                 for (int i = 0; i < names.size(); i++) {
148                     string group = groupMap->getGroup(names[i]);
149                     
150                     if (group == "not found") { m->mothurOut("[ERROR]: " + names[i] + " is not in your groupfile, please correct."); m->mothurOutEndLine(); error=true; }
151                     else {
152                         map<string, int>::iterator it = groupCounts.find(group);
153                         
154                         //if not found, then this sequence is not from a group we care about
155                         if (it != groupCounts.end()) {
156                             it->second++;
157                             thisTotal++;
158                         }
159                     }
160                 }
161             }else if (createGroup) {
162                 groupCounts["Group1"]=0;
163                 for (int i = 0; i < names.size(); i++) {
164                     string group = "Group1";
165                     groupCounts["Group1"]++; thisTotal++;
166                 }
167             }else { thisTotal = names.size();  }
168             
169             //if group info, then read it
170             vector<int> thisGroupsCount; thisGroupsCount.resize(numGroups, 0);
171             for (int i = 0; i < numGroups; i++) {  
172                 thisGroupsCount[i] = groupCounts[groups[i]]; 
173                 totalGroups[i] += thisGroupsCount[i]; 
174             }
175             
176             map<string, int>::iterator it = indexNameMap.find(firstCol);
177             if (it == indexNameMap.end()) {
178                 if (hasGroups) {  counts.push_back(thisGroupsCount);  }
179                 indexNameMap[firstCol] = uniques;
180                 totals.push_back(thisTotal);
181                 total += thisTotal;
182                 uniques++;
183             }else {
184                 error = true;
185                 m->mothurOut("[ERROR]: Your count table contains more than 1 sequence named " + firstCol + ", sequence names must be unique. Please correct."); m->mothurOutEndLine(); 
186             }
187         }
188         in.close();
189                 
190         if (error) { m->control_pressed = true; }
191         else { //check for zero groups
192             if (hasGroups) {
193                 for (int i = 0; i < totalGroups.size(); i++) {
194                     if (totalGroups[i] == 0) { m->mothurOut("\nRemoving group: " + groups[i] + " because all sequences have been removed.\n"); removeGroup(groups[i]); i--; }
195                 }
196             }
197         }
198         if (groupfile != "") { delete groupMap; }
199         
200         return 0;
201     }
202         catch(exception& e) {
203                 m->errorOut(e, "CountTable", "createTable");
204                 exit(1);
205         }
206 }
207 /************************************************************/
208 int CountTable::readTable(string file) {
209     try {
210         filename = file;
211         ifstream in;
212         m->openInputFile(filename, in);
213         
214         string headers = m->getline(in); m->gobble(in);
215         vector<string> columnHeaders = m->splitWhiteSpace(headers);
216         
217         int numGroups = 0;
218         groups.clear();
219         totalGroups.clear();
220         indexGroupMap.clear();
221         indexNameMap.clear();
222         counts.clear();
223         map<int, string> originalGroupIndexes;
224         if (columnHeaders.size() > 2) { hasGroups = true; numGroups = columnHeaders.size() - 2;  }
225         for (int i = 2; i < columnHeaders.size(); i++) {  groups.push_back(columnHeaders[i]);  originalGroupIndexes[i-2] = columnHeaders[i]; totalGroups.push_back(0); }
226         //sort groups to keep consistent with how we store the groups in groupmap
227         sort(groups.begin(), groups.end());
228         for (int i = 0; i < groups.size(); i++) {  indexGroupMap[groups[i]] = i; }
229         m->setAllGroups(groups);
230         
231         bool error = false;
232         string name;
233         int thisTotal;
234         uniques = 0;
235         total = 0;
236         while (!in.eof()) {
237             
238             if (m->control_pressed) { break; }
239             
240             in >> name; m->gobble(in); in >> thisTotal; m->gobble(in);
241             if (m->debug) { m->mothurOut("[DEBUG]: " + name + '\t' + toString(thisTotal) + "\n"); }
242             
243             //if group info, then read it
244             vector<int> groupCounts; groupCounts.resize(numGroups, 0);
245             for (int i = 0; i < numGroups; i++) {  int thisIndex = indexGroupMap[originalGroupIndexes[i]]; in >> groupCounts[thisIndex]; m->gobble(in); totalGroups[thisIndex] += groupCounts[thisIndex];  }
246             
247             map<string, int>::iterator it = indexNameMap.find(name);
248             if (it == indexNameMap.end()) {
249                 if (hasGroups) {  counts.push_back(groupCounts);  }
250                 indexNameMap[name] = uniques;
251                 totals.push_back(thisTotal);
252                 total += thisTotal;
253                 uniques++;
254             }else {
255                 error = true;
256                 m->mothurOut("[ERROR]: Your count table contains more than 1 sequence named " + name + ", sequence names must be unique. Please correct."); m->mothurOutEndLine(); 
257             }
258         }
259         in.close();
260         
261         if (error) { m->control_pressed = true; }
262         else { //check for zero groups
263             if (hasGroups) {
264                 for (int i = 0; i < totalGroups.size(); i++) {
265                     if (totalGroups[i] == 0) { m->mothurOut("\nRemoving group: " + groups[i] + " because all sequences have been removed.\n"); removeGroup(groups[i]); i--; }
266                 }
267             }
268         }
269         
270         return 0;
271     }
272         catch(exception& e) {
273                 m->errorOut(e, "CountTable", "readTable");
274                 exit(1);
275         }
276 }
277 /************************************************************/
278 int CountTable::printTable(string file) {
279     try {
280         ofstream out;
281         m->openOutputFile(file, out); 
282                 out << "Representative_Sequence\ttotal\t";
283         for (int i = 0; i < groups.size(); i++) { out << groups[i] << '\t'; }
284         out << endl;
285         
286         map<int, string> reverse; //use this to preserve order
287         for (map<string, int>::iterator it = indexNameMap.begin(); it !=indexNameMap.end(); it++) { reverse[it->second] = it->first;  }
288         
289         for (int i = 0; i < totals.size(); i++) {
290             map<int, string>::iterator itR = reverse.find(i);
291             
292             if (itR != reverse.end()) { //will equal end if seqs were removed because remove just removes from indexNameMap
293                 out << itR->second << '\t' << totals[i] << '\t';
294                 if (hasGroups) {
295                     for (int j = 0; j < groups.size(); j++) {
296                         out << counts[i][j] << '\t';
297                     }
298                 }
299                 out << endl;
300             }
301         }
302         /*for (map<string, int>::iterator itNames = indexNameMap.begin(); itNames != indexNameMap.end(); itNames++) {
303             out << itNames->first << '\t' << totals[itNames->second] << '\t';
304             if (hasGroups) {
305                 
306                 for (int i = 0; i < groups.size(); i++) {
307                     out << counts[itNames->second][i] << '\t';
308                 }
309             }
310             out << endl;
311         }*/
312         out.close();
313         return 0;
314     }
315         catch(exception& e) {
316                 m->errorOut(e, "CountTable", "printTable");
317                 exit(1);
318         }
319 }
320 /************************************************************/
321 int CountTable::printHeaders(ofstream& out) {
322     try {
323                 out << "Representative_Sequence\ttotal\t";
324         for (int i = 0; i < groups.size(); i++) { out << groups[i] << '\t'; }
325         out << endl;
326         return 0;
327     }
328         catch(exception& e) {
329                 m->errorOut(e, "CountTable", "printHeaders");
330                 exit(1);
331         }
332 }
333 /************************************************************/
334 int CountTable::printSeq(ofstream& out, string seqName) {
335     try {
336                 map<string, int>::iterator it = indexNameMap.find(seqName);
337         if (it == indexNameMap.end()) {
338             m->mothurOut("[ERROR]: " + seqName + " is not in your count table. Please correct.\n"); m->control_pressed = true;
339         }else { 
340             out << it->first << '\t' << totals[it->second] << '\t';
341             if (hasGroups) {
342                 for (int i = 0; i < groups.size(); i++) {
343                     out << counts[it->second][i] << '\t';
344                 }
345             }
346             out << endl;
347         }
348         return 0;
349     }
350         catch(exception& e) {
351                 m->errorOut(e, "CountTable", "printSeq");
352                 exit(1);
353         }
354 }
355 /************************************************************/
356 //group counts for a seq
357 vector<int> CountTable::getGroupCounts(string seqName) {
358     try {
359         vector<int> temp;
360         if (hasGroups) {
361             map<string, int>::iterator it = indexNameMap.find(seqName);
362             if (it == indexNameMap.end()) {
363                 m->mothurOut("[ERROR]: " + seqName + " is not in your count table. Please correct.\n"); m->control_pressed = true;
364             }else { 
365                 temp = counts[it->second];
366             }
367         }else{  m->mothurOut("[ERROR]: Your count table does not have group info. Please correct.\n"); m->control_pressed = true; }
368         
369         return temp;
370     }
371         catch(exception& e) {
372                 m->errorOut(e, "CountTable", "getGroupCounts");
373                 exit(1);
374         }
375 }
376 /************************************************************/
377 //total number of sequences for the group
378 int CountTable::getGroupCount(string groupName) {
379     try {
380         if (hasGroups) {
381             map<string, int>::iterator it = indexGroupMap.find(groupName);
382             if (it == indexGroupMap.end()) {
383                 m->mothurOut("[ERROR]: group " + groupName + " is not in your count table. Please correct.\n"); m->control_pressed = true;
384             }else { 
385                 return totalGroups[it->second];
386             }
387         }else{  m->mothurOut("[ERROR]: Your count table does not have group info. Please correct.\n");  m->control_pressed = true; }
388
389         return 0;
390     }
391         catch(exception& e) {
392                 m->errorOut(e, "CountTable", "getGroupCount");
393                 exit(1);
394         }
395 }
396 /************************************************************/
397 //total number of sequences for the seq for the group
398 int CountTable::getGroupCount(string seqName, string groupName) {
399     try {
400         if (hasGroups) {
401             map<string, int>::iterator it = indexGroupMap.find(groupName);
402             if (it == indexGroupMap.end()) {
403                 m->mothurOut("[ERROR]: group " + groupName + " is not in your count table. Please correct.\n"); m->control_pressed = true;
404             }else { 
405                 map<string, int>::iterator it2 = indexNameMap.find(seqName);
406                 if (it2 == indexNameMap.end()) {
407                     m->mothurOut("[ERROR]: seq " + seqName + " is not in your count table. Please correct.\n"); m->control_pressed = true;
408                 }else { 
409                     return counts[it2->second][it->second];
410                 }
411             }
412         }else{  m->mothurOut("[ERROR]: Your count table does not have group info. Please correct.\n");  m->control_pressed = true; }
413         
414         return 0;
415     }
416         catch(exception& e) {
417                 m->errorOut(e, "CountTable", "getGroupCount");
418                 exit(1);
419         }
420 }
421 /************************************************************/
422 //set the number of sequences for the seq for the group
423 int CountTable::setAbund(string seqName, string groupName, int num) {
424     try {
425         if (hasGroups) {
426             map<string, int>::iterator it = indexGroupMap.find(groupName);
427             if (it == indexGroupMap.end()) {
428                 m->mothurOut("[ERROR]: " + groupName + " is not in your count table. Please correct.\n"); m->control_pressed = true;
429             }else { 
430                 map<string, int>::iterator it2 = indexNameMap.find(seqName);
431                 if (it2 == indexNameMap.end()) {
432                     m->mothurOut("[ERROR]: " + seqName + " is not in your count table. Please correct.\n"); m->control_pressed = true;
433                 }else { 
434                     int oldCount = counts[it2->second][it->second];
435                     counts[it2->second][it->second] = num;
436                     totalGroups[it->second] += (num - oldCount);
437                     total += (num - oldCount);
438                     totals[it2->second] += (num - oldCount);
439                 }
440             }
441         }else{  m->mothurOut("[ERROR]: Your count table does not have group info. Please correct.\n");  m->control_pressed = true; }
442         
443         return 0;
444     }
445         catch(exception& e) {
446                 m->errorOut(e, "CountTable", "set");
447                 exit(1);
448         }
449 }
450 /************************************************************/
451 //add group
452 int CountTable::addGroup(string groupName) {
453     try {        
454         bool sanity = m->inUsersGroups(groupName, groups);
455         if (sanity) { m->mothurOut("[ERROR]: " + groupName + " is already in the count table, cannot add again.\n"); m->control_pressed = true;  return 0; }
456         
457         groups.push_back(groupName);
458         if (!hasGroups) { counts.resize(uniques);  }
459         
460         for (int i = 0; i < counts.size(); i++) { counts[i].push_back(0); }
461         totalGroups.push_back(0);
462         indexGroupMap[groupName] = groups.size()-1;
463         map<string, int> originalGroupMap = indexGroupMap;
464         
465         //important to play well with others, :)
466         sort(groups.begin(), groups.end());
467         
468         //fix indexGroupMap && totalGroups
469         vector<int> newTotals; newTotals.resize(groups.size(), 0);
470         for (int i = 0; i < groups.size(); i++) {  
471             indexGroupMap[groups[i]] = i;  
472             //find original spot of group[i]
473             int index = originalGroupMap[groups[i]];
474             newTotals[i] = totalGroups[index];
475         }
476         totalGroups = newTotals;
477         
478         //fix counts vectors
479         for (int i = 0; i < counts.size(); i++) {
480             vector<int> newCounts; newCounts.resize(groups.size(), 0);
481             for (int j = 0; j < groups.size(); j++) {  
482                 //find original spot of group[i]
483                 int index = originalGroupMap[groups[j]];
484                 newCounts[j] = counts[i][index];
485             }
486             counts[i] = newCounts;
487         }
488         hasGroups = true;
489         m->setAllGroups(groups);
490         
491         return 0;
492     }
493         catch(exception& e) {
494                 m->errorOut(e, "CountTable", "addGroup");
495                 exit(1);
496         }
497 }
498 /************************************************************/
499 //remove group
500 int CountTable::removeGroup(string groupName) {
501     try {        
502         if (hasGroups) {
503             //save for later in case removing a group means we need to remove a seq.
504             map<int, string> reverse;
505             for (map<string, int>::iterator it = indexNameMap.begin(); it !=indexNameMap.end(); it++) { reverse[it->second] = it->first;  }
506             
507             map<string, int>::iterator it = indexGroupMap.find(groupName);
508             if (it == indexGroupMap.end()) {
509                 m->mothurOut("[ERROR]: " + groupName + " is not in your count table. Please correct.\n"); m->control_pressed = true;
510             }else { 
511                 int indexOfGroupToRemove = it->second;
512                 map<string, int> currentGroupIndex = indexGroupMap;
513                 vector<string> newGroups;
514                 for (int i = 0; i < groups.size(); i++) {
515                     if (groups[i] != groupName) { 
516                         newGroups.push_back(groups[i]);
517                         indexGroupMap[groups[i]] = newGroups.size()-1;
518                     }
519                 }
520                 indexGroupMap.erase(groupName);
521                 groups = newGroups;
522                 totalGroups.erase(totalGroups.begin()+indexOfGroupToRemove);
523                 
524                 int thisIndex = 0;
525                 map<string, int> newIndexNameMap;
526                 for (int i = 0; i < counts.size(); i++) {
527                     int num = counts[i][indexOfGroupToRemove];
528                     counts[i].erase(counts[i].begin()+indexOfGroupToRemove);
529                     totals[i] -= num;
530                     total -= num;
531                     if (totals[i] == 0) { //your sequences are only from the group we want to remove, then remove you.
532                         counts.erase(counts.begin()+i);
533                         totals.erase(totals.begin()+i);
534                         uniques--;
535                         i--;
536                     }
537                     newIndexNameMap[reverse[thisIndex]] = i;
538                     thisIndex++;
539                 }
540                 indexNameMap = newIndexNameMap;
541                 
542                 if (groups.size() == 0) { hasGroups = false; }
543             }
544         }else { m->mothurOut("[ERROR]: your count table does not contain group information, can not remove group " + groupName + ".\n"); m->control_pressed = true; }
545     
546         return 0;
547     }
548         catch(exception& e) {
549                 m->errorOut(e, "CountTable", "removeGroup");
550                 exit(1);
551         }
552 }
553 /************************************************************/
554 //vector of groups for the seq
555 vector<string> CountTable::getGroups(string seqName) {
556     try {
557         vector<string> thisGroups;
558         if (hasGroups) {
559             vector<int> thisCounts = getGroupCounts(seqName);
560             for (int i = 0; i < thisCounts.size(); i++) {  
561                 if (thisCounts[i] != 0) {  thisGroups.push_back(groups[i]); }
562             } 
563         }else{  m->mothurOut("[ERROR]: Your count table does not have group info. Please correct.\n");  m->control_pressed = true; }
564         
565         return thisGroups;
566     }
567         catch(exception& e) {
568                 m->errorOut(e, "CountTable", "getGroups");
569                 exit(1);
570         }
571 }
572 /************************************************************/
573 //total number of seqs represented by seq
574 int CountTable::renameSeq(string oldSeqName, string newSeqName) {
575     try {
576         
577         map<string, int>::iterator it = indexNameMap.find(oldSeqName);
578         if (it == indexNameMap.end()) {
579             m->mothurOut("[ERROR]: " + oldSeqName + " is not in your count table. Please correct.\n"); m->control_pressed = true;
580         }else {  
581             int index = it->second;
582             indexNameMap.erase(it);
583             indexNameMap[newSeqName] = index;
584         }
585         
586         return 0;
587     }
588         catch(exception& e) {
589                 m->errorOut(e, "CountTable", "renameSeq");
590                 exit(1);
591         }
592 }
593
594 /************************************************************/
595 //total number of seqs represented by seq
596 int CountTable::getNumSeqs(string seqName) {
597     try {
598                 
599         map<string, int>::iterator it = indexNameMap.find(seqName);
600         if (it == indexNameMap.end()) {
601             m->mothurOut("[ERROR]: " + seqName + " is not in your count table. Please correct.\n"); m->control_pressed = true;
602         }else { 
603             return totals[it->second];
604         }
605
606         return 0;
607     }
608         catch(exception& e) {
609                 m->errorOut(e, "CountTable", "getNumSeqs");
610                 exit(1);
611         }
612 }
613 /************************************************************/
614 //returns unique index for sequence like get in NameAssignment
615 int CountTable::get(string seqName) {
616     try {
617         
618         map<string, int>::iterator it = indexNameMap.find(seqName);
619         if (it == indexNameMap.end()) {
620             m->mothurOut("[ERROR]: " + seqName + " is not in your count table. Please correct.\n"); m->control_pressed = true;
621         }else { return it->second; }
622         
623         return -1;
624     }
625         catch(exception& e) {
626                 m->errorOut(e, "CountTable", "get");
627                 exit(1);
628         }
629 }
630 /************************************************************/
631 //add seqeunce without group info
632 int CountTable::push_back(string seqName) {
633     try {
634         map<string, int>::iterator it = indexNameMap.find(seqName);
635         if (it == indexNameMap.end()) {
636             if (hasGroups) {  m->mothurOut("[ERROR]: Your count table has groups and I have no group information for " + seqName + "."); m->mothurOutEndLine(); m->control_pressed = true;  }
637             indexNameMap[seqName] = uniques;
638             totals.push_back(1);
639             total++;
640             uniques++;
641         }else {
642             m->mothurOut("[ERROR]: Your count table contains more than 1 sequence named " + seqName + ", sequence names must be unique. Please correct."); m->mothurOutEndLine(); m->control_pressed = true;
643         }
644         
645         return 0;
646     }
647         catch(exception& e) {
648                 m->errorOut(e, "CountTable", "push_back");
649                 exit(1);
650         }
651 }
652 /************************************************************/
653 //remove sequence
654 int CountTable::remove(string seqName) {
655     try {
656         map<string, int>::iterator it = indexNameMap.find(seqName);
657         if (it != indexNameMap.end()) {
658             uniques--;
659             if (hasGroups){ //remove this sequences counts from group totals
660                 for (int i = 0; i < totalGroups.size(); i++) {  totalGroups[i] -= counts[it->second][i];  counts[it->second][i] = 0; }
661             }
662             int thisTotal = totals[it->second]; totals[it->second] = 0;
663             total -= thisTotal;
664             indexNameMap.erase(it);
665         }else {
666             m->mothurOut("[ERROR]: Your count table contains does not include " + seqName + ", cannot remove."); m->mothurOutEndLine(); m->control_pressed = true;
667         }
668         
669         return 0;
670     }
671         catch(exception& e) {
672                 m->errorOut(e, "CountTable", "push_back");
673                 exit(1);
674         }
675 }
676 /************************************************************/
677 //add seqeunce without group info
678 int CountTable::push_back(string seqName, int thisTotal) {
679     try {
680         map<string, int>::iterator it = indexNameMap.find(seqName);
681         if (it == indexNameMap.end()) {
682             if (hasGroups) {  m->mothurOut("[ERROR]: Your count table has groups and I have no group information for " + seqName + "."); m->mothurOutEndLine(); m->control_pressed = true;  }
683             indexNameMap[seqName] = uniques;
684             totals.push_back(thisTotal);
685             total+=thisTotal;
686             uniques++;
687         }else {
688             m->mothurOut("[ERROR]: Your count table contains more than 1 sequence named " + seqName + ", sequence names must be unique. Please correct."); m->mothurOutEndLine(); m->control_pressed = true;
689         }
690         
691         return 0;
692     }
693         catch(exception& e) {
694                 m->errorOut(e, "CountTable", "push_back");
695                 exit(1);
696         }
697 }
698 /************************************************************/
699 //add sequence with group info
700 int CountTable::push_back(string seqName, vector<int> groupCounts) {
701     try {
702         map<string, int>::iterator it = indexNameMap.find(seqName);
703         if (it == indexNameMap.end()) {
704             if ((hasGroups) && (groupCounts.size() != getNumGroups())) {  m->mothurOut("[ERROR]: Your count table has a " + toString(getNumGroups()) + " groups and " + seqName + " has " + toString(groupCounts.size()) + ", please correct."); m->mothurOutEndLine(); m->control_pressed = true;  }
705             int thisTotal = 0;
706             for (int i = 0; i < getNumGroups(); i++) {   totalGroups[i] += groupCounts[i];  thisTotal += groupCounts[i]; }
707             if (hasGroups) {  counts.push_back(groupCounts);  }
708             indexNameMap[seqName] = uniques;
709             totals.push_back(thisTotal);
710             total+= thisTotal;
711             uniques++;
712         }else {
713             m->mothurOut("[ERROR]: Your count table contains more than 1 sequence named " + seqName + ", sequence names must be unique. Please correct."); m->mothurOutEndLine(); m->control_pressed = true;
714         }
715         
716         return 0;
717     }
718         catch(exception& e) {
719                 m->errorOut(e, "CountTable", "push_back");
720                 exit(1);
721         }
722 }
723
724 /************************************************************/
725 //create ListVector from uniques
726 ListVector CountTable::getListVector() {
727     try {
728         ListVector list(indexNameMap.size());
729         for (map<string, int>::iterator it = indexNameMap.begin(); it != indexNameMap.end(); it++) { 
730             if (m->control_pressed) { break; }
731             list.set(it->second, it->first); 
732         }
733         return list;
734     }
735         catch(exception& e) {
736                 m->errorOut(e, "CountTable", "getListVector");
737                 exit(1);
738         }
739 }
740
741 /************************************************************/
742 //returns the names of all unique sequences in file
743 vector<string> CountTable::getNamesOfSeqs() {
744     try {
745         vector<string> names;
746         for (map<string, int>::iterator it = indexNameMap.begin(); it != indexNameMap.end(); it++) {
747             names.push_back(it->first);
748         }
749                 
750         return names;
751     }
752         catch(exception& e) {
753                 m->errorOut(e, "CountTable", "getNamesOfSeqs");
754                 exit(1);
755         }
756 }
757 /************************************************************/
758 //returns the names of all unique sequences in file mapped to their seqCounts
759 map<string, int> CountTable::getNameMap() {
760     try {
761         map<string, int> names;
762         for (map<string, int>::iterator it = indexNameMap.begin(); it != indexNameMap.end(); it++) {
763             names[it->first] = totals[it->second];
764         }
765         
766         return names;
767     }
768         catch(exception& e) {
769                 m->errorOut(e, "CountTable", "getNameMap");
770                 exit(1);
771         }
772 }
773 /************************************************************/
774 //returns the names of all unique sequences in file
775 vector<string> CountTable::getNamesOfSeqs(string group) {
776     try {
777         vector<string> names;
778         if (hasGroups) {
779             map<string, int>::iterator it = indexGroupMap.find(group);
780             if (it == indexGroupMap.end()) {
781                 m->mothurOut("[ERROR]: " + group + " is not in your count table. Please correct.\n"); m->control_pressed = true;
782             }else { 
783                 for (map<string, int>::iterator it2 = indexNameMap.begin(); it2 != indexNameMap.end(); it2++) {
784                     if (counts[it2->second][it->second] != 0) {  names.push_back(it2->first); }
785                 }
786             }
787         }else{  m->mothurOut("[ERROR]: Your count table does not have group info. Please correct.\n");  m->control_pressed = true; }
788         
789         return names;
790     }
791         catch(exception& e) {
792                 m->errorOut(e, "CountTable", "getNamesOfSeqs");
793                 exit(1);
794         }
795 }
796 /************************************************************/
797 //merges counts of seq1 and seq2, saving in seq1
798 int CountTable::mergeCounts(string seq1, string seq2) {
799     try {
800         map<string, int>::iterator it = indexNameMap.find(seq1);
801         if (it == indexNameMap.end()) {
802             m->mothurOut("[ERROR]: " + seq1 + " is not in your count table. Please correct.\n"); m->control_pressed = true;
803         }else { 
804             map<string, int>::iterator it2 = indexNameMap.find(seq2);
805             if (it2 == indexNameMap.end()) {
806                 m->mothurOut("[ERROR]: " + seq2 + " is not in your count table. Please correct.\n"); m->control_pressed = true;
807             }else { 
808                 //merge data
809                 for (int i = 0; i < groups.size(); i++) { counts[it->second][i] += counts[it2->second][i]; }
810                 totals[it->second] += totals[it2->second];
811                 uniques--;
812                 indexNameMap.erase(it2); 
813             }
814         }
815         return 0;
816     }
817         catch(exception& e) {
818                 m->errorOut(e, "CountTable", "getNamesOfSeqs");
819                 exit(1);
820         }
821 }
822 /************************************************************/
823 int CountTable::copy(CountTable* ct) {
824     try {
825         vector<string> thisGroups = ct->getNamesOfGroups();
826         for (int i = 0; i < thisGroups.size(); i++) { addGroup(thisGroups[i]); }
827         vector<string> names = ct->getNamesOfSeqs();
828                                                                
829         for (int i = 0; i < names.size(); i++) {
830             vector<int> thisCounts = ct->getGroupCounts(names[i]);
831             push_back(names[i], thisCounts);
832         }
833                                                                
834         return 0;
835     }
836         catch(exception& e) {
837                 m->errorOut(e, "CountTable", "copy");
838                 exit(1);
839         }
840 }
841
842 /************************************************************/
843
844