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