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