<commit_before>/*
 * FlexibleTree.java
 *
 * Copyright (C) 2002-2006 <NAME> and <NAME>
 *
 * This file is part of BEAST.
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership and licensing.
 *
 * BEAST is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 *  BEAST is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with BEAST; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA  02110-1301  USA
 */

package dr.evolution.tree;

import dr.evolution.util.MutableTaxonListListener;
import dr.evolution.util.Taxon;
import dr.util.Attributable;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * data structure for binary rooted trees
 *
 * @author <NAME>
 * @author <NAME>
 * @version $Id: FlexibleTree.java,v 1.34 2006/07/02 21:14:52 rambaut Exp $
 */
public class FlexibleTree implements MutableTree {

    /**
     * Constructor tree with no nodes. Use adoptNodes to add some nodes.
     */
    public FlexibleTree() {
        root = null;
    }

    /**
     * clone constructor
     */
    public FlexibleTree(Tree tree) {
        this(tree, false);
    }

    /**
     * clone constructor
     */
    public FlexibleTree(Tree tree, boolean copyAttributes) {

        setUnits(tree.getUnits());

        root = new FlexibleNode(tree, tree.getRoot(), copyAttributes);

        nodeCount = tree.getNodeCount();
        internalNodeCount = tree.getInternalNodeCount();
        externalNodeCount = tree.getExternalNodeCount();


        nodes = new FlexibleNode[nodeCount];

        FlexibleNode node = root;
        do {
            node = (FlexibleNode) Tree.Utils.postorderSuccessor(this, node);
            if ((node.getNumber() >= externalNodeCount && node.isExternal()) ||
                    (node.getNumber() < externalNodeCount && !node.isExternal())) {
                throw new RuntimeException("Error cloning tree: node numbers are incompatible");
            }
            nodes[node.getNumber()] = node;
        } while (node != root);

        heightsKnown = tree.hasNodeHeights();
        lengthsKnown = tree.hasBranchLengths();
    }

    /**
     * clone constructor
     */
    public FlexibleTree(FlexibleNode root) {
        this(root, true, true, null);
    }

    /**
     * clone constructor
     */
    public FlexibleTree(FlexibleNode root, boolean heightsKnown, boolean lengthsKnown) {

        this(root, heightsKnown, lengthsKnown, null);
    }

    /**
     * clone constructor
     */
    public FlexibleTree(FlexibleNode root, Map<Taxon, Integer> taxonNumberMap) {
        this(root, true, true, taxonNumberMap);
    }

    /**
     * clone constructor
     */
    public FlexibleTree(FlexibleNode root, boolean heightsKnown, boolean lengthsKnown, Map<Taxon, Integer> taxonNumberMap) {

        adoptNodes(root, taxonNumberMap);

        this.heightsKnown = heightsKnown;
        this.lengthsKnown = lengthsKnown;

    }

    /**
     * @return a copy of this tree
     */
    public Tree getCopy() {
        return new FlexibleTree(this);
    }

    public void adoptTreeModelOrdering() {
        resolveTree();
        int i = 0;
        int j = externalNodeCount;

        FlexibleNode node = (FlexibleNode) getRoot();

        do {
            node = (FlexibleNode) Tree.Utils.postorderSuccessor(this, node);

            if (node.isExternal()) {
                node.setNumber(i);
                nodes[i] = node;
                i++;
            } else {
                node.setNumber(j);
                nodes[j] = node;
                j++;
            }
        } while (node != root);
    }

    /**
     * Adopt a node hierarchy as its own. Only called by the FlexibleTree(FlexibleNode, TaxonList).
     * This creates the node list and stores the nodes in post-traversal order.
     */
    protected void adoptNodes(FlexibleNode node, Map<Taxon, Integer> taxonNumberMap) {

        if (inEdit) throw new RuntimeException("Mustn't be in an edit transaction to call this method!");

        internalNodeCount = 0;
        externalNodeCount = 0;

        root = node;

        do {
            node = (FlexibleNode) Tree.Utils.postorderSuccessor(this, node);
            if (node.isExternal()) {
                externalNodeCount++;
            } else
                internalNodeCount++;

        } while (node != root);

        nodeCount = internalNodeCount + externalNodeCount;
        //System.out.println("internal count = " + internalNodeCount);
        //System.out.println("external count = " + externalNodeCount);

        nodes = new FlexibleNode[nodeCount];

        node = root;
        int i = 0;
        int j = externalNodeCount;

        do {
            node = (FlexibleNode) Tree.Utils.postorderSuccessor(this, node);
            //System.out.print("node = " + node.getId() + " ");
            if (node.isExternal()) {
                if (taxonNumberMap != null) {
                    i = taxonNumberMap.get(node.getTaxon());
                }

                node.setNumber(i);
                //System.out.println("  leaf number " + i);
                nodes[i] = node;

                if (taxonNumberMap == null) {
                    i++;
                }
            } else {
                node.setNumber(j);
                //System.out.println("  ancestor number " + j);
                nodes[j] = node;
                j++;
            }
        } while (node != root);
    }

    /**
     * Return the units that this tree is expressed in.
     */
    public final Type getUnits() {
        return units;
    }

    /**
     * Sets the units that this tree is expressed in.
     */
    public final void setUnits(Type units) {
        this.units = units;
    }

