示例#1
0
void
Tree::RootAt(PolyNode* inNode)	{

	double lengthbefore = GetLength();
	// inNode should not be root
	if (inNode->IsRoot())	{
		cerr << "error in PolyNode::RootAt : inNode is root\n";
		exit(1);
	}

	if (inNode)	{

		PolyNode* theUp = inNode->Up();
		PolyNode* newRoot = 0;


		if (theUp->IsRoot())	{
			inNode->Detach();
			if (theUp->down->next != theUp->down)	{
				newRoot = new PolyNode();
				newRoot->SetTree(this);
				theUp->AttachTo(newRoot);
				theUp->mProb = inNode->mProb;
			}
			else	{
				newRoot = theUp;
			}
		}

		else	{
			newRoot = theUp->FlipFlop();
			if ( ! newRoot)	{
				newRoot = new PolyNode();
				newRoot->SetTree(this);
			}
			inNode->Detach();
			theUp->AttachTo(newRoot);
			theUp->mProb = inNode->mProb;
		}
		inNode->AttachTo(newRoot);
		mRoot = newRoot;
	}

	double lengthafter = GetLength();
	if (fabs(lengthafter - lengthbefore) > 1e-8)	{
		cerr << "error in rerooting: length not conserved\n";
		cerr << "length before : " << lengthbefore << '\n';
		cerr << "length after  : " << lengthafter << '\n';
		cerr << lengthbefore - lengthafter << '\n';
		// exit(1);
	}

	double totallength = mRoot->down->branchLength + mRoot->down->next->branchLength;
	mRoot->down->branchLength  = totallength / 2;
	mRoot->down->next->branchLength  = totallength / 2;
	
}
示例#2
0
void Tree::Trichotomise()	{

	double lengthbefore = GetLength();
	PolyNode* node = mRoot->down;
	if (node->next->next == node)	{
		if (!node->IsLeaf())	{
			node = node->next;
		}
		else	{
			if (node->next->IsLeaf())	{
				cerr << "error : cannot trichotomise a two species tree\n";
				exit(1);
			}
		}

		PolyNode* temp = node->next;
		node->Detach();
		// PolyNode* temp = mRoot->down;
		mRoot->down = 0;
		// delete mRoot;
		mRoot = temp;
		mRoot->up = 0;
		node->branchLength += mRoot->branchLength;
		mRoot->branchLength = 0;
		node->AttachTo(mRoot);
	}
	double lengthafter = GetLength();
	if (fabs(lengthafter - lengthbefore) > 1e-8)	{
		cerr << "error in trichotomise: length not conserved\n";
		cerr << "length before : " << lengthbefore << '\n';
		cerr << "length after  : " << lengthafter << '\n';
		cerr << lengthbefore - lengthafter << '\n';
		exit(1);
	}
}
示例#3
0
int Tree::ReadPhylip(istream& is, PolyNode* currentNode)	{

// 	int verbose = 1;
	PolyNode* node = 0;
	double d;

	int END = 0;

	char c = is.peek();
	while ((c == ' ') || (c == '\n') || (c == '\t'))	{
		is.get();
		c = is.peek();
	}


	while( (! is.eof()) && (! END) )	{

		string s;
		char c = is.peek();

		// cerr << c ;

		switch (c)	{

			case '\n'  :
			case ' '   :
			case '\t'  :

				is >> c;

				if (verbose)	{
					cerr << c;
				}

				break;


			case '('   :

				is >> c;
				if (verbose)	{
					cerr << c;
				}

				// make a new polynode
				node = new PolyNode();
				node->AttachTo(currentNode);
				currentNode = node;

				break;


			case ','   :

				is >> c;
				if (verbose)	{
					cerr << c;
				}
				node = new PolyNode();
				if (currentNode->IsRoot())	{
					cerr << "error in reading tree file : found a coma not within brackets\n";
					exit(1);
				}
				node->AttachTo(currentNode->Up());
				currentNode = node;

				break;


			case ')' :

				is >> c;
				if (verbose)	{
					cerr << c;
				}
				if (currentNode->IsRoot())	{
					cerr << "error in reading tree file: found more closing than opening brackets\n";
					exit(1);
				}

				currentNode = currentNode->Up();

				// check whether is followed by a digit, a ':', a ')' or  a ',' (anything else will throw exception)
				c = is.peek();

				switch(c)	{

					case '0':
					case '1':
					case '2':
					case '3':
					case '4':
					case '5':
					case '6':
					case '7':
					case '8':
					case '9':

						// probability
						is >> d;
						if (verbose)	{
							cerr << d;
						}

						currentNode->SetProb(d);

						// then check whether is further followed by ':' or ',' or ')' (anything else exits)

						c = is.peek();

						switch(c)	{

							case ':' 	:

								is >> c;
								if (verbose)	{
									cerr << c;
								}

								// read branchLength
								// and check that it is followed either by ',' or by ')'

								is >> d;
								if (verbose)	{
									cerr << "BL" << d;
								}
								currentNode->SetBranchLength(d);

								c = is.peek();

								if ((c != ',') && (c != ')') && (c != ';'))	{
									cerr << "error\n";
									cerr << c << '\n';
									exit(1);
								}

							break;

							case ',' :
							case ')' :

							break;

							default	:

								cerr << "error in reading tree file : after reading a branchlength of an internal node\n";
								cerr << c << '\n';
								double d;
								is >> d;
								cerr << d << '\n';
								exit(1);

							break;
						}

					break;


					case ':' 	:

						is >> c;
						if (verbose)	{
							cerr << c;
						}

						// read branchLength
						// and check that it is followed either by ',' or by ')'
						is >> d;
						if (verbose)	{
							cerr << "BL" << d;
						}

						currentNode->SetBranchLength(d);

						c = is.peek();

						if ((c != ',') && (c != ')') && (c != ';'))	{
							cerr << "error\n";
							cerr << c << '\n';
							exit(1);
						}

					break;

					case ';' :
					case ',' :
					case ')' :
					break;

					default	:

						cerr << "error in reading tree file\n";
						cerr << "character : " << c << '\n';
						exit(1);

					break;

				}

			break;


			case ';'	:

				is >> c;
				if (verbose)	{
					cerr << "END" << c;
				}

				// close the tree
				// current node should be root
				if (! currentNode->IsRoot())	{
					cerr << "error in reading tree file : lacking closing brackets overall\n";
					exit(1);
				}

				END = 1;

			break;


			case '0':
			case '1':
			case '2':
			case '3':
			case '4':
			case '5':
			case '6':
			case '7':
			case '8':
			case '9':

				// species label

				s == "";
				do	{
					s += c;
					is >> c;
					if (is.eof())	{
						cerr << "error in reading treefile : unexpected end of file in string\n";
						exit(1);
					}
					c = is.peek();
				}	while ((c != ',') && (c != ':') && (c != ')'));
				if (IsInt(s))	{
					int i = Int(s);
					// is >> i;
					if (verbose)	{
						cerr << i;
					}
					node->SetLabel(i);
				}
				else	{
					node->SetName(s);
				}
				
				// check whether is followed by : or , or ) (anything else will throw exception)
				c = is.peek();

				switch(c)	{

					case ':' :

						is >> c;
						if (verbose)	{
							cerr << c;
						}

						// branchlength
						double d;
						is >> d;
						if (verbose)	{
							cerr << "BL" << d;
						}

						node->SetBranchLength(d);

						c = is.peek();

						if ((c != ',') && (c != ')'))	{
							cerr << "error\n";
							cerr << c << '\n';
							exit(1);
						}

					break;

					case ',' :
					case ')' :

					break;

					default	:

						cerr << "error in reading tree file\n";
						cerr << "character : " << c << '\n';
						exit(1);

					break;

				}

			break;

			default :

				// assume this is a species name

				s == "";
				do	{
					s += c;
					is >> c;
					if (is.eof())	{
						return 0;
					}
					c = is.peek();
				}	while ((c != ',') && (c != ':') && (c != ')'));

				currentNode->SetName(s);
				if (verbose)	{
					cerr << '\"' << s << '\"';
				}

				// check whether is followed by : or , (anything else will throw exception)
				c = is.peek();

				switch(c)	{

					case ':' :

						is >> c;
						if (verbose)	{
							cerr << c;
						}

						// branchlength
						double d;
						is >> d;
						if (verbose)	{
							cerr << "BL" << d;
						}

						node->SetBranchLength(d);
					break;



					case ',' :
					case ')':

					break;

					default	:

						cerr << "error in reading tree file : after reading species name\n";
						exit(1);

					break;

				}


			break;

		}
	}
	if (verbose)	{
		cerr << "tree read : ok " << '\n' << '\n';
		cerr.flush();
	}
	return 1;
}