]> 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 /************************************************************/
13 int CountTable::readTable(string file) {
14     try {
15         filename = file;
16         ifstream in;
17         m->openInputFile(filename, in);
18         
19         string headers = m->getline(in); m->gobble(in);
20         vector<string> columnHeaders = m->splitWhiteSpace(headers);
21         
22         int numGroups = 0;
23         groups.clear();
24         totalGroups.clear();
25         indexGroupMap.clear();
26         indexNameMap.clear();
27         counts.clear();
28         map<int, string> originalGroupIndexes;
29         if (columnHeaders.size() > 2) { hasGroups = true; numGroups = columnHeaders.size() - 2;  }
30         for (int i = 2; i < columnHeaders.size(); i++) {  groups.push_back(columnHeaders[i]);  originalGroupIndexes[i-2] = columnHeaders[i]; totalGroups.push_back(0); }
31         //sort groups to keep consistent with how we store the groups in groupmap
32         sort(groups.begin(), groups.end());
33         for (int i = 0; i < groups.size(); i++) {  indexGroupMap[groups[i]] = i; }
34         m->setAllGroups(groups);
35         
36         bool error = false;
37         string name;
38         int thisTotal;
39         uniques = 0;
40         total = 0;
41         while (!in.eof()) {
42             
43             if (m->control_pressed) { break; }
44             
45             in >> name; m->gobble(in); in >> thisTotal; m->gobble(in);
46             if (m->debug) { m->mothurOut("[DEBUG]: " + name + '\t' + toString(thisTotal) + "\n"); }
47             
48             //if group info, then read it
49             vector<int> groupCounts; groupCounts.resize(numGroups, 0);
50             for (int i = 0; i < numGroups; i++) {  int thisIndex = indexGroupMap[originalGroupIndexes[i]]; in >> groupCounts[thisIndex]; m->gobble(in); totalGroups[thisIndex] += groupCounts[thisIndex];  }
51             
52             map<string, int>::iterator it = indexNameMap.find(name);
53             if (it == indexNameMap.end()) {
54                 if (hasGroups) {  counts.push_back(groupCounts);  }
55                 indexNameMap[name] = uniques;
56                 totals.push_back(thisTotal);
57                 total += thisTotal;
58                 uniques++;
59             }else {
60                 error = true;
61                 m->mothurOut("[ERROR]: Your count table contains more than 1 sequence named " + name + ", sequence names must be unique. Please correct."); m->mothurOutEndLine(); 
62             }
63         }
64         in.close();
65         
66         if (error) { m->control_pressed = true; }
67         
68         return 0;
69     }
70         catch(exception& e) {
71                 m->errorOut(e, "CountTable", "readTable");
72                 exit(1);
73         }
74 }
75 /************************************************************/
76 //group counts for a seq
77 vector<int> CountTable::getGroupCounts(string seqName) {
78     try {
79         vector<int> temp;
80         if (hasGroups) {
81             map<string, int>::iterator it = indexNameMap.find(seqName);
82             if (it == indexNameMap.end()) {
83                 m->mothurOut("[ERROR]: " + seqName + " is not in your count table. Please correct.\n"); m->control_pressed = true;
84             }else { 
85                 temp = counts[it->second];
86             }
87         }else{  m->mothurOut("[ERROR]: Your count table does not have group info. Please correct.\n"); m->control_pressed = true; }
88         
89         return temp;
90     }
91         catch(exception& e) {
92                 m->errorOut(e, "CountTable", "getGroupCounts");
93                 exit(1);
94         }
95 }
96 /************************************************************/
97 //total number of sequences for the group
98 int CountTable::getGroupCount(string groupName) {
99     try {
100         if (hasGroups) {
101             map<string, int>::iterator it = indexGroupMap.find(groupName);
102             if (it == indexGroupMap.end()) {
103                 m->mothurOut("[ERROR]: " + groupName + " is not in your count table. Please correct.\n"); m->control_pressed = true;
104             }else { 
105                 return totalGroups[it->second];
106             }
107         }else{  m->mothurOut("[ERROR]: Your count table does not have group info. Please correct.\n");  m->control_pressed = true; }
108
109         return 0;
110     }
111         catch(exception& e) {
112                 m->errorOut(e, "CountTable", "getGroupCount");
113                 exit(1);
114         }
115 }
116 /************************************************************/
117 //total number of sequences for the seq for the group
118 int CountTable::getGroupCount(string seqName, string groupName) {
119     try {
120         if (hasGroups) {
121             map<string, int>::iterator it = indexGroupMap.find(groupName);
122             if (it == indexGroupMap.end()) {
123                 m->mothurOut("[ERROR]: " + groupName + " is not in your count table. Please correct.\n"); m->control_pressed = true;
124             }else { 
125                 map<string, int>::iterator it2 = indexNameMap.find(seqName);
126                 if (it2 == indexNameMap.end()) {
127                     m->mothurOut("[ERROR]: " + seqName + " is not in your count table. Please correct.\n"); m->control_pressed = true;
128                 }else { 
129                     return counts[it2->second][it->second];
130                 }
131             }
132         }else{  m->mothurOut("[ERROR]: Your count table does not have group info. Please correct.\n");  m->control_pressed = true; }
133         
134         return 0;
135     }
136         catch(exception& e) {
137                 m->errorOut(e, "CountTable", "getGroupCount");
138                 exit(1);
139         }
140 }
141 /************************************************************/
142 //total number of seqs represented by seq
143 int CountTable::getNumSeqs(string seqName) {
144     try {
145                 
146         map<string, int>::iterator it = indexNameMap.find(seqName);
147         if (it == indexNameMap.end()) {
148             m->mothurOut("[ERROR]: " + seqName + " is not in your count table. Please correct.\n"); m->control_pressed = true;
149         }else { 
150             return totals[it->second];
151         }
152
153         return 0;
154     }
155         catch(exception& e) {
156                 m->errorOut(e, "CountTable", "getNumSeqs");
157                 exit(1);
158         }
159 }
160 /************************************************************/
161 //returns unique index for sequence like get in NameAssignment
162 int CountTable::get(string seqName) {
163     try {
164         
165         map<string, int>::iterator it = indexNameMap.find(seqName);
166         if (it == indexNameMap.end()) {
167             m->mothurOut("[ERROR]: " + seqName + " is not in your count table. Please correct.\n"); m->control_pressed = true;
168         }else { return it->second; }
169         
170         return -1;
171     }
172         catch(exception& e) {
173                 m->errorOut(e, "CountTable", "get");
174                 exit(1);
175         }
176 }
177 /************************************************************/
178 //create ListVector from uniques
179 ListVector CountTable::getListVector() {
180     try {
181         ListVector list(indexNameMap.size());
182         for (map<string, int>::iterator it = indexNameMap.begin(); it != indexNameMap.end(); it++) { 
183             if (m->control_pressed) { break; }
184             list.set(it->second, it->first); 
185         }
186         return list;
187     }
188         catch(exception& e) {
189                 m->errorOut(e, "CountTable", "getListVector");
190                 exit(1);
191         }
192 }
193
194 /************************************************************/
195 //returns the names of all unique sequences in file
196 vector<string> CountTable::getNamesOfSeqs() {
197     try {
198         vector<string> names;
199         for (map<string, int>::iterator it = indexNameMap.begin(); it != indexNameMap.end(); it++) {
200             names.push_back(it->first);
201         }
202                 
203         return names;
204     }
205         catch(exception& e) {
206                 m->errorOut(e, "CountTable", "getNamesOfSeqs");
207                 exit(1);
208         }
209 }
210 /************************************************************/
211 //returns names of seqs
212 int CountTable::mergeCounts(string seq1, string seq2) {
213     try {
214         map<string, int>::iterator it = indexNameMap.find(seq1);
215         if (it == indexNameMap.end()) {
216             m->mothurOut("[ERROR]: " + seq1 + " is not in your count table. Please correct.\n"); m->control_pressed = true;
217         }else { 
218             map<string, int>::iterator it2 = indexNameMap.find(seq2);
219             if (it2 == indexNameMap.end()) {
220                 m->mothurOut("[ERROR]: " + seq2 + " is not in your count table. Please correct.\n"); m->control_pressed = true;
221             }else { 
222                 //merge data
223                 for (int i = 0; i < groups.size(); i++) {
224                     counts[it->second][i] += counts[it2->second][i];
225                     counts[it2->second][i] = 0;
226                 }
227                 totals[it->second] += totals[it2->second];
228                 totals[it2->second] = 0;
229                 uniques--;
230                 indexNameMap.erase(it2); 
231             }
232         }
233         
234         return 0;
235     }
236         catch(exception& e) {
237                 m->errorOut(e, "CountTable", "getNamesOfSeqs");
238                 exit(1);
239         }
240 }
241
242 /************************************************************/
243
244