]> git.donarmstrong.com Git - mothur.git/blob - heatmap.cpp
This contains Pat's bug fixes and updates. It represents mothur v.1.3.0
[mothur.git] / heatmap.cpp
1 /*
2  *  heatmap.cpp
3  *  Mothur
4  *
5  *  Created by Sarah Westcott on 3/25/09.
6  *  Copyright 2009 Schloss Lab UMASS Amherst. All rights reserved.
7  *
8  */
9
10 #include "heatmap.h"
11
12 //**********************************************************************************************************************
13 HeatMap::HeatMap(){
14         try {
15                 globaldata = GlobalData::getInstance();
16                 format = globaldata->getFormat();
17                 sorted = globaldata->getSorted();
18         }
19         catch(exception& e) {
20                 cout << "Standard Error: " << e.what() << " has occurred in the HeatMap class Function HeatMap. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
21                 exit(1);
22         }
23         catch(...) {
24                 cout << "An unknown error has occurred in the HeatMap class function HeatMap. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
25                 exit(1);
26         }
27 }
28
29 //**********************************************************************************************************************
30
31 void HeatMap::getPic(RAbundVector* rabund) {
32         try {
33                 //get users scaling method
34                 scaler = globaldata->getScale();
35                 
36                 float maxRelAbund = 0.0;                
37                 
38                 for(int i=0;i<rabund->size();i++){                              
39                         float relAbund = rabund->get(i) / (float)rabund->getNumSeqs();
40                         if(relAbund > maxRelAbund){     maxRelAbund = relAbund; }
41                 }
42                 
43                 scaler = globaldata->getScale();
44                 
45                 vector<string> scaleRelAbund(rabund->size(), "");
46                 
47                 for(int i=0;i<rabund->size();i++){
48                         float relAbund = rabund->get(i) / (float)rabund->getNumSeqs();
49                         
50                         if (rabund->get(i) != 0) { //don't want log value of 0.
51                                 if (scaler == "log10") {
52                                         scaleRelAbund[i] = toHex(int(255 * log10(relAbund) / log10(maxRelAbund))) + "0000";  
53                                 }else if (scaler == "log2") {
54                                         scaleRelAbund[i] = toHex(int(255 * log2(relAbund) / log2(maxRelAbund))) + "0000";  
55                                 }else if (scaler == "linear") {
56                                         scaleRelAbund[i] = toHex(int(255 * relAbund / maxRelAbund)) + "0000";  
57                                 }else {  //if user enters invalid scaler option.
58                                         scaleRelAbund[i] = toHex(int(255 * log10(relAbund / log10(maxRelAbund))))  + "0000"; 
59                                 } 
60                         }
61                         else { scaleRelAbund[i] = "FFFFFF";  }
62                 }
63                 
64                 
65                 string filenamesvg = getRootName(globaldata->inputFileName) + rabund->getLabel() + ".heatmap.svg";
66                 openOutputFile(filenamesvg, outsvg);
67                 
68                 //svg image
69                 outsvg << "<svg width=\"100%\" height=\"100%\" viewBox=\"0 0 " + toString(300) + " " + toString((rabund->getNumBins()*5 + 120))  + "\">\n";
70                 outsvg << "<g>\n";
71                 
72                 //white backround
73                 outsvg << "<rect fill=\"white\" stroke=\"white\" x=\"0\" y=\"0\" width=\"" + toString(300) + "\" height=\"" + toString((rabund->getNumBins()*5 + 120))  + "\"/>"; 
74                 outsvg << "<text fill=\"black\" class=\"seri\" x=\"" + toString((150) - 40) + "\" y=\"25\">Heatmap at distance " + rabund->getLabel() + "</text>\n";
75                                 
76                 //output legend and color labels
77                 string color;
78                 int x = 0;
79                 int y = 103 + (rabund->getNumBins()*5);
80                 printLegend(y, maxRelAbund);
81                 
82                 y = 70;
83                 for (int i = 0; i < scaleRelAbund.size(); i++) {
84                         
85                         outsvg << "<rect fill=\"#" + scaleRelAbund[i] + "\" stroke=\"#" + scaleRelAbund[i] + "\" x=\"" + toString(x) + "\" y=\"" + toString(y) + "\" width=\"300\" height=\"5\"/>\n";
86                         y += 5;
87                 }
88                 
89                 outsvg << "</g>\n</svg>\n";
90                 outsvg.close();
91                 
92                 
93         }
94         catch(exception& e) {
95                 cout << "Standard Error: " << e.what() << " has occurred in the HeatMap class Function getPic. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
96                 exit(1);
97         }
98         catch(...) {
99                 cout << "An unknown error has occurred in the HeatMap class function getPic. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
100                 exit(1);
101         }
102 }
103
104 //**********************************************************************************************************************
105
106 void HeatMap::getPic(vector<SharedRAbundVector*> lookup) {
107         try {
108                 //sort lookup so shared bins are on top
109                 if (sorted == "T") {  sortSharedVectors(lookup);  }
110                 
111                 vector<vector<string> > scaleRelAbund;
112                 vector<float> maxRelAbund(lookup.size(), 0.0);          
113                 float superMaxRelAbund = 0;
114                 
115                 for(int i = 0; i < lookup.size(); i++){
116                         for(int j=0; j<lookup[i]->size(); j++){
117                                 
118                                 float relAbund = lookup[i]->getAbundance(j) / (float)lookup[i]->getNumSeqs();
119                                 if(relAbund > maxRelAbund[i]){  maxRelAbund[i] = relAbund;      }
120                         }
121                         if(maxRelAbund[i] > superMaxRelAbund){  superMaxRelAbund = maxRelAbund[i];      }
122                 }
123                 
124                 scaler = globaldata->getScale();
125                 
126                 scaleRelAbund.resize(lookup.size());
127                 for(int i=0;i<lookup.size();i++){
128                         scaleRelAbund[i].assign(lookup[i]->size(), "");
129                         for(int j=0;j<lookup[i]->size();j++){
130                                 float relAbund = lookup[i]->getAbundance(j) / (float)lookup[i]->getNumSeqs();
131                                 
132                                 if (lookup[i]->getAbundance(j) != 0) { //don't want log value of 0.
133                                         if (scaler == "log10") {
134                                                 scaleRelAbund[i][j] = toHex(int(255 * log10(relAbund) / log10(maxRelAbund[i]))) + "0000";  
135                                         }else if (scaler == "log2") {
136                                                 scaleRelAbund[i][j] = toHex(int(255 * log2(relAbund) / log2(maxRelAbund[i]))) + "0000";  
137                                         }else if (scaler == "linear") {
138                                                 scaleRelAbund[i][j] = toHex(int(255 * relAbund / maxRelAbund[i])) + "0000";  
139                                         }else {  //if user enters invalid scaler option.
140                                                 scaleRelAbund[i][j] = toHex(int(255 * log10(relAbund / log10(maxRelAbund[i]))))  + "0000"; 
141                                         } 
142                                 }else { scaleRelAbund[i][j] = "FFFFFF";  }
143
144                         }
145                 }
146
147                 string filenamesvg = getRootName(globaldata->inputFileName) + lookup[0]->getLabel() + ".heatmap.svg";
148                 openOutputFile(filenamesvg, outsvg);
149                 
150                 //svg image
151                 outsvg << "<svg width=\"100%\" height=\"100%\" viewBox=\"0 0 " + toString(lookup.size() * 300) + " " + toString((lookup[0]->getNumBins()*5 + 120))  + "\">\n";
152                 outsvg << "<g>\n";
153                 
154                 //white backround
155                 outsvg << "<rect fill=\"white\" stroke=\"white\" x=\"0\" y=\"0\" width=\"" + toString(lookup.size() * 300) + "\" height=\"" + toString((lookup[0]->getNumBins()*5 + 120))  + "\"/>"; 
156                 outsvg << "<text fill=\"black\" class=\"seri\" x=\"" + toString((lookup.size() * 150) - 40) + "\" y=\"25\">Heatmap at distance " + lookup[0]->getLabel() + "</text>\n";
157                 
158                 //column labels
159                 for (int h = 0; h < lookup.size(); h++) {
160                         outsvg << "<text fill=\"black\" class=\"seri\" x=\"" + toString(((300 * (h+1)) - 150) - ((int)lookup[h]->getGroup().length() / 2)) + "\" y=\"50\">" + lookup[h]->getGroup() + "</text>\n"; 
161                 }
162                 
163                 //output legend and color labels
164                 string color;
165                 int x = 0;
166                 int y = 103 + (lookup[0]->getNumBins()*5);
167                 printLegend(y, superMaxRelAbund);
168                 
169                 y = 70;
170                 for (int i = 0; i < scaleRelAbund[0].size(); i++) {
171                         for (int j = 0; j < scaleRelAbund.size(); j++) {
172                                 
173                                 outsvg << "<rect fill=\"#" + scaleRelAbund[j][i] + "\" stroke=\"#" + scaleRelAbund[j][i] + "\" x=\"" + toString(x) + "\" y=\"" + toString(y) + "\" width=\"300\" height=\"5\"/>\n";
174                                 x += 300;
175                         }
176                         x = 0;
177                         y += 5;
178                 }
179                 
180                 outsvg << "</g>\n</svg>\n";
181                 outsvg.close();
182
183         }
184         catch(exception& e) {
185                 cout << "Standard Error: " << e.what() << " has occurred in the HeatMap class Function getPic. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
186                 exit(1);
187         }
188         catch(...) {
189                 cout << "An unknown error has occurred in the HeatMap class function getPic. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
190                 exit(1);
191         }
192 }
193
194 //**********************************************************************************************************************
195 void HeatMap::sortSharedVectors(vector<SharedRAbundVector*>& lookup){
196         try {
197                 //copy lookup and then clear it to refill with sorted.
198                 //loop though lookup and determine if they are shared
199                 //if they are then insert in the front
200                 //if not push to back
201                 
202                 vector<SharedRAbundVector*> looktemp;
203                 map<int, int> place; //spot in lookup where you insert shared by, ie, 3 -> 2 if they are shared by 3 inset into location 2.
204                 map<int, int>::iterator it;
205                 int count;
206                 
207                 //create and initialize looktemp as a copy of lookup
208                 for (int i = 0; i < lookup.size(); i++) { 
209                         SharedRAbundVector* temp = new SharedRAbundVector(lookup[i]->getNumBins());
210                         temp->setLabel(lookup[i]->getLabel());
211                         temp->setGroup(lookup[i]->getGroup());
212                         //copy lookup i's info
213                         for (int j = 0; j < lookup[i]->size(); j++) {
214                                 temp->set(j, lookup[i]->getAbundance(j), lookup[i]->getGroup());
215                         }
216                         looktemp.push_back(temp);
217                 }
218                 
219                 //clear out lookup to create sorted lookup -- Sarah look at - this is causing segmentation faults
220                 for (int j = 0; j < lookup.size(); j++) {
221 //                      delete lookup[j];
222                 }
223                 lookup.clear();  //doesn't this do the job?
224                 
225                 //create and initialize lookup to empty vectors
226                 for (int i = 0; i < looktemp.size(); i++) { 
227                         SharedRAbundVector* temp = new SharedRAbundVector();
228                         temp->setLabel(looktemp[i]->getLabel());
229                         temp->setGroup(looktemp[i]->getGroup());
230                         lookup.push_back(temp); 
231                         
232                         //initialize place map
233                         place[i] = 0;
234                 }
235                 
236                 
237                 //for each bin
238                 for (int i = 0; i < looktemp[0]->size(); i++) {
239                         count = 0;
240                         bool updatePlace = false;
241                         //for each group
242                         for (int j = 0; j < looktemp.size(); j++) {
243                                 if (looktemp[j]->getAbundance(i) != 0) { count++; }
244                         }
245                         
246                         //fill lookup
247                         for (int j = 0; j < looktemp.size(); j++) {
248                                 //if they are not shared then push to back, if they are not insert in front
249                                 if (count < 2)  { lookup[j]->push_back(looktemp[j]->getAbundance(i), i, looktemp[j]->getGroup()); }
250                                 //they are shared by some
251                                 else {  lookup[j]->insert(looktemp[j]->getAbundance(i), place[count], looktemp[j]->getGroup());   updatePlace = true; }
252                         }
253                         
254                         if (updatePlace == true) {
255                                 //move place holders below where you entered up to "make space" for you entry
256                                 for (it = place.begin(); it!= place.end(); it++) {  
257                                         if (it->first < count) { it->second++; }
258                                 }
259                         }
260                 }
261                 
262                 //delete looktemp -- Sarah look at - this is causing segmentation faults
263                 for (int j = 0; j < looktemp.size(); j++) {
264 //                      delete looktemp[j];
265                 }
266                 
267         }
268         catch(exception& e) {
269                 cout << "Standard Error: " << e.what() << " has occurred in the HeatMap class Function sortSharedVectors. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
270                 exit(1);
271         }
272         catch(...) {
273                 cout << "An unknown error has occurred in the HeatMap class function sortSharedVectors. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
274                 exit(1);
275         }
276         
277 }
278
279 //**********************************************************************************************************************
280
281 void HeatMap::printLegend(int y, float maxbin) {
282         try {
283                 
284                 //output legend and color labels
285                 //go through map and give each score a color value
286                 string color;
287                 int x = 10;
288                 
289                 //prints legend
290                 for (int i = 1; i < 255; i++) {
291                         color = toHex(int((float)(i)));
292                         outsvg << "<rect fill=\"#" + color + "0000\" stroke=\"#" + color + "0000\" x=\"" + toString(x) + "\" y=\"" + toString(y) + "\" width=\"1\" height=\"10\"/>\n";
293                         x += 1;
294                 }
295                 
296                 //prints legend labels
297                 x = 10;
298                 for (int i = 1; i<=5; i++) {
299                         float label;
300                         if(scaler== "log10")            {       label = maxbin * log10(51*i) / log10(255);      }
301                         else if(scaler== "log2")        {       label = maxbin * log2(51*i) / log2(255);        }
302                         else if(scaler== "linear")      {       label = maxbin * 51 * i / 255;                          }
303                         else                                            {       label = maxbin * log10(51*i) / log10(255);      }
304                         file://localhost/Users/westcott/Desktop/c.amazon.fn.0.19.rep.fasta
305                         label = int(label * 1000 + 0.5);
306                         label /= 1000.0;
307                         string text = toString(label, 3);
308                         
309                         outsvg << "<text fill=\"black\" class=\"seri\" x=\"" + toString(x) + "\" y=\"" + toString(y-3) + "\">" + text + "</text>\n";
310                         x += 60;
311                 }
312         }
313         
314         catch(exception& e) {
315                 cout << "Standard Error: " << e.what() << " has occurred in the HeatMap class Function printLegend. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
316                 exit(1);
317         }
318         catch(...) {
319                 cout << "An unknown error has occurred in the HeatMap class function printLegend. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
320                 exit(1);
321         }
322         
323 }
324
325
326
327