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