X-Git-Url: https://git.donarmstrong.com/?p=mothur.git;a=blobdiff_plain;f=heatmap.cpp;h=514c7af15312b60d4787bb0aa659dbd9f1ccaf08;hp=aef9f3712d2a1ebedacbf2bf78d1a3a987fc2a1d;hb=b206f634aae1b4ce13978d203247fb64757d5482;hpb=e4c80376cc4533f66c8dfc18f3e1a86a60ac17fe diff --git a/heatmap.cpp b/heatmap.cpp index aef9f37..514c7af 100644 --- a/heatmap.cpp +++ b/heatmap.cpp @@ -10,9 +10,8 @@ #include "heatmap.h" //********************************************************************************************************************** -HeatMap::HeatMap(string sort, string scale, int num, int fsize, string dir){ +HeatMap::HeatMap(string sort, string scale, int num, int fsize, string dir, string i){ try { - globaldata = GlobalData::getInstance(); m = MothurOut::getInstance(); // format = globaldata->getFormat(); sorted = sort; @@ -20,6 +19,7 @@ HeatMap::HeatMap(string sort, string scale, int num, int fsize, string dir){ outputDir = dir; numOTU = num; fontSize = fsize; + inputfile = i; } catch(exception& e) { m->errorOut(e, "HeatMap", "HeatMap"); @@ -32,6 +32,14 @@ HeatMap::HeatMap(string sort, string scale, int num, int fsize, string dir){ string HeatMap::getPic(RAbundVector* rabund) { try { + int numBinsToDisplay = rabund->getNumBins(); + + if (numOTU != 0) { //user want to display a portion of the otus + if (numOTU < numBinsToDisplay) { numBinsToDisplay = numOTU; } + } + + //sort lookup so shared bins are on top + if (sorted != "none") { sortRabund(rabund); } float maxRelAbund = 0.0; @@ -40,10 +48,9 @@ string HeatMap::getPic(RAbundVector* rabund) { if(relAbund > maxRelAbund){ maxRelAbund = relAbund; } } + vector scaleRelAbund(numBinsToDisplay, ""); - vector scaleRelAbund(rabund->size(), ""); - - for(int i=0;isize();i++){ + for(int i=0;iget(i) / (float)rabund->getNumSeqs(); if (m->control_pressed) { return "control"; } @@ -63,24 +70,25 @@ string HeatMap::getPic(RAbundVector* rabund) { } - string filenamesvg = outputDir + getRootName(getSimpleName(globaldata->inputFileName)) + rabund->getLabel() + ".heatmap.bin.svg"; - openOutputFile(filenamesvg, outsvg); + string filenamesvg = outputDir + m->getRootName(m->getSimpleName(inputfile)) + rabund->getLabel() + ".heatmap.bin.svg"; + m->openOutputFile(filenamesvg, outsvg); //svg image - outsvg << "getNumBins()*5 + 120)) + "\">\n"; + outsvg << "\n"; outsvg << "\n"; //white backround - outsvg << "getNumBins()*5 + 120)) + "\"/>"; - outsvg << "Heatmap at distance " + rabund->getLabel() + "\n"; + outsvg << ""; + outsvg << "Heatmap at distance " + rabund->getLabel() + "\n"; //output legend and color labels string color; int x = 0; - int y = 103 + (rabund->getNumBins()*5); + int y = 103 + (numBinsToDisplay*5); printLegend(y, maxRelAbund); y = 70; + for (int i = 0; i < scaleRelAbund.size(); i++) { if (m->control_pressed) { outsvg.close(); return "control"; } @@ -111,10 +119,11 @@ string HeatMap::getPic(vector lookup) { } //sort lookup so shared bins are on top - if (sorted != "none") { sortSharedVectors(lookup); } + vector sortedLabels = m->currentSharedBinLabels; + if (sorted != "none") { sortedLabels = sortSharedVectors(lookup); } vector > scaleRelAbund; - vector maxRelAbund(lookup.size(), 0.0); + vector maxRelAbund(lookup[0]->size(), 0.0); float superMaxRelAbund = 0; for(int i = 0; i < lookup.size(); i++){ @@ -128,8 +137,8 @@ string HeatMap::getPic(vector lookup) { scaleRelAbund.resize(lookup.size()); for(int i=0;isize(), ""); - for(int j=0;jsize();j++){ + scaleRelAbund[i].assign(numBinsToDisplay, ""); + for(int j=0;jcontrol_pressed) { return "control"; } float relAbund = lookup[i]->getAbundance(j) / (float)lookup[i]->getNumSeqs(); @@ -148,38 +157,48 @@ string HeatMap::getPic(vector lookup) { } } - string filenamesvg = outputDir + getRootName(getSimpleName(globaldata->inputFileName)) + lookup[0]->getLabel() + ".heatmap.bin.svg"; - openOutputFile(filenamesvg, outsvg); + string filenamesvg = outputDir + m->getRootName(m->getSimpleName(inputfile)) + lookup[0]->getLabel() + ".heatmap.bin.svg"; + m->openOutputFile(filenamesvg, outsvg); + int binHeight = 20; + int labelBump = 100; + int binWidth = 300; //svg image - outsvg << "getNumBins()*5 + 120)) + "\">\n"; + outsvg << "\n"; outsvg << "\n"; //white backround - outsvg << "getNumBins()*5 + 120)) + "\"/>"; + outsvg << ""; outsvg << "Heatmap at distance " + lookup[0]->getLabel() + "\n"; //column labels - for (int h = 0; h < lookup.size(); h++) { - outsvg << "getGroup().length() / 2)) + "\" y=\"50\">" + lookup[h]->getGroup() + "\n"; + for (int h = 0; h < lookup.size()+1; h++) { + if (h == 0) { + string tempLabel = "OTU"; + outsvg << "" + tempLabel + "\n"; + }else { + outsvg << "getGroup().length() / 2)+labelBump/2) + "\" y=\"50\">" + lookup[h-1]->getGroup() + "\n"; + } } //output legend and color labels string color; int x = 0; - int y = 103 + (lookup[0]->getNumBins()*5); + int y = 103 + (numBinsToDisplay*binHeight); printLegend(y, superMaxRelAbund); y = 70; for (int i = 0; i < numBinsToDisplay; i++) { + outsvg << "" + sortedLabels[i] + "\n"; + x += labelBump; for (int j = 0; j < scaleRelAbund.size(); j++) { if (m->control_pressed) { outsvg.close(); return "control"; } - outsvg << "\n"; - x += 300; + outsvg << "\n"; + x += binWidth; } x = 0; - y += 5; + y += binHeight; } outsvg << "\n\n"; @@ -195,12 +214,14 @@ string HeatMap::getPic(vector lookup) { } //********************************************************************************************************************** -int HeatMap::sortSharedVectors(vector& lookup){ +vector HeatMap::sortSharedVectors(vector& lookup){ try { vector looktemp; map place; //spot in lookup where you insert shared by, ie, 3 -> 2 if they are shared by 3 inset into location 2. map::iterator it; + + vector sortedLabels = m->currentSharedBinLabels; /****************** find order of otus **********************/ if (sorted == "shared") { @@ -209,7 +230,7 @@ int HeatMap::sortSharedVectors(vector& lookup){ place = orderTopOtu(lookup); }else if (sorted == "topgroup") { place = orderTopGroup(lookup); - }else { m->mothurOut("Error: invalid sort option."); m->mothurOutEndLine(); return 1; } + }else { m->mothurOut("Error: invalid sort option."); m->mothurOutEndLine(); return sortedLabels; } /******************* create copy of lookup *********************/ @@ -233,6 +254,7 @@ int HeatMap::sortSharedVectors(vector& lookup){ int newAbund = looktemp[j]->getAbundance(i); // 1 -> 3 lookup[j]->set(place[i], newAbund, looktemp[j]->getGroup()); //binNumber, abundance, group } + sortedLabels[place[i]] = m->currentSharedBinLabels[i]; } //delete looktemp -- Sarah look at - this is causing segmentation faults @@ -240,7 +262,7 @@ int HeatMap::sortSharedVectors(vector& lookup){ // delete looktemp[j]; } - return 0; + return sortedLabels; } catch(exception& e) { @@ -398,6 +420,323 @@ void HeatMap::printLegend(int y, float maxbin) { } //********************************************************************************************************************** +string HeatMap::getPic(vector lookup) { + try { + + int numBinsToDisplay = lookup[0]->size(); + + if (numOTU != 0) { //user want to display a portion of the otus + if (numOTU < numBinsToDisplay) { numBinsToDisplay = numOTU; } + } + + //sort lookup so shared bins are on top + vector sortedLabels = m->currentSharedBinLabels; + if (sorted != "none") { sortedLabels = sortSharedVectors(lookup); } + + vector > scaleRelAbund; + vector maxRelAbund(lookup.size(), 0.0); + float superMaxRelAbund = 0; + + for(int i = 0; i < lookup.size(); i++){ + for(int j=0; jsize(); j++){ + + float relAbund = lookup[i]->getAbundance(j); + if(relAbund > maxRelAbund[i]){ maxRelAbund[i] = relAbund; } + } + if(maxRelAbund[i] > superMaxRelAbund){ superMaxRelAbund = maxRelAbund[i]; } + } + + scaleRelAbund.resize(lookup.size()); + for(int i=0;icontrol_pressed) { return "control"; } + float relAbund = lookup[i]->getAbundance(j); + + if (lookup[i]->getAbundance(j) != 0) { //don't want log value of 0. + if (scaler == "log10") { + scaleRelAbund[i][j] = toHex(int(255 * log10(relAbund) / log10(maxRelAbund[i]))) + "0000"; + }else if (scaler == "log2") { + scaleRelAbund[i][j] = toHex(int(255 * log2(relAbund) / log2(maxRelAbund[i]))) + "0000"; + }else if (scaler == "linear") { + scaleRelAbund[i][j] = toHex(int(255 * relAbund / maxRelAbund[i])) + "0000"; + }else { //if user enters invalid scaler option. + scaleRelAbund[i][j] = toHex(int(255 * log10(relAbund / log10(maxRelAbund[i])))) + "0000"; + } + }else { scaleRelAbund[i][j] = "FFFFFF"; } + + } + } + + string filenamesvg = outputDir + m->getRootName(m->getSimpleName(inputfile)) + lookup[0]->getLabel() + ".heatmap.bin.svg"; + m->openOutputFile(filenamesvg, outsvg); + + int binHeight = 20; + int labelBump = 100; + int binWidth = 300; + + //svg image + outsvg << "\n"; + outsvg << "\n"; + + //white backround + outsvg << ""; + outsvg << "Heatmap at distance " + lookup[0]->getLabel() + "\n"; + + //column labels + for (int h = 0; h < lookup.size()+1; h++) { + if (h == 0) { + string tempLabel = "OTU"; + outsvg << "" + tempLabel + "\n"; + }else { + outsvg << "getGroup().length() / 2)+labelBump/2) + "\" y=\"50\">" + lookup[h-1]->getGroup() + "\n"; + } + } + + //output legend and color labels + string color; + int x = 0; + int y = 103 + (numBinsToDisplay*binHeight); + printLegend(y, superMaxRelAbund); + + y = 70; + for (int i = 0; i < numBinsToDisplay; i++) { + outsvg << "" + sortedLabels[i] + "\n"; + x += labelBump; + for (int j = 0; j < scaleRelAbund.size(); j++) { + if (m->control_pressed) { outsvg.close(); return "control"; } + + outsvg << "\n"; + x += binWidth; + } + x = 0; + y += binHeight; + } + + outsvg << "\n\n"; + outsvg.close(); + + return filenamesvg; + + } + catch(exception& e) { + m->errorOut(e, "HeatMap", "getPic"); + exit(1); + } +} +//********************************************************************************************************************** +vector HeatMap::sortSharedVectors(vector& lookup){ + try { + + vector looktemp; + map place; //spot in lookup where you insert shared by, ie, 3 -> 2 if they are shared by 3 inset into location 2. + map::iterator it; + + vector sortedLabels = m->currentSharedBinLabels; + + /****************** find order of otus **********************/ + if (sorted == "shared") { + place = orderShared(lookup); + }else if (sorted == "topotu") { + place = orderTopOtu(lookup); + }else if (sorted == "topgroup") { + place = orderTopGroup(lookup); + }else { m->mothurOut("Error: invalid sort option."); m->mothurOutEndLine(); return sortedLabels; } + + + /******************* create copy of lookup *********************/ + //create and initialize looktemp as a copy of lookup + for (int i = 0; i < lookup.size(); i++) { + SharedRAbundFloatVector* temp = new SharedRAbundFloatVector(lookup[i]->getNumBins()); + temp->setLabel(lookup[i]->getLabel()); + temp->setGroup(lookup[i]->getGroup()); + //copy lookup i's info + for (int j = 0; j < lookup[i]->size(); j++) { + temp->set(j, lookup[i]->getAbundance(j), lookup[i]->getGroup()); + } + looktemp.push_back(temp); + } + + /************************ fill lookup in order given by place *********************/ + //for each bin + for (int i = 0; i < looktemp[0]->size(); i++) { //place + //fill lookup // 2 -> 1 + for (int j = 0; j < looktemp.size(); j++) { // 3 -> 2 + float newAbund = looktemp[j]->getAbundance(i); // 1 -> 3 + lookup[j]->set(place[i], newAbund, looktemp[j]->getGroup()); //binNumber, abundance, group + sortedLabels[place[i]] = m->currentSharedBinLabels[i]; + } + } + + //delete looktemp -- Sarah look at - this is causing segmentation faults + for (int j = 0; j < looktemp.size(); j++) { +// delete looktemp[j]; + } + + return sortedLabels; + + } + catch(exception& e) { + m->errorOut(e, "HeatMap", "sortSharedVectors"); + exit(1); + } +} +//********************************************************************************************************************** +int HeatMap::sortRabund(RAbundVector*& r){ + try { + map place; //spot in lookup where you insert shared by, ie, 3 -> 2 if they are shared by 3 inset into location 2. + map::iterator it; + + /****************** find order of otus **********************/ + vector totals; + + //for each bin + for (int i = 0; i < r->getNumBins(); i++) { + binCount temp(i, r->get(i)); + + totals.push_back(temp); + } + + sort(totals.begin(), totals.end(), comparebinCounts); + + //fill place + for (int i = 0; i < totals.size(); i++) { place[totals[i].bin] = i; } + + /******************* create copy of lookup *********************/ + //create and initialize rtemp as a copy of r + + RAbundVector* rtemp = new RAbundVector(r->getNumBins()); + for (int i = 0; i < r->size(); i++) { rtemp->set(i, r->get(i)); } + rtemp->setLabel(r->getLabel()); + + /************************ fill lookup in order given by place *********************/ + //for each bin + for (int i = 0; i < rtemp->size(); i++) { //place + //fill lookup // 2 -> 1 + // 3 -> 2 + int newAbund = rtemp->get(i); // 1 -> 3 + r->set(place[i], newAbund); //binNumber, abundance + } + + return 0; + + } + catch(exception& e) { + m->errorOut(e, "HeatMap", "sortRabund"); + exit(1); + } +} +//********************************************************************************************************************** +map HeatMap::orderShared(vector& lookup){ + try { + + map place; //spot in lookup where you insert shared by, ie, 3 -> 2 if they are shared by 3 inset into location 2. + map::iterator it; + + vector sharedBins; + vector uniqueBins; + + //for each bin + for (int i = 0; i < lookup[0]->size(); i++) { + int count = 0; + + //is this bin shared + for (int j = 0; j < lookup.size(); j++) { if (lookup[j]->getAbundance(i) != 0) { count++; } } + + if (count < 2) { uniqueBins.push_back(i); } + else { sharedBins.push_back(i); } + } + + //fill place + for (int i = 0; i < sharedBins.size(); i++) { place[sharedBins[i]] = i; } + for (int i = 0; i < uniqueBins.size(); i++) { place[uniqueBins[i]] = (sharedBins.size() + i); } + + return place; + + } + catch(exception& e) { + m->errorOut(e, "HeatMap", "orderShared"); + exit(1); + } +} +//********************************************************************************************************************** +map HeatMap::orderTopOtu(vector& lookup){ + try { + + map place; //spot in lookup where you insert shared by, ie, 3 -> 2 if they are shared by 3 inset into location 2. + map::iterator it; + + vector totals; + + //for each bin + for (int i = 0; i < lookup[0]->size(); i++) { + int total = 0; + + for (int j = 0; j < lookup.size(); j++) { total += lookup[j]->getAbundance(i); } + + binCountFloat temp(i, total); + + totals.push_back(temp); + } + + sort(totals.begin(), totals.end(), comparebinFloatCounts); + + //fill place + for (int i = 0; i < totals.size(); i++) { place[totals[i].bin] = i; } + + return place; + + } + catch(exception& e) { + m->errorOut(e, "HeatMap", "orderTopOtu"); + exit(1); + } +} +//********************************************************************************************************************** +map HeatMap::orderTopGroup(vector& lookup){ + try { + + map place; //spot in lookup where you insert shared by, ie, 3 -> 2 if they are shared by 3 inset into location 2. + map::iterator it; + + vector < vector > totals; //totals[0] = bin totals for group 0, totals[1] = bin totals for group 1, ... + totals.resize(lookup.size()); + + //for each bin + for (int i = 0; i < lookup[0]->size(); i++) { + for (int j = 0; j < lookup.size(); j++) { + binCountFloat temp(i, (lookup[j]->getAbundance(i))); + totals[j].push_back(temp); + } + } + + for (int i = 0; i < totals.size(); i++) { sort(totals[i].begin(), totals[i].end(), comparebinFloatCounts); } + + //fill place + //grab the top otu for each group adding it if its not already added + int count = 0; + for (int i = 0; i < totals[0].size(); i++) { + + for (int j = 0; j < totals.size(); j++) { + it = place.find(totals[j][i].bin); + + if (it == place.end()) { //not added yet + place[totals[j][i].bin] = count; + count++; + } + } + } + + return place; + + } + catch(exception& e) { + m->errorOut(e, "HeatMap", "orderTopGroup"); + exit(1); + } +} +//********************************************************************************************************************** +