用于解析Newick格式的Java库或代码?

时间:2010-10-08 13:33:57

标签: java tree

任何人都知道我可以用来轻松解析Newick文件的好Java库吗?或者,如果您有一些经过测试的源代码,我可以使用吗?

我想在java中阅读newick文件:http://en.wikipedia.org/wiki/Newick_format并生成相同的可视化表示。我已经看到一些java程序可以做到这一点,但不容易找到解析在代码中的工作方式。

5 个答案:

答案 0 :(得分:2)

查看FigTree和BEAST成名的jebl(Java进化生物学库)。可能比您可能需要的树功能更多,但它是一个可靠的库。

答案 1 :(得分:1)

在寻找Java Newick解析器时偶然发现了这个问题。

我也遇到了libnewicktree,它似乎是来自Juxtaposer的Ne​​wick解析器的更新版本。

答案 2 :(得分:0)

似乎Tree Juxtaposer包含newick tree parser(但每个文件只限一棵树)。

答案 3 :(得分:0)

我喜欢使用基于Archaeopteryx库的forester库。它可以比解析和可视化树做更多的事情,但即使对于基本任务,它的使用仍然非常简单:

import java.io.IOException;    
import org.forester.archaeopteryx.Archaeopteryx;
import org.forester.phylogeny.Phylogeny;

public class PhylogenyTree {
    public static void main(String[] args) throws IOException{
        String nhx = "(mammal,(turtle,rayfinfish,(frog,salamander)))";
        Phylogeny ph = Phylogeny.createInstanceFromNhxString(nhx);
        Archaeopteryx.createApplication(ph);
    }

}

答案 4 :(得分:0)

这是我为个人使用而编写的Newick解析器。使用它健康;没有可视化。

import java.util.ArrayList;

/**
 * Created on 12/18/16
 *
 * @author @author <a href="mailto:knapp@american.edu">Adam Knapp</a>
 * @version 0.1
 */
public class NewickTree {

    private static int node_uuid = 0;
    ArrayList<Node> nodeList = new ArrayList<>();
    private Node root;

    static NewickTree readNewickFormat(String newick) {
        return new NewickTree().innerReadNewickFormat(newick);
    }

    private static String[] split(String s) {

        ArrayList<Integer> splitIndices = new ArrayList<>();

        int rightParenCount = 0;
        int leftParenCount = 0;
        for (int i = 0; i < s.length(); i++) {
            switch (s.charAt(i)) {
                case '(':
                    leftParenCount++;
                    break;
                case ')':
                    rightParenCount++;
                    break;
                case ',':
                    if (leftParenCount == rightParenCount) splitIndices.add(i);
                    break;
            }
        }

        int numSplits = splitIndices.size() + 1;
        String[] splits = new String[numSplits];

        if (numSplits == 1) {
            splits[0] = s;
        } else {

            splits[0] = s.substring(0, splitIndices.get(0));

            for (int i = 1; i < splitIndices.size(); i++) {
                splits[i] = s.substring(splitIndices.get(i - 1) + 1, splitIndices.get(i));
            }

            splits[numSplits - 1] = s.substring(splitIndices.get(splitIndices.size() - 1) + 1);
        }

        return splits;
    }

    private NewickTree innerReadNewickFormat(String newick) {

        // single branch = subtree (?)
        this.root = readSubtree(newick.substring(0, newick.length() - 1));

        return this;
    }

    private Node readSubtree(String s) {

        int leftParen = s.indexOf('(');
        int rightParen = s.lastIndexOf(')');

        if (leftParen != -1 && rightParen != -1) {

            String name = s.substring(rightParen + 1);
            String[] childrenString = split(s.substring(leftParen + 1, rightParen));

            Node node = new Node(name);
            node.children = new ArrayList<>();
            for (String sub : childrenString) {
                Node child = readSubtree(sub);
                node.children.add(child);
                child.parent = node;
            }

            nodeList.add(node);
            return node;
        } else if (leftParen == rightParen) {

            Node node = new Node(s);
            nodeList.add(node);
            return node;

        } else throw new RuntimeException("unbalanced ()'s");
    }

    static class Node {
        final String name;
        final int weight;
        boolean realName = false;
        ArrayList<Node> children;
        Node parent;

        /**
         * @param name name in "actualName:weight" format, weight defaults to zero if colon absent
         */
        Node(String name) {

            int colonIndex = name.indexOf(':');
            String actualNameText;
            if (colonIndex == -1) {
                actualNameText = name;
                weight = 0;
            } else {
                actualNameText = name.substring(0, colonIndex);
                weight = Integer.parseInt(name.substring(colonIndex + 1, name.length()));
            }

            if (actualNameText.equals("")) {
                this.realName = false;
                this.name = Integer.toString(node_uuid);
                node_uuid++;
            } else {
                this.realName = true;
                this.name = actualNameText;
            }
        }

        @Override
        public int hashCode() {
            return name.hashCode();
        }

        @Override
        public boolean equals(Object o) {
            if (!(o instanceof Node)) return false;
            Node other = (Node) o;
            return this.name.equals(other.name);
        }

        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();
            if (children != null && children.size() > 0) {
                sb.append("(");
                for (int i = 0; i < children.size() - 1; i++) {
                    sb.append(children.get(i).toString());
                    sb.append(",");
                }
                sb.append(children.get(children.size() - 1).toString());
                sb.append(")");
            }
            if (name != null) sb.append(this.getName());
            return sb.toString();
        }

        String getName() {
            if (realName)
                return name;
            else
                return "";
        }
    }

    @Override
    public String toString() {
        return root.toString() + ";";
    }

}