nexml - index of /nexml/javascript/

Skip to: Site menu | Main content

The future data exchange standard is here!

nexml is an exchange standard for representing phylogenetic data — inspired by the commonly used NEXUS format, but more robust and easier to process.

Process nexml data

Directory listing

~ / nexml / javascript
digg reddit del.icio.us facebook | Tue Jan 6 02:08:03 2009 —

Nexml JavaScript libraries

The JS libraries are a port of a subset of Bio::Phylo's functionality. In particular, they implement most of the tree API, with the characters API in early development.

The libraries are useful for client side data pre- and post processing, for example in the widget on the front page, where these JS libraries interact with the Tree of Life web service through AJAX, parse the xml the service returns, reformat it to a newick string and pass it to the visualization widget.

Tree and node objects

Some neat things are possible, for example:

    // instantiate node object
    var root = new Phylo.Forest.Node( { 'name' : 'root' } );

    // instantiate tree object
    var tree = new Phylo.Forest.Tree( { 'name' : 'tree' } );

    // add root node to tree
    tree.insert(root);
    
    // build tree recursively, up to a depth of maxdepth    
    var maxdepth = 5;
    var nodecounter = 1;
    tree.visit_depth_first({
        'pre' : function (node) {
            if ( node.calc_nodes_to_root() < maxdepth ) {
                var left  = new Phylo.Forest.Node( { 'name' : 'left'  + nodecounter++ } );
                var right = new Phylo.Forest.Node( { 'name' : 'right' + nodecounter } ); 
                node.set_child(left);
                node.set_child(right);
                left.set_parent(node);
                right.set_parent(node);
                tree.insert(left,right);
            }
        }
    });
    
    alert(tree.to_newick());

Containers and nexml

    // now, create a "forest" object, a container for trees
    var forest = new Phylo.Forest({ 'name' : 'forest' });
    
    // add the tree to the forest container
    forest.insert(tree);
    
    // create a taxa container
    var taxa = new Phylo.Taxa({ 'name' : 'taxa' });
    
    // create a link between taxa and forest
    forest.set_taxa(taxa);
    
    // create taxon objects for all tips
    tree.get_terminals().map(
        function(tip) {
            var taxon = new Phylo.Taxa.Taxon({ 'name' : tip.get_name() });
            tip.set_taxon(taxon);
            taxa.insert(taxon);
        }
    );
    
    // and serialize to xml
    var xml = taxa.get_root_open_tag() 
        + taxa.to_xml()
        + forest.to_xml()
        + forest.get_root_close_tag();
    alert(xml);

Round-tripping trees nexml

    // now parse the xml, this returns an array of top level container objects
    var blocks = Phylo.IO.parse( { 'format' : 'nexml', 'string' : xml } );
    
    // find the forest object, get the parsed tree
    var parsed_tree;
    for ( var i = 0; i < blocks.length; i++ ) {
    
        // each "class" has a unique constant
        if ( blocks[i]._type() == Phylo.Util.CONSTANT._FOREST_() ) {
            parsed_tree = blocks[i].first();
            break;
        }
    }
    
    // ...and write out the round trip
    alert(parsed_tree.to_newick());

Character data

    // create a matrix object
    var matrix = new Phylo.Matrices.Matrix({
        'name':'matrix',
        'type':'Dna'
    });
    
    // create a datum object
    var datum = new Phylo.Matrices.Datum({
        'name':'datum',
        'type':'Dna'
    });
    
    // add some data
    datum.set_char(['acgt']);
    
    // add datum to matrix
    matrix.insert(datum);
    var taxa = new Phylo.Taxa();
    matrix.set_taxa(taxa);
    
    // write xml
    var xml = taxa.get_root_open_tag()
        + taxa.to_xml()
        + matrix.to_xml({'compact':false}) // when set to 'true', creates <seq> elements
        + taxa.get_root_close_tag();
    alert(xml);

Round-tripping characters nexml

    // now parse the taxa block and characters matrix
    var blocks = Phylo.IO.parse({
        'format':'nexml',
        'string':xml
    });
    
    // now loop over the blocks
    for ( var i in blocks ) {
        if ( blocks[i] == Phylo.Util.CONSTANT._TAXA_() ) {
            taxa = blocks[i];
        }
        else if ( blocks[i] == Phylo.Util.CONSTANT._MATRIX_() ) {
            matrix = blocks[i];
        }
    }
    
    // writes out the same info set as the input
    var xml = taxa.get_root_open_tag()
        + taxa.to_xml()
        + matrix.to_xml({'compact':false}) // when set to 'true', creates <seq> elements
        + taxa.get_root_close_tag();
    alert(xml);    

The Project object

	// the project object is a convenient container to clump data together
	var p = new Phylo.Project();
	Phylo.IO.parse({
		'format'  :'nexml',
		'string'  : xml,
		'project' : p,
	});
	alert(p.to_xml());
      Name                 Last modified       Size  Description

[DIR] Parent Directory 17-Dec-2008 14:31 - Folder [   ] Phylo.js 17-Dec-2008 14:31 2k Javascript [DIR] Phylo/ 17-Dec-2008 14:31 - Folder [TXT] phylo.html 17-Dec-2008 14:31 1k HTML document [   ] phylo.xhtml 08-Sep-2008 23:40 4k Folder [   ] phylolib.js 17-Dec-2008 14:31 1k Javascript [TXT] phylowidget.html 17-Dec-2008 14:31 3k HTML document [   ] phylowidget.js 17-Dec-2008 14:31 22k Javascript [   ] prototype.js 17-Dec-2008 14:31 94k Javascript [   ] tolwebajax.js 17-Dec-2008 14:31 3k Javascript