    /**
     * @return a count of the number of nodes (internal + external) in this
     *         tree.
     */
    public int getNodeCount() {<commit_msg>Fixed an issue with FlexibleTree not reading trees without translation tables.<commit_after>/*
 * FlexibleTree.java
 *
 * Copyright (C) 2002-2006 <NAME> and <NAME>
 *
 * This file is part of BEAST.
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership and licensing.
 *
 * BEAST is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 *  BEAST is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with BEAST; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA  02110-1301  USA
 */

package dr.evolution.tree;

import dr.evolution.util.MutableTaxonListListener;
import dr.evolution.util.Taxon;
import dr.util.Attributable;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * data structure for binary rooted trees
 *
 * @author <NAME>
 * @author <NAME>
 * @version $Id: FlexibleTree.java,v 1.34 2006/07/02 21:14:52 rambaut Exp $
 */
public class FlexibleTree implements MutableTree {

    /**
     * Constructor tree with no nodes. Use adoptNodes to add some nodes.
     */
    public FlexibleTree() {
        root = null;
    }

    /**
     * clone constructor
     */
    public FlexibleTree(Tree tree) {
        this(tree, false);
    }

    /**
     * clone constructor
     */
    public FlexibleTree(Tree tree, boolean copyAttributes) {

        setUnits(tree.getUnits());

        root = new FlexibleNode(tree, tree.getRoot(), copyAttributes);

        nodeCount = tree.getNodeCount();
        internalNodeCount = tree.getInternalNodeCount();
        externalNodeCount = tree.getExternalNodeCount();


        nodes = new FlexibleNode[nodeCount];

        FlexibleNode node = root;
        do {
            node = (FlexibleNode) Tree.Utils.postorderSuccessor(this, node);
            if ((node.getNumber() >= externalNodeCount && node.isExternal()) ||
                    (node.getNumber() < externalNodeCount && !node.isExternal())) {
                throw new RuntimeException("Error cloning tree: node numbers are incompatible");
            }
            nodes[node.getNumber()] = node;
        } while (node != root);

        heightsKnown = tree.hasNodeHeights();
        lengthsKnown = tree.hasBranchLengths();
    }

    /**
     * clone constructor
     */
    public FlexibleTree(FlexibleNode root) {
        this(root, true, true, null);
    }

    /**
     * clone constructor
     */
    public FlexibleTree(FlexibleNode root, boolean heightsKnown, boolean lengthsKnown) {

        this(root, heightsKnown, lengthsKnown, null);
    }

    /**
     * clone constructor
     */
    public FlexibleTree(FlexibleNode root, Map<Taxon, Integer> taxonNumberMap) {
        this(root, true, true, taxonNumberMap);
    }

    /**
     * clone constructor
     */
    public FlexibleTree(FlexibleNode root, boolean heightsKnown, boolean lengthsKnown, Map<Taxon, Integer> taxonNumberMap) {

        adoptNodes(root, taxonNumberMap);

        this.heightsKnown = heightsKnown;
        this.lengthsKnown = lengthsKnown;

    }

    /**
     * @return a copy of this tree
     */
    public Tree getCopy() {
        return new FlexibleTree(this);
    }

    public void adoptTreeModelOrdering() {
        resolveTree();
        int i = 0;
        int j = externalNodeCount;

        FlexibleNode node = (FlexibleNode) getRoot();

        do {
            node = (FlexibleNode) Tree.Utils.postorderSuccessor(this, node);

            if (node.isExternal()) {
                node.setNumber(i);
                nodes[i] = node;
                i++;
            } else {
                node.setNumber(j);
                nodes[j] = node;
                j++;
            }
        } while (node != root);
    }

    /**
     * Adopt a node hierarchy as its own. Only called by the FlexibleTree(FlexibleNode, TaxonList).
     * This creates the node list and stores the nodes in post-traversal order.
     */
    protected void adoptNodes(FlexibleNode node, Map<Taxon, Integer> taxonNumberMap) {

        if (inEdit) throw new RuntimeException("Mustn't be in an edit transaction to call this method!");

        internalNodeCount = 0;
        externalNodeCount = 0;

        root = node;

        do {
            node = (FlexibleNode) Tree.Utils.postorderSuccessor(this, node);
            if (node.isExternal()) {
                externalNodeCount++;
            } else
                internalNodeCount++;

        } while (node != root);

        nodeCount = internalNodeCount + externalNodeCount;
        //System.out.println("internal count = " + internalNodeCount);
        //System.out.println("external count = " + externalNodeCount);

        nodes = new FlexibleNode[nodeCount];

        node = root;
        int i = 0;
        int j = externalNodeCount;

        do {
            node = (FlexibleNode) Tree.Utils.postorderSuccessor(this, node);
            //System.out.print("node = " + node.getId() + " ");
            if (node.isExternal()) {
                if (taxonNumberMap != null && taxonNumberMap.size() > 0) {
                    i = taxonNumberMap.get(node.getTaxon());
                }

                node.setNumber(i);
                //System.out.println("  leaf number " + i);
                nodes[i] = node;

                if (taxonNumberMap == null || taxonNumberMap.size() == 0) {
                    i++;
                }
            } else {
                node.setNumber(j);
                //System.out.println("  ancestor number " + j);
                nodes[j] = node;
                j++;
            }
        } while (node != root);
    }

    /**
     * Return the units that this tree is expressed in.
     */
    public final Type getUnits() {
        return units;
    }

    /**
     * Sets the units that this tree is expressed in.
     */
    public final void setUnits(Type units) {
        this.units = units;
    }

    /**
     * @return a count of the number of nodes (internal + external) in this
     *         tree.
     */
    public int getNodeCount() {
{'fraction_non_alphanumeric': 0.10300693909020817, 'fraction_numerical': 0.006476484194294526, 'mean_word_length': 2.059198113207547, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 20, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4318889', 'n_tokens_mistral': 3746, 'n_tokens_neox': 3472, 'n_words': 1064}