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