]> git.donarmstrong.com Git - mothur.git/blob - heatmap.cpp
pcr.seqs bug fix. working on shannon range calc
[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, int num, int fsize, string dir, string i){
14         try {
15                 m = MothurOut::getInstance();
16 //              format = globaldata->getFormat();
17                 sorted = sort;
18                 scaler = scale;
19                 outputDir = dir;
20                 numOTU = num;
21                 fontSize = fsize;
22                 inputfile = i;
23         }
24         catch(exception& e) {
25                 m->errorOut(e, "HeatMap", "HeatMap");
26                 exit(1);
27         }
28 }
29
30 //**********************************************************************************************************************
31
32 string HeatMap::getPic(RAbundVector* rabund) {
33         try {
34                 
35                 int numBinsToDisplay = rabund->getNumBins();
36                 
37                 if (numOTU != 0) { //user want to display a portion of the otus
38                         if (numOTU < numBinsToDisplay) {  numBinsToDisplay = numOTU; }
39                 }
40                 
41                 //sort lookup so shared bins are on top
42                 if (sorted != "none") {  sortRabund(rabund);  }
43                 
44                 float maxRelAbund = 0.0;                
45                 
46                 for(int i=0;i<rabund->size();i++){                              
47                         float relAbund = rabund->get(i) / (float)rabund->getNumSeqs();
48                         if(relAbund > maxRelAbund){     maxRelAbund = relAbund; }
49                 }
50                 
51                 vector<string> scaleRelAbund(numBinsToDisplay, "");
52                 
53                 for(int i=0;i<numBinsToDisplay;i++){
54                         float relAbund = rabund->get(i) / (float)rabund->getNumSeqs();
55                         
56                         if (m->control_pressed) { return "control"; }
57                         
58                         if (rabund->get(i) != 0) { //don't want log value of 0.
59                                 if (scaler == "log10") {
60                                         scaleRelAbund[i] = toHex(int(255 * log10(relAbund) / log10(maxRelAbund))) + "0000";  
61                                 }else if (scaler == "log2") {
62                                         scaleRelAbund[i] = toHex(int(255 * log2(relAbund) / log2(maxRelAbund))) + "0000";  
63                                 }else if (scaler == "linear") {
64                                         scaleRelAbund[i] = toHex(int(255 * relAbund / maxRelAbund)) + "0000";  
65                                 }else {  //if user enters invalid scaler option.
66                                         scaleRelAbund[i] = toHex(int(255 * log10(relAbund / log10(maxRelAbund))))  + "0000"; 
67                                 } 
68                         }
69                         else { scaleRelAbund[i] = "FFFFFF";  }
70                 }
71                 
72                 
73                 string filenamesvg = outputDir + m->getRootName(m->getSimpleName(inputfile)) + rabund->getLabel() + ".heatmap.bin.svg";
74                 m->openOutputFile(filenamesvg, outsvg);
75                 
76                 //svg image
77                 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((numBinsToDisplay*5 + 120))  + "\">\n";
78                 outsvg << "<g>\n";
79                 
80                 //white backround
81                 outsvg << "<rect fill=\"white\" stroke=\"white\" x=\"0\" y=\"0\" width=\"" + toString(300) + "\" height=\"" + toString((numBinsToDisplay*5 + 120))  + "\"/>"; 
82                 outsvg << "<text fill=\"black\" class=\"seri\" text-anchor=\"middle\" font-size=\"" + toString(fontSize) + "\" x=\"" + toString((150) - 40) + "\" y=\"25\">Heatmap at distance " + rabund->getLabel() + "</text>\n";
83                                 
84                 //output legend and color labels
85                 string color;
86                 int x = 0;
87                 int y = 103 + (numBinsToDisplay*5);
88                 printLegend(y, maxRelAbund);
89                 
90                 y = 70;
91
92                 for (int i = 0; i < scaleRelAbund.size(); i++) {
93                         if (m->control_pressed) { outsvg.close(); return "control"; }
94                         
95                         outsvg << "<rect fill=\"#" + scaleRelAbund[i] + "\" stroke=\"#" + scaleRelAbund[i] + "\" x=\"" + toString(x) + "\" y=\"" + toString(y) + "\" width=\"300\" height=\"5\"/>\n";
96                         y += 5;
97                 }
98                 
99                 outsvg << "</g>\n</svg>\n";
100                 outsvg.close();
101                 
102                 return filenamesvg;
103         }
104         catch(exception& e) {
105                 m->errorOut(e, "HeatMap", "getPic");
106                 exit(1);
107         }
108 }
109
110 //**********************************************************************************************************************
111
112 string HeatMap::getPic(vector<SharedRAbundVector*> lookup) {
113         try {
114         
115                 int numBinsToDisplay = lookup[0]->size();
116                 
117                 if (numOTU != 0) { //user want to display a portion of the otus
118                         if (numOTU < numBinsToDisplay) {  numBinsToDisplay = numOTU; }
119                 }
120                 
121                 //sort lookup so shared bins are on top
122         vector<string> sortedLabels = m->currentSharedBinLabels;
123                 if (sorted != "none") {  sortedLabels = sortSharedVectors(lookup);  }
124                 
125                 vector<vector<string> > scaleRelAbund;
126                 vector<float> maxRelAbund(lookup[0]->size(), 0.0);              
127                 float superMaxRelAbund = 0;
128                 
129                 for(int i = 0; i < lookup.size(); i++){
130                         for(int j=0; j<lookup[i]->size(); j++){
131                                 
132                                 float relAbund = lookup[i]->getAbundance(j) / (float)lookup[i]->getNumSeqs();
133                                 if(relAbund > maxRelAbund[i]){  maxRelAbund[i] = relAbund;      }
134                         }
135                         if(maxRelAbund[i] > superMaxRelAbund){  superMaxRelAbund = maxRelAbund[i];      }
136                 }
137                 
138                 scaleRelAbund.resize(lookup.size());
139                 for(int i=0;i<lookup.size();i++){
140                         scaleRelAbund[i].assign(numBinsToDisplay, "");
141                         for(int j=0;j<numBinsToDisplay;j++){
142                                 if (m->control_pressed) {  return "control"; }
143                                 float relAbund = lookup[i]->getAbundance(j) / (float)lookup[i]->getNumSeqs();
144                                 
145                                 if (lookup[i]->getAbundance(j) != 0) { //don't want log value of 0.
146                                         if (scaler == "log10") {
147                         if (maxRelAbund[i] == 1) { maxRelAbund[i] -= 0.001; }
148                         if (relAbund == 1) { relAbund -= 0.001; }
149                                                 scaleRelAbund[i][j] = toHex(int(255 * log10(relAbund) / log10(maxRelAbund[i]))) + "0000";
150                                         }else if (scaler == "log2") {
151                         if (maxRelAbund[i] == 1) { maxRelAbund[i] -= 0.001; }
152                         if (relAbund == 1) { relAbund -= 0.001; }
153                                                 scaleRelAbund[i][j] = toHex(int(255 * log2(relAbund) / log2(maxRelAbund[i]))) + "0000";  
154                                         }else if (scaler == "linear") {
155                                                 scaleRelAbund[i][j] = toHex(int(255 * relAbund / maxRelAbund[i])) + "0000";
156                                         }else {  //if user enters invalid scaler option.
157                         if (maxRelAbund[i] == 1) { maxRelAbund[i] += 0.001; }
158                                                 scaleRelAbund[i][j] = toHex(int(255 * log10(relAbund / log10(maxRelAbund[i]))))  + "0000"; 
159                                         } 
160                                 }else { scaleRelAbund[i][j] = "FFFFFF";  }
161
162                         }
163                 }
164
165                 string filenamesvg = outputDir + m->getRootName(m->getSimpleName(inputfile)) + lookup[0]->getLabel() + ".heatmap.bin.svg";
166                 m->openOutputFile(filenamesvg, outsvg);
167         int binHeight = 20;
168         int labelBump = 100;
169         int binWidth = 300;
170                 
171                 //svg image
172                 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() * binWidth + labelBump) + " " + toString((numBinsToDisplay*binHeight + 120))  + "\">\n";
173                 outsvg << "<g>\n";
174                 
175                 //white backround
176                 outsvg << "<rect fill=\"white\" stroke=\"white\" x=\"0\" y=\"0\" width=\"" + toString(lookup.size() * binWidth+labelBump) + "\" height=\"" + toString((numBinsToDisplay*binHeight + 120))  + "\"/>";
177                 outsvg << "<text fill=\"black\" class=\"seri\" font-size=\"" + toString(fontSize) + "\" text-anchor=\"middle\" x=\"" + toString((lookup.size() * 150) - 40) + "\" y=\"25\">Heatmap at distance " + lookup[0]->getLabel() + "</text>\n";
178                 
179                 //column labels
180                 for (int h = 0; h < lookup.size()+1; h++) {
181             if (h == 0) {
182                 string tempLabel = "OTU";
183                 outsvg << "<text fill=\"black\" class=\"seri\" font-size=\"" + toString(fontSize) + "\" x=\"" + toString(labelBump-labelBump/2+1) + "\" y=\"50\">" + tempLabel + "</text>\n";
184             }else {
185                 outsvg << "<text fill=\"black\" class=\"seri\" font-size=\"" + toString(fontSize) + "\" x=\"" + toString(((binWidth * h) - 150) - ((int)lookup[h-1]->getGroup().length() / 2)+labelBump/2) + "\" y=\"50\">" + lookup[h-1]->getGroup() + "</text>\n";
186             }
187                 }
188
189                 //output legend and color labels
190                 string color;
191                 int x = 0;
192                 int y = 103 + (numBinsToDisplay*binHeight);
193                 printLegend(y, superMaxRelAbund);
194                 
195                 y = 70;
196                 for (int i = 0; i < numBinsToDisplay; i++) {
197             outsvg << "<text fill=\"black\" class=\"seri\" font-size=\"" + toString(fontSize) + "\" x=\"" + toString(x) + "\" y=\"" + toString(y) + "\">" + sortedLabels[i] + "</text>\n";
198             x += labelBump;
199                         for (int j = 0; j < scaleRelAbund.size(); j++) {
200                                 if (m->control_pressed) { outsvg.close(); return "control"; }
201                                 
202                                 outsvg << "<rect fill=\"#" + scaleRelAbund[j][i] + "\" stroke=\"#" + scaleRelAbund[j][i] + "\" x=\"" + toString(x) + "\" y=\"" + toString(y) + "\" width=\"" + toString(binWidth) +  "\" height=\"" + toString(binHeight) +  "\"/>\n";
203                                 x += binWidth;
204                         }
205                         x = 0;
206                         y += binHeight;
207                 }
208                 
209                 outsvg << "</g>\n</svg>\n";
210                 outsvg.close();
211                 
212                 return filenamesvg;
213
214         }
215         catch(exception& e) {
216                 m->errorOut(e, "HeatMap", "getPic");
217                 exit(1);
218         }
219 }
220
221 //**********************************************************************************************************************
222 vector<string> HeatMap::sortSharedVectors(vector<SharedRAbundVector*>& lookup){
223         try {
224                                 
225                 vector<SharedRAbundVector*> looktemp;
226                 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.
227                 map<int, int>::iterator it;
228         
229         vector<string> sortedLabels = m->currentSharedBinLabels;
230                 
231                 /****************** find order of otus **********************/
232                 if (sorted == "shared") {
233                         place = orderShared(lookup);    
234                 }else if (sorted == "topotu") {
235                         place = orderTopOtu(lookup);    
236                 }else if (sorted == "topgroup") {
237                         place = orderTopGroup(lookup);  
238                 }else { m->mothurOut("Error: invalid sort option."); m->mothurOutEndLine();  return sortedLabels; }
239                                 
240                 
241                 /******************* create copy of lookup *********************/
242                 //create and initialize looktemp as a copy of lookup
243                 for (int i = 0; i < lookup.size(); i++) { 
244                         SharedRAbundVector* temp = new SharedRAbundVector(lookup[i]->getNumBins());
245                         temp->setLabel(lookup[i]->getLabel());
246                         temp->setGroup(lookup[i]->getGroup());
247                         //copy lookup i's info
248                         for (int j = 0; j < lookup[i]->size(); j++) {
249                                 temp->set(j, lookup[i]->getAbundance(j), lookup[i]->getGroup());
250                         }
251                         looktemp.push_back(temp);
252                 }
253         
254                 /************************ fill lookup in order given by place *********************/
255                 //for each bin
256                 for (int i = 0; i < looktemp[0]->size(); i++) {                                                                                                         //place
257                         //fill lookup                                                                                                                                                                   // 2 -> 1
258                         for (int j = 0; j < looktemp.size(); j++) {                                                                                                             // 3 -> 2
259                                 int newAbund = looktemp[j]->getAbundance(i);                                                                                            // 1 -> 3
260                                 lookup[j]->set(place[i], newAbund, looktemp[j]->getGroup()); //binNumber, abundance, group
261                         }
262             sortedLabels[place[i]] = m->currentSharedBinLabels[i];
263                 }
264                 
265                 //delete looktemp -- Sarah look at - this is causing segmentation faults
266                 for (int j = 0; j < looktemp.size(); j++) {
267 //                      delete looktemp[j];
268                 }
269                 
270                 return sortedLabels;
271                 
272         }
273         catch(exception& e) {
274                 m->errorOut(e, "HeatMap", "sortSharedVectors");
275                 exit(1);
276         }
277 }
278 //**********************************************************************************************************************
279 map<int, int> HeatMap::orderShared(vector<SharedRAbundVector*>& lookup){
280         try {
281                                 
282                 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.
283                 map<int, int>::iterator it;
284                 
285                 vector<int> sharedBins;
286                 vector<int> uniqueBins;
287                 
288                 //for each bin
289                 for (int i = 0; i < lookup[0]->size(); i++) {   
290                         int count = 0;                                                                                          
291                         
292                         //is this bin shared
293                         for (int j = 0; j < lookup.size(); j++) {               if (lookup[j]->getAbundance(i) != 0) { count++; }       }
294                         
295                         if (count < 2)  {  uniqueBins.push_back(i); }
296                         else                    {  sharedBins.push_back(i); }
297                 }
298                 
299                 //fill place
300                 for (int i = 0; i < sharedBins.size(); i++) { place[sharedBins[i]] = i; }
301                 for (int i = 0; i < uniqueBins.size(); i++) { place[uniqueBins[i]] = (sharedBins.size() + i); }
302                 
303                 return place;
304                 
305         }
306         catch(exception& e) {
307                 m->errorOut(e, "HeatMap", "orderShared");
308                 exit(1);
309         }
310 }
311 //**********************************************************************************************************************
312 map<int, int> HeatMap::orderTopOtu(vector<SharedRAbundVector*>& lookup){
313         try {
314                                 
315                 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.
316                 map<int, int>::iterator it;
317                 
318                 vector<binCount> totals;
319                 
320                 //for each bin
321                 for (int i = 0; i < lookup[0]->size(); i++) {   
322                         int total = 0;                                                                                          
323                         
324                         for (int j = 0; j < lookup.size(); j++) {       total += lookup[j]->getAbundance(i);    }
325                         
326                         binCount temp(i, total);
327                         
328                         totals.push_back(temp);
329                 }
330                 
331                 sort(totals.begin(), totals.end(), comparebinCounts);
332                 
333                 //fill place
334                 for (int i = 0; i < totals.size(); i++) {   place[totals[i].bin] = i;  }
335                                 
336                 return place;
337                 
338         }
339         catch(exception& e) {
340                 m->errorOut(e, "HeatMap", "orderTopOtu");
341                 exit(1);
342         }
343 }
344 //**********************************************************************************************************************
345 map<int, int> HeatMap::orderTopGroup(vector<SharedRAbundVector*>& lookup){
346         try {
347                                 
348                 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.
349                 map<int, int>::iterator it;
350                 
351                 vector < vector<binCount> > totals; //totals[0] = bin totals for group 0, totals[1] = bin totals for group 1, ...
352                 totals.resize(lookup.size());
353                 
354                 //for each bin
355                 for (int i = 0; i < lookup[0]->size(); i++) {   
356                         for (int j = 0; j < lookup.size(); j++) {
357                                 binCount temp(i, (lookup[j]->getAbundance(i)));
358                                 totals[j].push_back(temp);
359                         }
360                 }
361                 
362                 for (int i = 0; i < totals.size(); i++) { sort(totals[i].begin(), totals[i].end(), comparebinCounts);  }
363                 
364                 //fill place
365                 //grab the top otu for each group adding it if its not already added
366                 int count = 0;
367                 for (int i = 0; i < totals[0].size(); i++) { 
368                 
369                         for (int j = 0; j < totals.size(); j++) {  
370                                 it = place.find(totals[j][i].bin);
371                                 
372                                 if (it == place.end()) { //not added yet
373                                         place[totals[j][i].bin] = count;
374                                         count++;
375                                 }
376                         }
377                 }
378                                 
379                 return place;
380                 
381         }
382         catch(exception& e) {
383                 m->errorOut(e, "HeatMap", "orderTopGroup");
384                 exit(1);
385         }
386 }
387 //**********************************************************************************************************************
388
389 void HeatMap::printLegend(int y, float maxbin) {
390         try {
391                 
392                 //output legend and color labels
393                 //go through map and give each score a color value
394                 string color;
395                 int x = 10;
396                 
397                 //prints legend
398                 for (int i = 1; i < 255; i++) {
399                         color = toHex(int((float)(i)));
400                         outsvg << "<rect fill=\"#" + color + "0000\" stroke=\"#" + color + "0000\" x=\"" + toString(x) + "\" y=\"" + toString(y) + "\" width=\"1\" height=\"10\"/>\n";
401                         x += 1;
402                 }
403                 
404                 //prints legend labels
405                 x = 10;
406                 for (int i = 1; i<=5; i++) {
407                         float label;
408                         if(scaler== "log10")            {       label = maxbin * log10(51*i) / log10(255);      }
409                         else if(scaler== "log2")        {       label = maxbin * log2(51*i) / log2(255);        }
410                         else if(scaler== "linear")      {       label = maxbin * 51 * i / 255;                          }
411                         else                                            {       label = maxbin * log10(51*i) / log10(255);      }
412                         label = int(label * 1000 + 0.5);
413                         label /= 1000.0;
414                         string text = toString(label, 3);
415                         
416                         outsvg << "<text fill=\"black\" class=\"seri\" x=\"" + toString(x) + "\" y=\"" + toString(y-3) + "\">" + text + "</text>\n";
417                         x += 60;
418                 }
419         }
420         
421         catch(exception& e) {
422                 m->errorOut(e, "HeatMap", "printLegend");
423                 exit(1);
424         }
425 }
426 //**********************************************************************************************************************
427
428 string HeatMap::getPic(vector<SharedRAbundFloatVector*> lookup) {
429         try {
430         
431                 int numBinsToDisplay = lookup[0]->size();
432                 
433                 if (numOTU != 0) { //user want to display a portion of the otus
434                         if (numOTU < numBinsToDisplay) {  numBinsToDisplay = numOTU; }
435                 }
436                 
437                 //sort lookup so shared bins are on top
438                 vector<string> sortedLabels = m->currentSharedBinLabels;
439                 if (sorted != "none") {  sortedLabels = sortSharedVectors(lookup);  }
440                 
441                 vector<vector<string> > scaleRelAbund;
442                 vector<float> maxRelAbund(lookup.size(), 0.0);          
443                 float superMaxRelAbund = 0;
444                 
445                 for(int i = 0; i < lookup.size(); i++){
446                         for(int j=0; j<lookup[i]->size(); j++){
447                                 
448                                 float relAbund = lookup[i]->getAbundance(j);
449                                 if(relAbund > maxRelAbund[i]){  maxRelAbund[i] = relAbund;      }
450                         }
451                         if(maxRelAbund[i] > superMaxRelAbund){  superMaxRelAbund = maxRelAbund[i];      }
452                 }
453                 
454                 scaleRelAbund.resize(lookup.size());
455                 for(int i=0;i<lookup.size();i++){
456                         scaleRelAbund[i].assign(numBinsToDisplay, "");
457                         for(int j=0;j<numBinsToDisplay;j++){
458                                 if (m->control_pressed) {  return "control"; }
459                                 float relAbund = lookup[i]->getAbundance(j);
460                                 
461                                 if (lookup[i]->getAbundance(j) != 0) { //don't want log value of 0.
462                                         if (scaler == "log10") {
463                         if (maxRelAbund[i] == 1) { maxRelAbund[i] -= 0.001; }
464                         if (relAbund == 1) { relAbund -= 0.001; }
465                                                 scaleRelAbund[i][j] = toHex(int(255 * log10(relAbund) / log10(maxRelAbund[i]))) + "0000";  
466                                         }else if (scaler == "log2") {
467                         if (maxRelAbund[i] == 1) { maxRelAbund[i] -= 0.001; }
468                         if (relAbund == 1) { relAbund -= 0.001; }
469                                                 scaleRelAbund[i][j] = toHex(int(255 * log2(relAbund) / log2(maxRelAbund[i]))) + "0000";  
470                                         }else if (scaler == "linear") {
471                                                 scaleRelAbund[i][j] = toHex(int(255 * relAbund / maxRelAbund[i])) + "0000";
472                                         }else {  //if user enters invalid scaler option.
473                                                 scaleRelAbund[i][j] = toHex(int(255 * log10(relAbund / log10(maxRelAbund[i]))))  + "0000"; 
474                                         } 
475                                 }else { scaleRelAbund[i][j] = "FFFFFF";  }
476
477                         }
478                 }
479
480                 string filenamesvg = outputDir + m->getRootName(m->getSimpleName(inputfile)) + lookup[0]->getLabel() + ".heatmap.bin.svg";
481                 m->openOutputFile(filenamesvg, outsvg);
482         
483         int binHeight = 20;
484         int labelBump = 100;
485         int binWidth = 300;
486                 
487                 //svg image
488                 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() * binWidth + labelBump) + " " + toString((numBinsToDisplay*binHeight + 120))  + "\">\n";
489                 outsvg << "<g>\n";
490                 
491                 //white backround
492                 outsvg << "<rect fill=\"white\" stroke=\"white\" x=\"0\" y=\"0\" width=\"" + toString(lookup.size() * binWidth+labelBump) + "\" height=\"" + toString((numBinsToDisplay*binHeight + 120))  + "\"/>";
493                 outsvg << "<text fill=\"black\" class=\"seri\" font-size=\"" + toString(fontSize) + "\" text-anchor=\"middle\" x=\"" + toString((lookup.size() * 150) - 40) + "\" y=\"25\">Heatmap at distance " + lookup[0]->getLabel() + "</text>\n";
494                 
495                 //column labels
496                 for (int h = 0; h < lookup.size()+1; h++) {
497             if (h == 0) {
498                 string tempLabel = "OTU";
499                 outsvg << "<text fill=\"black\" class=\"seri\" font-size=\"" + toString(fontSize) + "\" x=\"" + toString(labelBump-labelBump/2+1) + "\" y=\"50\">" + tempLabel + "</text>\n";
500             }else {
501                 outsvg << "<text fill=\"black\" class=\"seri\" font-size=\"" + toString(fontSize) + "\" x=\"" + toString(((binWidth * h) - 150) - ((int)lookup[h-1]->getGroup().length() / 2)+labelBump/2) + "\" y=\"50\">" + lookup[h-1]->getGroup() + "</text>\n";
502             }
503                 }
504         
505                 //output legend and color labels
506                 string color;
507                 int x = 0;
508                 int y = 103 + (numBinsToDisplay*binHeight);
509                 printLegend(y, superMaxRelAbund);
510                 
511                 y = 70;
512                 for (int i = 0; i < numBinsToDisplay; i++) {
513             outsvg << "<text fill=\"black\" class=\"seri\" font-size=\"" + toString(fontSize) + "\" x=\"" + toString(x) + "\" y=\"" + toString(y) + "\">" + sortedLabels[i] + "</text>\n";
514             x += labelBump;
515                         for (int j = 0; j < scaleRelAbund.size(); j++) {
516                                 if (m->control_pressed) { outsvg.close(); return "control"; }
517                                 
518                                 outsvg << "<rect fill=\"#" + scaleRelAbund[j][i] + "\" stroke=\"#" + scaleRelAbund[j][i] + "\" x=\"" + toString(x) + "\" y=\"" + toString(y) + "\" width=\"" + toString(binWidth) +  "\" height=\"" + toString(binHeight) +  "\"/>\n";
519                                 x += binWidth;
520                         }
521                         x = 0;
522                         y += binHeight;
523                 }
524                 
525                 outsvg << "</g>\n</svg>\n";
526                 outsvg.close();
527                 
528                 return filenamesvg;
529
530         }
531         catch(exception& e) {
532                 m->errorOut(e, "HeatMap", "getPic");
533                 exit(1);
534         }
535 }
536 //**********************************************************************************************************************
537 vector<string> HeatMap::sortSharedVectors(vector<SharedRAbundFloatVector*>& lookup){
538         try {
539                                 
540                 vector<SharedRAbundFloatVector*> looktemp;
541                 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.
542                 map<int, int>::iterator it;
543         
544         vector<string> sortedLabels = m->currentSharedBinLabels;
545                 
546                 /****************** find order of otus **********************/
547                 if (sorted == "shared") {
548                         place = orderShared(lookup);    
549                 }else if (sorted == "topotu") {
550                         place = orderTopOtu(lookup);    
551                 }else if (sorted == "topgroup") {
552                         place = orderTopGroup(lookup);  
553                 }else { m->mothurOut("Error: invalid sort option."); m->mothurOutEndLine();  return sortedLabels; }
554                                 
555                 
556                 /******************* create copy of lookup *********************/
557                 //create and initialize looktemp as a copy of lookup
558                 for (int i = 0; i < lookup.size(); i++) { 
559                         SharedRAbundFloatVector* temp = new SharedRAbundFloatVector(lookup[i]->getNumBins());
560                         temp->setLabel(lookup[i]->getLabel());
561                         temp->setGroup(lookup[i]->getGroup());
562                         //copy lookup i's info
563                         for (int j = 0; j < lookup[i]->size(); j++) {
564                                 temp->set(j, lookup[i]->getAbundance(j), lookup[i]->getGroup());
565                         }
566                         looktemp.push_back(temp);
567                 }
568         
569                 /************************ fill lookup in order given by place *********************/
570                 //for each bin
571                 for (int i = 0; i < looktemp[0]->size(); i++) {                                                                                                         //place
572                         //fill lookup                                                                                                                                                                   // 2 -> 1
573                         for (int j = 0; j < looktemp.size(); j++) {                                                                                                             // 3 -> 2
574                                 float newAbund = looktemp[j]->getAbundance(i);                                                                                          // 1 -> 3
575                                 lookup[j]->set(place[i], newAbund, looktemp[j]->getGroup()); //binNumber, abundance, group
576                 sortedLabels[place[i]] = m->currentSharedBinLabels[i];
577                         }
578                 }
579                 
580                 //delete looktemp -- Sarah look at - this is causing segmentation faults
581                 for (int j = 0; j < looktemp.size(); j++) {
582 //                      delete looktemp[j];
583                 }
584                 
585                 return sortedLabels;
586                 
587         }
588         catch(exception& e) {
589                 m->errorOut(e, "HeatMap", "sortSharedVectors");
590                 exit(1);
591         }
592 }
593 //**********************************************************************************************************************
594 int HeatMap::sortRabund(RAbundVector*& r){
595         try {
596                 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.
597                 map<int, int>::iterator it;
598                 
599                 /****************** find order of otus **********************/
600                 vector<binCount> totals;
601                 
602                 //for each bin
603                 for (int i = 0; i < r->getNumBins(); i++) {     
604                         binCount temp(i, r->get(i));
605                         
606                         totals.push_back(temp);
607                 }
608                 
609                 sort(totals.begin(), totals.end(), comparebinCounts);
610                 
611                 //fill place
612                 for (int i = 0; i < totals.size(); i++) {   place[totals[i].bin] = i;  }
613                 
614                 /******************* create copy of lookup *********************/
615                 //create and initialize rtemp as a copy of r
616                 
617                 RAbundVector* rtemp = new RAbundVector(r->getNumBins());
618                 for (int i = 0; i < r->size(); i++) {  rtemp->set(i, r->get(i)); }
619                 rtemp->setLabel(r->getLabel());
620                         
621                 /************************ fill lookup in order given by place *********************/
622                 //for each bin
623                 for (int i = 0; i < rtemp->size(); i++) {                                                                               //place
624                         //fill lookup                                                                                                                           // 2 -> 1
625                                                                                                                                                                                 // 3 -> 2
626                         int newAbund = rtemp->get(i);                                                                                           // 1 -> 3
627                         r->set(place[i], newAbund); //binNumber, abundance
628                 }
629                 
630                 return 0;
631                 
632         }
633         catch(exception& e) {
634                 m->errorOut(e, "HeatMap", "sortRabund");
635                 exit(1);
636         }
637 }
638 //**********************************************************************************************************************
639 map<int, int> HeatMap::orderShared(vector<SharedRAbundFloatVector*>& lookup){
640         try {
641                                 
642                 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.
643                 map<int, int>::iterator it;
644                 
645                 vector<int> sharedBins;
646                 vector<int> uniqueBins;
647                 
648                 //for each bin
649                 for (int i = 0; i < lookup[0]->size(); i++) {   
650                         int count = 0;                                                                                          
651                         
652                         //is this bin shared
653                         for (int j = 0; j < lookup.size(); j++) {               if (lookup[j]->getAbundance(i) != 0) { count++; }       }
654                         
655                         if (count < 2)  {  uniqueBins.push_back(i); }
656                         else                    {  sharedBins.push_back(i); }
657                 }
658                 
659                 //fill place
660                 for (int i = 0; i < sharedBins.size(); i++) { place[sharedBins[i]] = i; }
661                 for (int i = 0; i < uniqueBins.size(); i++) { place[uniqueBins[i]] = (sharedBins.size() + i); }
662                 
663                 return place;
664                 
665         }
666         catch(exception& e) {
667                 m->errorOut(e, "HeatMap", "orderShared");
668                 exit(1);
669         }
670 }
671 //**********************************************************************************************************************
672 map<int, int> HeatMap::orderTopOtu(vector<SharedRAbundFloatVector*>& lookup){
673         try {
674                                 
675                 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.
676                 map<int, int>::iterator it;
677                 
678                 vector<binCountFloat> totals;
679                 
680                 //for each bin
681                 for (int i = 0; i < lookup[0]->size(); i++) {   
682                         int total = 0;                                                                                          
683                         
684                         for (int j = 0; j < lookup.size(); j++) {       total += lookup[j]->getAbundance(i);    }
685                         
686                         binCountFloat temp(i, total);
687                         
688                         totals.push_back(temp);
689                 }
690                 
691                 sort(totals.begin(), totals.end(), comparebinFloatCounts);
692                 
693                 //fill place
694                 for (int i = 0; i < totals.size(); i++) {   place[totals[i].bin] = i;  }
695                                 
696                 return place;
697                 
698         }
699         catch(exception& e) {
700                 m->errorOut(e, "HeatMap", "orderTopOtu");
701                 exit(1);
702         }
703 }
704 //**********************************************************************************************************************
705 map<int, int> HeatMap::orderTopGroup(vector<SharedRAbundFloatVector*>& lookup){
706         try {
707                                 
708                 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.
709                 map<int, int>::iterator it;
710                 
711                 vector < vector<binCountFloat> > totals; //totals[0] = bin totals for group 0, totals[1] = bin totals for group 1, ...
712                 totals.resize(lookup.size());
713                 
714                 //for each bin
715                 for (int i = 0; i < lookup[0]->size(); i++) {   
716                         for (int j = 0; j < lookup.size(); j++) {
717                                 binCountFloat temp(i, (lookup[j]->getAbundance(i)));
718                                 totals[j].push_back(temp);
719                         }
720                 }
721                 
722                 for (int i = 0; i < totals.size(); i++) { sort(totals[i].begin(), totals[i].end(), comparebinFloatCounts);  }
723                 
724                 //fill place
725                 //grab the top otu for each group adding it if its not already added
726                 int count = 0;
727                 for (int i = 0; i < totals[0].size(); i++) { 
728                 
729                         for (int j = 0; j < totals.size(); j++) {  
730                                 it = place.find(totals[j][i].bin);
731                                 
732                                 if (it == place.end()) { //not added yet
733                                         place[totals[j][i].bin] = count;
734                                         count++;
735                                 }
736                         }
737                 }
738                                 
739                 return place;
740                 
741         }
742         catch(exception& e) {
743                 m->errorOut(e, "HeatMap", "orderTopGroup");
744                 exit(1);
745         }
746 }
747 //**********************************************************************************************************************
748
749
750
751
752