//**********************************************************************************************************************
vector<string> IndicatorCommand::getRequiredParameters(){
try {
- string Array[] = {"label","tree"};
+ string Array[] = {"tree"};
vector<string> myArray (Array, Array+(sizeof(Array)/sizeof(string)));
return myArray;
}
else { inputFileName = relabundfile; }
groups = validParameter.validFile(parameters, "groups", false);
- if (groups == "not found") { groups = ""; pickedGroups = false; }
- else {
- pickedGroups = true;
- m->splitAtDash(groups, Groups);
- globaldata->Groups = Groups;
- }
+ if (groups == "not found") { groups = ""; Groups.push_back("all"); }
+ else { m->splitAtDash(groups, Groups); }
+ globaldata->Groups = Groups;
label = validParameter.validFile(parameters, "label", false);
- if (label == "not found") { label = ""; m->mothurOut("You must provide a label to process."); m->mothurOutEndLine(); abort = true; }
+ if (label == "not found") { label = ""; m->mothurOut("You did not provide a label, I will use the first label in your inputfile."); m->mothurOutEndLine(); label=""; }
if ((relabundfile == "") && (sharedfile == "")) { m->mothurOut("You must provide either a shared or relabund file."); m->mothurOutEndLine(); abort = true; }
void IndicatorCommand::help(){
try {
m->mothurOut("The indicator command reads a shared or relabund file and a tree file, and outputs a .indicator.tre and .indicator.summary file. \n");
- m->mothurOut("The new tree contains labels at each internal node. The label is the OTU number of the indicator OTU.\n");
+ m->mothurOut("The new tree contains labels at each internal node. The label is the node number so you can relate the tree to the summary file.\n");
m->mothurOut("The summary file lists the indicator value for each OTU for each node.\n");
- m->mothurOut("The indicator command parameters are tree, groups, shared, relabund and label. The tree and label parameter are required as well as either shared or relabund.\n");
+ m->mothurOut("The indicator command parameters are tree, groups, shared, relabund and label. The tree parameter is required as well as either shared or relabund.\n");
m->mothurOut("The groups parameter allows you to specify which of the groups in your shared or relabund you would like analyzed. The groups may be entered separated by dashes.\n");
m->mothurOut("The label parameter indicates at what distance your tree relates to the shared or relabund.\n");
m->mothurOut("The indicator command should be used in the following format: indicator(tree=test.tre, shared=test.shared, label=0.03)\n");
/***************************************************/
Tree* outputTree = new Tree(globaldata->Groups.size());
- if (pickedGroups) {
- outputTree->getSubTree(T[0], globaldata->Groups);
- outputTree->assembleTree();
- }else{
- outputTree->getCopy(T[0]);
- outputTree->assembleTree();
- }
-
+ outputTree->getSubTree(T[0], globaldata->Groups);
+ outputTree->assembleTree();
+
//no longer need original tree, we have output tree to use and label
for (int i = 0; i < T.size(); i++) { delete T[i]; } globaldata->gTree.clear();
+
if (m->control_pressed) {
if (sharedfile != "") { for (int i = 0; i < lookup.size(); i++) { delete lookup[i]; } }
else { for (int i = 0; i < lookupFloat.size(); i++) { delete lookupFloat[i]; } }
//report all otu values to file
int IndicatorCommand::GetIndicatorSpecies(Tree*& T){
try {
+
string thisOutputDir = outputDir;
if (outputDir == "") { thisOutputDir += m->hasPath(inputFileName); }
string outputFileName = thisOutputDir + m->getRootName(m->getSimpleName(inputFileName)) + "indicator.summary";
ofstream out;
m->openOutputFile(outputFileName, out);
- out << "Node\tOTU#\tIndVal" << endl;
-
+ out.setf(ios::fixed, ios::floatfield); out.setf(ios::showpoint);
+
string treeOutputDir = outputDir;
if (outputDir == "") { treeOutputDir += m->hasPath(treefile); }
string outputTreeFileName = treeOutputDir + m->getRootName(m->getSimpleName(treefile)) + "indicator.tre";
//you need the distances to leaf to decide grouping below
//this will also set branch lengths if the tree does not include them
- map<int, float> distToLeaf = getLengthToLeaf(T);
+ map<int, float> distToRoot = getDistToRoot(T);
//for each node
for (int i = T->getNumLeaves(); i < T->getNumNodes(); i++) {
if (sharedfile != "") {
vector< vector<SharedRAbundVector*> > groupings;
- /*groupings.resize(1);
- groupings[0].push_back(lookup[0]);
- groupings[0].push_back(lookup[1]);
- groupings[0].push_back(lookup[2]);
- groupings[0].push_back(lookup[3]);
- groupings[0].push_back(lookup[4]);*/
-
//get nodes that will be a valid grouping
//you are valid if you are not one of my descendants
- //AND your distToLeaf is <= mine
- //AND your distToLeaf is >= my smallest childs
- //AND you were not added as part of a larger grouping
+ //AND your distToRoot is >= mine
+ //AND you were not added as part of a larger grouping. Largest nodes are added first.
+
set<string> groupsAlreadyAdded;
+ //create a grouping with my grouping
+ vector<SharedRAbundVector*> subset;
+ int count = 0;
+ int doneCount = nodeToDescendants[i].size();
+ for (int k = 0; k < lookup.size(); k++) {
+ //is this descendant of i
+ if ((nodeToDescendants[i].count(lookup[k]->getGroup()) != 0)) {
+ subset.push_back(lookup[k]);
+ groupsAlreadyAdded.insert(lookup[k]->getGroup());
+ count++;
+ }
+ if (count == doneCount) { break; } //quit once you get the rabunds for this grouping
+ }
+ if (subset.size() != 0) { groupings.push_back(subset); }
+
+
for (int j = (T->getNumNodes()-1); j >= 0; j--) {
- if ((descendantNodes[i].count(j) == 0) && (distToLeaf[j] <= distToLeaf[i]) && ((distToLeaf[j] >= distToLeaf[T->tree[i].getLChild()]) || (distToLeaf[j] >= distToLeaf[T->tree[i].getRChild()]))) {
+
+
+ if ((descendantNodes[i].count(j) == 0) && (distToRoot[j] >= distToRoot[i])) {
vector<SharedRAbundVector*> subset;
int count = 0;
int doneCount = nodeToDescendants[j].size();
}
}
- if (groupsAlreadyAdded.size() != lookup.size()) { m->mothurOut("[ERROR]: could not make proper groupings."); m->mothurOutEndLine(); }
+ if (groupsAlreadyAdded.size() != lookup.size()) { m->mothurOut("[ERROR]: could not make proper groupings."); m->mothurOutEndLine(); }
+ //for (int k = 0; k < lookup.size(); k++) {
+ // if (groupsAlreadyAdded.count(lookup[k]->getGroup()) == 0) { cout << lookup[k]->getGroup() << endl; }
+ //}
indicatorValues = getValues(groupings);
//get nodes that will be a valid grouping
//you are valid if you are not one of my descendants
- //AND your distToLeaf is <= mine
- //AND your distToLeaf is >= my smallest childs
- //AND you were not added as part of a larger grouping
+ //AND your distToRoot is >= mine
+ //AND you were not added as part of a larger grouping. Largest nodes are added first.
+
set<string> groupsAlreadyAdded;
+ //create a grouping with my grouping
+ vector<SharedRAbundFloatVector*> subset;
+ int count = 0;
+ int doneCount = nodeToDescendants[i].size();
+ for (int k = 0; k < lookupFloat.size(); k++) {
+ //is this descendant of i
+ if ((nodeToDescendants[i].count(lookupFloat[k]->getGroup()) != 0)) {
+ subset.push_back(lookupFloat[k]);
+ groupsAlreadyAdded.insert(lookupFloat[k]->getGroup());
+ count++;
+ }
+ if (count == doneCount) { break; } //quit once you get the rabunds for this grouping
+ }
+ if (subset.size() != 0) { groupings.push_back(subset); }
+
for (int j = (T->getNumNodes()-1); j >= 0; j--) {
- if ((descendantNodes[i].count(j) == 0) && (distToLeaf[j] <= distToLeaf[i]) && ((distToLeaf[j] >= distToLeaf[T->tree[i].getLChild()]) || (distToLeaf[j] >= distToLeaf[T->tree[i].getRChild()]))) {
+ if ((descendantNodes[i].count(j) == 0) && (distToRoot[j] >= distToRoot[i])) {
vector<SharedRAbundFloatVector*> subset;
int count = 0;
int doneCount = nodeToDescendants[j].size();
if (m->control_pressed) { out.close(); return 0; }
+
/******************************************************/
//output indicator values to table form + label tree //
/*****************************************************/
- vector<int> indicatorOTUs;
- float largestValue = 0.0;
+ out << (i+1) << '\t';
for (int j = 0; j < indicatorValues.size(); j++) {
if (m->control_pressed) { out.close(); return 0; }
- out << (i+1) << '\t' << (j+1) << '\t' << indicatorValues[j] << endl;
-
- //show no favortism
- if (indicatorValues[j] > largestValue) {
- largestValue = indicatorValues[j];
- indicatorOTUs.clear();
- indicatorOTUs.push_back(j+1);
- }else if (indicatorValues[j] == largestValue) {
- indicatorOTUs.push_back(j+1);
- }
-
- random_shuffle(indicatorOTUs.begin(), indicatorOTUs.end());
-
- T->tree[i].setLabel(indicatorOTUs[0]);
+ out << indicatorValues[j] << '\t';
}
+ out << endl;
+
+ T->tree[i].setLabel((i+1));
}
out.close();
}
}
//**********************************************************************************************************************
-//you need the distances to leaf to decide groupings
+//you need the distances to root to decide groupings
//this will also set branch lengths if the tree does not include them
-map<int, float> IndicatorCommand::getLengthToLeaf(Tree*& T){
+map<int, float> IndicatorCommand::getDistToRoot(Tree*& T){
try {
map<int, float> dists;
- for (int i = 0; i < T->getNumNodes(); i++) {
-
- int lc = T->tree[i].getLChild();
- int rc = T->tree[i].getRChild();
-
- //if you have no branch length, set it then calc
- if (T->tree[i].getBranchLength() <= 0.0) {
+ bool hasBranchLengths = false;
+ for (int i = 0; i < T->getNumNodes(); i++) {
+ if (T->tree[i].getBranchLength() > 0.0) { hasBranchLengths = true; break; }
+ }
+
+ //set branchlengths if needed
+ if (!hasBranchLengths) {
+ for (int i = 0; i < T->getNumNodes(); i++) {
+
+ int lc = T->tree[i].getLChild();
+ int rc = T->tree[i].getRChild();
if (lc == -1) { // you are a leaf
//if you are a leaf set you priliminary length to 1.0, this may adjust later
T->tree[i].setBranchLength(1.0);
- dists[i] = 0.0;
+ dists[i] = 1.0;
}else{ // you are an internal node
//look at your children's length to leaf
float ldist = dists[lc];
float rdist = dists[rc];
- float greater;
- if (rdist > greater) { greater = rdist; }
- else { greater = ldist; }
+ float greater = ldist;
+ if (rdist > greater) { greater = rdist; dists[i] = ldist + 1.0;}
+ else { dists[i] = rdist + 1.0; }
+
//branch length = difference + 1
T->tree[lc].setBranchLength((abs(ldist-greater) + 1.0));
T->tree[rc].setBranchLength((abs(rdist-greater) + 1.0));
-
- dists[i] = dists[lc] + (abs(ldist-greater) + 1.0);
}
-
- }else{
- if (lc == -1) { dists[i] = 0.0; }
- else { dists[i] = dists[lc] + T->tree[lc].getBranchLength(); }
}
+ }
+
+ dists.clear();
+
+ for (int i = 0; i < T->getNumNodes(); i++) {
+
+ double sum = 0.0;
+ int index = i;
+ while(T->tree[index].getParent() != -1){
+ if (T->tree[index].getBranchLength() != -1) {
+ sum += abs(T->tree[index].getBranchLength());
+ }
+ index = T->tree[index].getParent();
+ }
+
+ dists[i] = sum;
}
return dists;
for (set<int>::iterator itNum = nodes[rc].begin(); itNum != nodes[rc].end(); itNum++) {
nodes[i].insert(*itNum);
}
+ //you are your own descendant
+ nodes[i].insert(i);
}
return names;
lookup = input->getSharedRAbundVectors();
string lastLabel = lookup[0]->getLabel();
+ if (label == "") { label = lastLabel; delete input; return 0; }
+
//if the users enters label "0.06" and there is no "0.06" in their file use the next lowest label.
set<string> labels; labels.insert(label);
set<string> processedLabels;
lookupFloat = input->getSharedRAbundFloatVectors();
string lastLabel = lookupFloat[0]->getLabel();
+ if (label == "") { label = lastLabel; delete input; return 0; }
+
//if the users enters label "0.06" and there is no "0.06" in their file use the next lowest label.
set<string> labels; labels.insert(label);
set<string> processedLabels;