]> git.donarmstrong.com Git - mothur.git/blob - counttable.cpp
added count parameter to chimera.slayer command
[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 bool CountTable::testGroups(string file) {
13     try {
14         m = MothurOut::getInstance(); hasGroups = false; total = 0;
15         ifstream in;
16         m->openInputFile(file, in);
17     
18         string headers = m->getline(in); m->gobble(in);
19         vector<string> columnHeaders = m->splitWhiteSpace(headers);
20         if (columnHeaders.size() > 2) { hasGroups = true;   }
21         return hasGroups;
22     }
23         catch(exception& e) {
24                 m->errorOut(e, "CountTable", "readTable");
25                 exit(1);
26         }
27 }
28 /************************************************************/
29 int CountTable::readTable(string file) {
30     try {
31         filename = file;
32         ifstream in;
33         m->openInputFile(filename, in);
34         
35         string headers = m->getline(in); m->gobble(in);
36         vector<string> columnHeaders = m->splitWhiteSpace(headers);
37         
38         int numGroups = 0;
39         groups.clear();
40         totalGroups.clear();
41         indexGroupMap.clear();
42         indexNameMap.clear();
43         counts.clear();
44         map<int, string> originalGroupIndexes;
45         if (columnHeaders.size() > 2) { hasGroups = true; numGroups = columnHeaders.size() - 2;  }
46         for (int i = 2; i < columnHeaders.size(); i++) {  groups.push_back(columnHeaders[i]);  originalGroupIndexes[i-2] = columnHeaders[i]; totalGroups.push_back(0); }
47         //sort groups to keep consistent with how we store the groups in groupmap
48         sort(groups.begin(), groups.end());
49         for (int i = 0; i < groups.size(); i++) {  indexGroupMap[groups[i]] = i; }
50         m->setAllGroups(groups);
51         
52         bool error = false;
53         string name;
54         int thisTotal;
55         uniques = 0;
56         total = 0;
57         while (!in.eof()) {
58             
59             if (m->control_pressed) { break; }
60             
61             in >> name; m->gobble(in); in >> thisTotal; m->gobble(in);
62             if (m->debug) { m->mothurOut("[DEBUG]: " + name + '\t' + toString(thisTotal) + "\n"); }
63             
64             //if group info, then read it
65             vector<int> groupCounts; groupCounts.resize(numGroups, 0);
66             for (int i = 0; i < numGroups; i++) {  int thisIndex = indexGroupMap[originalGroupIndexes[i]]; in >> groupCounts[thisIndex]; m->gobble(in); totalGroups[thisIndex] += groupCounts[thisIndex];  }
67             
68             map<string, int>::iterator it = indexNameMap.find(name);
69             if (it == indexNameMap.end()) {
70                 if (hasGroups) {  counts.push_back(groupCounts);  }
71                 indexNameMap[name] = uniques;
72                 totals.push_back(thisTotal);
73                 total += thisTotal;
74                 uniques++;
75             }else {
76                 error = true;
77                 m->mothurOut("[ERROR]: Your count table contains more than 1 sequence named " + name + ", sequence names must be unique. Please correct."); m->mothurOutEndLine(); 
78             }
79         }
80         in.close();
81         
82         if (error) { m->control_pressed = true; }
83         
84         return 0;
85     }
86         catch(exception& e) {
87                 m->errorOut(e, "CountTable", "readTable");
88                 exit(1);
89         }
90 }
91 /************************************************************/
92 //group counts for a seq
93 vector<int> CountTable::getGroupCounts(string seqName) {
94     try {
95         vector<int> temp;
96         if (hasGroups) {
97             map<string, int>::iterator it = indexNameMap.find(seqName);
98             if (it == indexNameMap.end()) {
99                 m->mothurOut("[ERROR]: " + seqName + " is not in your count table. Please correct.\n"); m->control_pressed = true;
100             }else { 
101                 temp = counts[it->second];
102             }
103         }else{  m->mothurOut("[ERROR]: Your count table does not have group info. Please correct.\n"); m->control_pressed = true; }
104         
105         return temp;
106     }
107         catch(exception& e) {
108                 m->errorOut(e, "CountTable", "getGroupCounts");
109                 exit(1);
110         }
111 }
112 /************************************************************/
113 //total number of sequences for the group
114 int CountTable::getGroupCount(string groupName) {
115     try {
116         if (hasGroups) {
117             map<string, int>::iterator it = indexGroupMap.find(groupName);
118             if (it == indexGroupMap.end()) {
119                 m->mothurOut("[ERROR]: " + groupName + " is not in your count table. Please correct.\n"); m->control_pressed = true;
120             }else { 
121                 return totalGroups[it->second];
122             }
123         }else{  m->mothurOut("[ERROR]: Your count table does not have group info. Please correct.\n");  m->control_pressed = true; }
124
125         return 0;
126     }
127         catch(exception& e) {
128                 m->errorOut(e, "CountTable", "getGroupCount");
129                 exit(1);
130         }
131 }
132 /************************************************************/
133 //total number of sequences for the seq for the group
134 int CountTable::getGroupCount(string seqName, string groupName) {
135     try {
136         if (hasGroups) {
137             map<string, int>::iterator it = indexGroupMap.find(groupName);
138             if (it == indexGroupMap.end()) {
139                 m->mothurOut("[ERROR]: " + groupName + " is not in your count table. Please correct.\n"); m->control_pressed = true;
140             }else { 
141                 map<string, int>::iterator it2 = indexNameMap.find(seqName);
142                 if (it2 == indexNameMap.end()) {
143                     m->mothurOut("[ERROR]: " + seqName + " is not in your count table. Please correct.\n"); m->control_pressed = true;
144                 }else { 
145                     return counts[it2->second][it->second];
146                 }
147             }
148         }else{  m->mothurOut("[ERROR]: Your count table does not have group info. Please correct.\n");  m->control_pressed = true; }
149         
150         return 0;
151     }
152         catch(exception& e) {
153                 m->errorOut(e, "CountTable", "getGroupCount");
154                 exit(1);
155         }
156 }
157 /************************************************************/
158 //total number of seqs represented by seq
159 int CountTable::getNumSeqs(string seqName) {
160     try {
161                 
162         map<string, int>::iterator it = indexNameMap.find(seqName);
163         if (it == indexNameMap.end()) {
164             m->mothurOut("[ERROR]: " + seqName + " is not in your count table. Please correct.\n"); m->control_pressed = true;
165         }else { 
166             return totals[it->second];
167         }
168
169         return 0;
170     }
171         catch(exception& e) {
172                 m->errorOut(e, "CountTable", "getNumSeqs");
173                 exit(1);
174         }
175 }
176 /************************************************************/
177 //returns unique index for sequence like get in NameAssignment
178 int CountTable::get(string seqName) {
179     try {
180         
181         map<string, int>::iterator it = indexNameMap.find(seqName);
182         if (it == indexNameMap.end()) {
183             m->mothurOut("[ERROR]: " + seqName + " is not in your count table. Please correct.\n"); m->control_pressed = true;
184         }else { return it->second; }
185         
186         return -1;
187     }
188         catch(exception& e) {
189                 m->errorOut(e, "CountTable", "get");
190                 exit(1);
191         }
192 }
193 /************************************************************/
194 //add seqeunce without group info
195 int CountTable::push_back(string seqName) {
196     try {
197         map<string, int>::iterator it = indexNameMap.find(seqName);
198         if (it == indexNameMap.end()) {
199             if (hasGroups) {  m->mothurOut("[ERROR]: Your count table has groups and I have no group information for " + seqName + "."); m->mothurOutEndLine(); m->control_pressed = true;  }
200             indexNameMap[seqName] = uniques;
201             totals.push_back(1);
202             total++;
203             uniques++;
204         }else {
205             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;
206         }
207         
208         return 0;
209     }
210         catch(exception& e) {
211                 m->errorOut(e, "CountTable", "push_back");
212                 exit(1);
213         }
214 }
215 /************************************************************/
216 //add seqeunce without group info
217 int CountTable::push_back(string seqName, int thisTotal) {
218     try {
219         map<string, int>::iterator it = indexNameMap.find(seqName);
220         if (it == indexNameMap.end()) {
221             if (hasGroups) {  m->mothurOut("[ERROR]: Your count table has groups and I have no group information for " + seqName + "."); m->mothurOutEndLine(); m->control_pressed = true;  }
222             indexNameMap[seqName] = uniques;
223             totals.push_back(thisTotal);
224             total+=thisTotal;
225             uniques++;
226         }else {
227             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;
228         }
229         
230         return 0;
231     }
232         catch(exception& e) {
233                 m->errorOut(e, "CountTable", "push_back");
234                 exit(1);
235         }
236 }
237 /************************************************************/
238 //add sequence with group info
239 int CountTable::push_back(string seqName, vector<int> groupCounts) {
240     try {
241         map<string, int>::iterator it = indexNameMap.find(seqName);
242         if (it == indexNameMap.end()) {
243             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;  }
244             int thisTotal = 0;
245             for (int i = 0; i < getNumGroups(); i++) {   totalGroups[i] += groupCounts[i];  thisTotal += groupCounts[i]; }
246             indexNameMap[seqName] = uniques;
247             totals.push_back(thisTotal);
248             total+= thisTotal;
249             uniques++;
250         }else {
251             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;
252         }
253         
254         return 0;
255     }
256         catch(exception& e) {
257                 m->errorOut(e, "CountTable", "push_back");
258                 exit(1);
259         }
260 }
261
262 /************************************************************/
263 //create ListVector from uniques
264 ListVector CountTable::getListVector() {
265     try {
266         ListVector list(indexNameMap.size());
267         for (map<string, int>::iterator it = indexNameMap.begin(); it != indexNameMap.end(); it++) { 
268             if (m->control_pressed) { break; }
269             list.set(it->second, it->first); 
270         }
271         return list;
272     }
273         catch(exception& e) {
274                 m->errorOut(e, "CountTable", "getListVector");
275                 exit(1);
276         }
277 }
278
279 /************************************************************/
280 //returns the names of all unique sequences in file
281 vector<string> CountTable::getNamesOfSeqs() {
282     try {
283         vector<string> names;
284         for (map<string, int>::iterator it = indexNameMap.begin(); it != indexNameMap.end(); it++) {
285             names.push_back(it->first);
286         }
287                 
288         return names;
289     }
290         catch(exception& e) {
291                 m->errorOut(e, "CountTable", "getNamesOfSeqs");
292                 exit(1);
293         }
294 }
295 /************************************************************/
296 //returns names of seqs
297 int CountTable::mergeCounts(string seq1, string seq2) {
298     try {
299         map<string, int>::iterator it = indexNameMap.find(seq1);
300         if (it == indexNameMap.end()) {
301             m->mothurOut("[ERROR]: " + seq1 + " is not in your count table. Please correct.\n"); m->control_pressed = true;
302         }else { 
303             map<string, int>::iterator it2 = indexNameMap.find(seq2);
304             if (it2 == indexNameMap.end()) {
305                 m->mothurOut("[ERROR]: " + seq2 + " is not in your count table. Please correct.\n"); m->control_pressed = true;
306             }else { 
307                 //merge data
308                 for (int i = 0; i < groups.size(); i++) {
309                     counts[it->second][i] += counts[it2->second][i];
310                     counts[it2->second][i] = 0;
311                 }
312                 totals[it->second] += totals[it2->second];
313                 totals[it2->second] = 0;
314                 uniques--;
315                 indexNameMap.erase(it2); 
316             }
317         }
318         
319         return 0;
320     }
321         catch(exception& e) {
322                 m->errorOut(e, "CountTable", "getNamesOfSeqs");
323                 exit(1);
324         }
325 }
326
327 /************************************************************/
328
329