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