+}
+/*****************************************************************/
+//returns a map with a groupname and the number of times that group was seen in the children
+//for instance if your children are white and black then it would return a map with 2 entries
+// p[white] = 1 and p[black] = 1. Now go up a level and merge that with a node who has p[white] = 1
+//and you get p[white] = 2, p[black] = 1, but you erase the p[black] because you have a p value higher than 1.
+
+map<string, int> Tree::mergeUserGroups(int i, vector<string> g) {
+ try {
+
+ int lc = tree[i].getLChild();
+ int rc = tree[i].getRChild();
+
+ //loop through nodes groups removing the ones the user doesn't want
+ for(it=tree[lc].pGroups.begin();it!=tree[lc].pGroups.end();){
+ if (inUsersGroups(it->first, g) != true) {
+ tree[lc].pGroups.erase(it++);
+ }else { it++; }
+ }
+
+ //loop through nodes groups removing the ones the user doesn't want
+ for(it=tree[rc].pGroups.begin();it!=tree[rc].pGroups.end();){
+ if (inUsersGroups(it->first, g) != true) {
+ tree[rc].pGroups.erase(it++);
+ }else { it++; }
+ }
+
+ //set parsimony groups to left child
+ map<string,int> parsimony = tree[lc].pGroups;
+
+ int maxPars = 1;
+
+ //look at right child groups and update maxPars if right child has something higher for that group.
+ for(it=tree[rc].pGroups.begin();it!=tree[rc].pGroups.end();it++){
+ it2 = parsimony.find(it->first);
+ if (it2 != parsimony.end()) {
+ parsimony[it->first]++;
+ }else {
+ parsimony[it->first] = 1;
+ }
+
+ if(parsimony[it->first] > maxPars){
+ maxPars = parsimony[it->first];
+ }
+ }
+
+ // this is true if right child had a greater parsimony for a certain group
+ if(maxPars > 1){
+ //erase all the groups that are only 1 because you found something with 2.
+ for(it=parsimony.begin();it!=parsimony.end();){
+ if(it->second == 1){
+ parsimony.erase(it++);
+ }else { it++; }
+ }
+
+ for(it=parsimony.begin();it!=parsimony.end();it++){
+ parsimony[it->first] = 1;
+ }
+ }
+
+ return parsimony;
+ }
+ catch(exception& e) {
+ m->errorOut(e, "Tree", "mergeUserGroups");
+ exit(1);
+ }
+}
+
+
+/**************************************************************************************************/
+
+map<string,int> Tree::mergeGcounts(int position) {
+ try{
+ map<string,int>::iterator pos;
+
+ int lc = tree[position].getLChild();
+ int rc = tree[position].getRChild();
+
+ map<string,int> sum = tree[lc].pcount;
+
+ for(it=tree[rc].pcount.begin();it!=tree[rc].pcount.end();it++){
+ sum[it->first] += it->second;
+ }
+ return sum;
+ }
+ catch(exception& e) {
+ m->errorOut(e, "Tree", "mergeGcounts");
+ exit(1);
+ }
+}
+/**************************************************************************************************/
+
+void Tree::randomLabels(vector<string> g) {
+ try {
+
+ for(int i = 0; i < numLeaves; i++){
+ int z;
+ //get random index to switch with
+ z = int((float)(i+1) * (float)(rand()) / ((float)RAND_MAX+1.0));
+
+ //you only want to randomize the nodes that are from a group the user wants analyzed, so
+ //if either of the leaf nodes you are about to switch are not in the users groups then you don't want to switch them.
+ bool treez, treei;
+
+ treez = inUsersGroups(tree[z].getGroup(), g);
+ treei = inUsersGroups(tree[i].getGroup(), g);
+
+ if ((treez == true) && (treei == true)) {
+ //switches node i and node z's info.
+ map<string,int> lib_hold = tree[z].pGroups;
+ tree[z].pGroups = (tree[i].pGroups);
+ tree[i].pGroups = (lib_hold);
+
+ vector<string> zgroup = tree[z].getGroup();
+ tree[z].setGroup(tree[i].getGroup());
+ tree[i].setGroup(zgroup);
+
+ string zname = tree[z].getName();
+ tree[z].setName(tree[i].getName());
+ tree[i].setName(zname);
+
+ map<string,int> gcount_hold = tree[z].pcount;
+ tree[z].pcount = (tree[i].pcount);
+ tree[i].pcount = (gcount_hold);
+ }
+ }
+ }
+ catch(exception& e) {
+ m->errorOut(e, "Tree", "randomLabels");