def getGTree( db, treeId ):
   
    root = None

    parentStack = []

    for gnodeRow in db( ( db.gnode.tree == treeId ) &
                        ( db.gnode.pruned == False ) ).select( db.gnode.ALL, orderby = db.gnode.next ).as_list():

        node = Node()

        node.id = gnodeRow['id']; node.next = gnodeRow['next']; node.back = gnodeRow['back']
        node.label = gnodeRow['label']; node.depth = len( parentStack )

        if( node.next - node.back == 1 ):
            node.isleaf = True

        if( node.next == 1 ):
            node.isroot = True
            root = node
            parentStack.append( node )
            continue

        while( node.back > parentStack[ -1 ].back ):
            parentStack.pop() 

        parentStack[ -1 ].add_child( node )
        parentStack.append( node )

    return root
def getGClade( db, rootRec, collapsedNodeRecs ):
  
    cladeRoot = None

    parentStack = []

    query = db( ( db.gnode.tree == rootRec.tree ) &
                ( db.gnode.next >= rootRec.next ) &
                ( db.gnode.back <= rootRec.back ) )
    
    for rec in collapsedNodeRecs:
        query=query( ~( ( db.gnode.next > rec['gnode']['next'] ) & ( db.gnode.back < rec['gnode']['back'] ) ) )

    for gnodeRow in query.select( db.gnode.ALL, orderby = db.gnode.next ).as_list():

        node = Node()

        node.id = gnodeRow['id']; node.next = gnodeRow['next']; node.back = gnodeRow['back']
        node.label = gnodeRow['label']; node.depth = len( parentStack ); node.text = node.label


        if( node.next - node.back == 1 ):
            node.isleaf = True

        if( node.next == rootRec.next ):
            cladeRoot = node
            parentStack.append( node )
            continue

        while( node.back > parentStack[ -1 ].back ):
            parentStack.pop() 

        node.parent = parentStack[ -1 ]
        parentStack[ -1 ].add_child( node )
        parentStack.append( node )

    return cladeRoot
def getSClade( db, rootRec, collapsedNodeRecs ):
  
    cladeRoot = None

    parentStack = []

    query = db( ( db.snode.tree == rootRec.tree ) &
                ( db.snode.next >= rootRec.next ) &
                ( db.snode.back <= rootRec.back ) )

    for rec in collapsedNodeRecs:
        query=query( ~( ( db.snode.next > rec['snode']['next'] ) & ( db.snode.back < rec['snode']['back'] ) ) )

    for snodeRow in query.select( db.snode.ALL, db.taxon.ALL, left = db.taxon.on( db.taxon.id == db.snode.taxon ), orderby = db.snode.next ).as_list():

        node = Node()

        node.id = snodeRow['snode']['id']; node.next = snodeRow['snode']['next']; node.back = snodeRow['snode']['back']; node.length = snodeRow['snode']['length']
        node.label = snodeRow['snode']['label']; node.taxon = snodeRow['taxon']['name']; node.depth = len( parentStack ); node.text = node.taxon if node.taxon else node.label

        if( node.next - node.back == 1 ):
            node.isleaf = True

        if( node.next == rootRec.next ):
            cladeRoot = node
            parentStack.append( node )
            continue

        while( node.back > parentStack[ -1 ].back ):
            parentStack.pop() 

        node.parent = parentStack[ -1 ]
        parentStack[ -1 ].add_child( node )
        parentStack.append( node )

    return cladeRoot
def getSTree( db, treeId ):
   
    root = None

    parentStack = []

    for snodeRow in db( db.snode.tree == treeId ).select( db.snode.ALL, db.taxon.ALL, left = db.taxon.on( db.taxon.id == db.snode.taxon ), orderby = db.snode.next ).as_list():

        node = Node()

        node.id = snodeRow['snode']['id']; node.next = snodeRow['snode']['next']; node.back = snodeRow['snode']['back']; node.length = snodeRow['snode']['length']   
        node.label = snodeRow['snode']['label']; node.taxon = snodeRow['taxon']['name']; node.depth = len( parentStack )

        if( node.next - node.back == 1 ):
            node.isleaf = True

        if( node.next == 1 ):
            node.isroot = True
            root = node
            parentStack.append( node )
            continue

        while( node.back > parentStack[ -1 ].back ):
            parentStack.pop() 

        parentStack[ -1 ].add_child( node )
        parentStack.append( node )

    return root