]> git.donarmstrong.com Git - mothur.git/blob - cluster.cpp
Merge remote-tracking branch 'mothur/master'
[mothur.git] / cluster.cpp
1 /*
2  *  cluster.cpp
3  *  
4  *
5  *  Created by Pat Schloss on 8/14/08.
6  *  Copyright 2008 Patrick D. Schloss. All rights reserved.
7  *
8  */
9
10 #include "cluster.hpp"
11 #include "rabundvector.hpp"
12 #include "listvector.hpp"
13
14 /***********************************************************************/
15
16 Cluster::Cluster(RAbundVector* rav, ListVector* lv, SparseDistanceMatrix* dm, float c, string f) :
17 rabund(rav), list(lv), dMatrix(dm), method(f)
18 {
19         try {
20         
21         mapWanted = false;  //set to true by mgcluster to speed up overlap merge
22         
23         //save so you can modify as it changes in average neighbor
24         cutoff = c;
25         m = MothurOut::getInstance();
26         }
27         catch(exception& e) {
28                 m->errorOut(e, "Cluster", "Cluster");
29                 exit(1);
30         }
31 }
32 /***********************************************************************/
33 void Cluster::clusterBins(){
34         try {
35                 rabund->set(smallCol, rabund->get(smallRow)+rabund->get(smallCol));     
36                 rabund->set(smallRow, 0);       
37                 rabund->setLabel(toString(smallDist));
38         }
39         catch(exception& e) {
40                 m->errorOut(e, "Cluster", "clusterBins");
41                 exit(1);
42         }
43 }
44 /***********************************************************************/
45
46 void Cluster::clusterNames(){
47         try {
48                 if (mapWanted) {  updateMap();  }
49                 
50                 list->set(smallCol, list->get(smallRow)+','+list->get(smallCol));
51                 list->set(smallRow, "");        
52                 list->setLabel(toString(smallDist));
53     }
54         catch(exception& e) {
55                 m->errorOut(e, "Cluster", "clusterNames");
56                 exit(1);
57         }
58 }
59 /***********************************************************************/
60 void Cluster::update(double& cutOFF){
61         try {
62         smallCol = dMatrix->getSmallestCell(smallRow);
63         nColCells = dMatrix->seqVec[smallCol].size();
64         nRowCells = dMatrix->seqVec[smallRow].size();
65         
66                 vector<int> foundCol(nColCells, 0);
67         //cout << dMatrix->getNNodes() << " small cell: " << smallRow << '\t' << smallCol << endl;  
68                 int search;
69                 bool changed;
70         
71                 for (int i=nRowCells-1;i>=0;i--) {
72             if (m->control_pressed) { break; }
73              
74                         //if you are not the smallCell
75                         if (dMatrix->seqVec[smallRow][i].index != smallCol) { 
76                 search = dMatrix->seqVec[smallRow][i].index;
77                 
78                                 bool merged = false;
79                                 for (int j=0;j<nColCells;j++) {
80                     
81                                         if (dMatrix->seqVec[smallCol][j].index != smallRow) {  //if you are not the smallest distance
82                                                 if (dMatrix->seqVec[smallCol][j].index == search) {
83                                                         foundCol[j] = 1;
84                                                         merged = true;
85                                                         changed = updateDistance(dMatrix->seqVec[smallCol][j], dMatrix->seqVec[smallRow][i]);
86                             dMatrix->updateCellCompliment(smallCol, j);
87                                                         break;
88                                                 }else if (dMatrix->seqVec[smallCol][j].index < search) { j+=nColCells; } //we don't have a distance for this cell 
89                                         }       
90                                 }
91                                 //if not merged it you need it for warning 
92                                 if ((!merged) && (method == "average" || method == "weighted")) {  
93                                         if (cutOFF > dMatrix->seqVec[smallRow][i].dist) {  
94                                                 cutOFF = dMatrix->seqVec[smallRow][i].dist;  
95                                         }
96                     
97                                 }
98                                 dMatrix->rmCell(smallRow, i);
99                         }
100                 }
101                 clusterBins();
102                 clusterNames();
103         
104                 // Special handling for singlelinkage case, not sure whether this
105                 // could be avoided
106                 for (int i=nColCells-1;i>=0;i--) {
107                         if (foundCol[i] == 0) { 
108                                 if (method == "average" || method == "weighted") {
109                                         if (dMatrix->seqVec[smallCol][i].index != smallRow) { //if you are not hte smallest distance 
110                                                 if (cutOFF > dMatrix->seqVec[smallCol][i].dist) {  
111                                                         cutOFF = dMatrix->seqVec[smallCol][i].dist;  
112                                                 }
113                                         }
114                                 }
115                 dMatrix->rmCell(smallCol, i);
116                         }
117                 }
118         
119         }
120         catch(exception& e) {
121                 m->errorOut(e, "Cluster", "update");
122                 exit(1);
123         }
124 }
125 /***********************************************************************/
126 void Cluster::setMapWanted(bool f)  {  
127         try {
128                 mapWanted = f;
129                 
130         //initialize map
131                 for (int k = 0; k < list->getNumBins(); k++) {
132             
133             string names = list->get(k);
134             
135             //parse bin
136             string individual = "";
137             int binNameslength = names.size();
138             for(int j=0;j<binNameslength;j++){
139                 if(names[j] == ','){
140                     seq2Bin[individual] = k;
141                     individual = "";                            
142                 }
143                 else{  individual += names[j];  }
144             }
145             //get last name
146             seq2Bin[individual] = k;
147                 }
148                 
149         }
150         catch(exception& e) {
151                 m->errorOut(e, "Cluster", "setMapWanted");
152                 exit(1);
153         }
154 }
155 /***********************************************************************/
156 void Cluster::updateMap() {
157     try {
158                 //update location of seqs in smallRow since they move to smallCol now
159                 string names = list->get(smallRow);
160                 
161         string individual = "";
162         int binNameslength = names.size();
163         for(int j=0;j<binNameslength;j++){
164             if(names[j] == ','){
165                 seq2Bin[individual] = smallCol;
166                 individual = "";                                
167             }
168             else{  individual += names[j];  }
169         }
170         //get last name
171         seq2Bin[individual] = smallCol;         
172         
173         }
174         catch(exception& e) {
175                 m->errorOut(e, "Cluster", "updateMap");
176                 exit(1);
177         }
178 }
179 /***********************************************************************/
180
181
182