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