5 * Created by westcott on 10/13/09.
6 * Copyright 2009 Schloss Lab. All rights reserved.
11 #include "rabundvector.hpp"
12 #include "listvector.hpp"
13 #include "sparsematrix.hpp"
15 /***********************************************************************/
17 HCluster::HCluster(RAbundVector* rav, ListVector* lv) : rabund(rav), list(lv){
20 numSeqs = list->getNumSeqs();
22 //initialize cluster array
23 for (int i = 0; i < numSeqs; i++) {
24 clusterNode temp(1, -1, i);
25 clusterArray.push_back(temp);
30 errorOut(e, "HCluster", "HCluster");
34 /***********************************************************************/
36 void HCluster::clusterBins(){
38 //cout << smallCol << '\t' << smallRow << '\t' << smallDist << '\t' << rabund->get(clusterArray[smallRow].smallChild) << '\t' << rabund->get(clusterArray[smallCol].smallChild);
40 rabund->set(clusterArray[smallCol].smallChild, rabund->get(clusterArray[smallRow].smallChild)+rabund->get(clusterArray[smallCol].smallChild));
41 rabund->set(clusterArray[smallRow].smallChild, 0);
42 rabund->setLabel(toString(smallDist));
44 //cout << '\t' << rabund->get(clusterArray[smallRow].smallChild) << '\t' << rabund->get(clusterArray[smallCol].smallChild) << endl;
47 errorOut(e, "HCluster", "clusterBins");
54 /***********************************************************************/
56 void HCluster::clusterNames(){
58 ///cout << smallCol << '\t' << smallRow << '\t' << smallDist << '\t' << list->get(clusterArray[smallRow].smallChild) << '\t' << list->get(clusterArray[smallCol].smallChild);
59 if (mapWanted) { updateMap(); }
61 list->set(clusterArray[smallCol].smallChild, list->get(clusterArray[smallRow].smallChild)+','+list->get(clusterArray[smallCol].smallChild));
62 list->set(clusterArray[smallRow].smallChild, "");
63 list->setLabel(toString(smallDist));
65 //cout << '\t' << list->get(clusterArray[smallRow].smallChild) << '\t' << list->get(clusterArray[smallCol].smallChild) << endl;
69 errorOut(e, "HCluster", "clusterNames");
74 /***********************************************************************/
75 int HCluster::getUpmostParent(int node){
78 while (clusterArray[node].parent != -1) {
79 node = clusterArray[node].parent;
85 errorOut(e, "HCluster", "getUpmostParent");
89 /***********************************************************************/
90 void HCluster::printInfo(){
93 cout << "link table" << endl;
94 for (it = activeLinks.begin(); it!= activeLinks.end(); it++) {
95 cout << it->first << " = " << it->second << endl;
98 for (int i = 0; i < linkTable.size(); i++) {
100 for (it = linkTable[i].begin(); it != linkTable[i].end(); it++) {
101 cout << it->first << '-' << it->second << '\t';
105 cout << endl << "clusterArray" << endl;
107 for (int i = 0; i < clusterArray.size(); i++) {
108 cout << i << '\t' << clusterArray[i].numSeq << '\t' << clusterArray[i].parent << '\t' << clusterArray[i].smallChild << endl;
114 catch(exception& e) {
115 errorOut(e, "HCluster", "getUpmostParent");
119 /***********************************************************************/
120 int HCluster::makeActive() {
124 //cout << "active - here" << endl;
125 it = activeLinks.find(smallRow);
126 it2 = activeLinks.find(smallCol);
128 if ((it == activeLinks.end()) && (it2 == activeLinks.end())) { //both are not active so add them
129 int size = linkTable.size();
130 map<int, int> temp; map<int, int> temp2;
132 //add link to eachother
133 temp[smallRow] = 1; // 1 2
134 temp2[smallCol] = 1; // 1 0 1
136 linkTable.push_back(temp);
137 linkTable.push_back(temp2);
140 activeLinks[smallRow] = size;
141 activeLinks[smallCol] = size+1;
142 //cout << "active - here1" << endl;
143 }else if ((it != activeLinks.end()) && (it2 == activeLinks.end())) { //smallRow is active, smallCol is not
144 int size = linkTable.size();
145 int alreadyActiveRow = it->second;
148 //add link to eachother
149 temp[smallRow] = 1; // 6 2 3 5
150 linkTable.push_back(temp); // 6 0 1 2 0
151 linkTable[alreadyActiveRow][smallCol] = 1; // 2 1 0 1 1
155 activeLinks[smallCol] = size;
156 //cout << "active - here2" << endl;
157 }else if ((it == activeLinks.end()) && (it2 != activeLinks.end())) { //smallCol is active, smallRow is not
158 int size = linkTable.size();
159 int alreadyActiveCol = it2->second;
162 //add link to eachother
163 temp[smallCol] = 1; // 6 2 3 5
164 linkTable.push_back(temp); // 6 0 1 2 0
165 linkTable[alreadyActiveCol][smallRow] = 1; // 2 1 0 1 1
169 activeLinks[smallRow] = size;
170 //cout << "active - here3" << endl;
171 }else { //both are active so add one
172 int row = it->second;
173 int col = it2->second;
174 //cout << row << '\t' << col << endl;
176 linkTable[row][smallCol]++;
177 linkTable[col][smallRow]++;
178 linkValue = linkTable[row][smallCol];
179 //cout << "active - here4" << endl;
184 catch(exception& e) {
185 errorOut(e, "HCluster", "makeActive");
189 /***********************************************************************/
190 void HCluster::updateArrayandLinkTable() {
192 //if cluster was made update clusterArray and linkTable
193 int size = clusterArray.size();
196 clusterNode temp(clusterArray[smallRow].numSeq + clusterArray[smallCol].numSeq, -1, clusterArray[smallCol].smallChild);
197 clusterArray.push_back(temp);
200 clusterArray[smallRow].parent = size;
201 clusterArray[smallCol].parent = size;
203 //update linkTable by merging clustered rows and columns
204 int rowSpot = activeLinks[smallRow];
205 int colSpot = activeLinks[smallCol];
206 //cout << "here" << endl;
208 for (int i = 0; i < linkTable.size(); i++) {
209 //check if they are in map
210 it = linkTable[i].find(smallRow);
211 it2 = linkTable[i].find(smallCol);
213 if ((it!=linkTable[i].end()) && (it2!=linkTable[i].end())) { //they are both there
214 linkTable[i][size] = linkTable[i][smallRow]+linkTable[i][smallCol];
215 linkTable[i].erase(smallCol); //delete col row
216 linkTable[i].erase(smallRow); //delete col row
217 }else if ((it==linkTable[i].end()) && (it2!=linkTable[i].end())) { //only col
218 linkTable[i][size] = linkTable[i][smallCol];
219 linkTable[i].erase(smallCol); //delete col
220 }else if ((it!=linkTable[i].end()) && (it2==linkTable[i].end())) { //only row
221 linkTable[i][size] = linkTable[i][smallRow];
222 linkTable[i].erase(smallRow); //delete col
226 //cout << "here2" << endl;
228 for (it = linkTable[rowSpot].begin(); it != linkTable[rowSpot].end(); it++) {
229 it2 = linkTable[colSpot].find(it->first); //does the col also have this
231 if (it2 == linkTable[colSpot].end()) { //not there so add it
232 linkTable[colSpot][it->first] = it->second;
234 linkTable[colSpot][it->first] = it->second+it2->second;
237 //cout << "here3" << endl;
238 linkTable[colSpot].erase(size);
239 linkTable.erase(linkTable.begin()+rowSpot); //delete row
242 activeLinks.erase(smallRow);
243 activeLinks.erase(smallCol);
244 activeLinks[size] = colSpot;
246 //adjust everybody elses spot since you deleted - time vs. space
247 for (it = activeLinks.begin(); it != activeLinks.end(); it++) {
248 if (it->second > rowSpot) { activeLinks[it->first]--; }
251 //cout << "here4" << endl;
254 catch(exception& e) {
255 errorOut(e, "HCluster", "updateArrayandLinkTable");
259 /***********************************************************************/
260 void HCluster::update(int row, int col, float distance){
265 smallDist = distance;
266 bool clustered = false;
268 //find upmost parent of row and col
269 smallRow = getUpmostParent(smallRow);
270 smallCol = getUpmostParent(smallCol);
271 //cout << "row = " << row << " smallRow = " << smallRow << " col = " << col << " smallCol = " << smallCol << " dist = " << distance << endl;
273 //are they active in the link table
274 int linkValue = makeActive(); //after this point this nodes info is active in linkTable
276 //cout << "linkValue = " << linkValue << " times = " << (clusterArray[smallRow].numSeq * clusterArray[smallCol].numSeq) << endl;
278 if (linkValue == (clusterArray[smallRow].numSeq * clusterArray[smallCol].numSeq)) {
280 updateArrayandLinkTable();
289 catch(exception& e) {
290 errorOut(e, "HCluster", "update");
294 /***********************************************************************/
295 void HCluster::setMapWanted(bool m) {
300 for (int i = 0; i < list->getNumBins(); i++) {
303 string names = list->get(i);
304 while (names.find_first_of(',') != -1) {
306 string name = names.substr(0,names.find_first_of(','));
307 //save name and bin number
309 names = names.substr(names.find_first_of(',')+1, names.length());
317 catch(exception& e) {
318 errorOut(e, "HCluster", "setMapWanted");
322 /***********************************************************************/
323 void HCluster::updateMap() {
325 //update location of seqs in smallRow since they move to smallCol now
326 string names = list->get(clusterArray[smallRow].smallChild);
327 while (names.find_first_of(',') != -1) {
329 string name = names.substr(0,names.find_first_of(','));
330 //save name and bin number
331 seq2Bin[name] = clusterArray[smallCol].smallChild;
332 names = names.substr(names.find_first_of(',')+1, names.length());
336 seq2Bin[names] = clusterArray[smallCol].smallChild;
338 catch(exception& e) {
339 errorOut(e, "HCluster", "updateMap");
343 /***********************************************************************/