Exemple #1
0
def ALEtreeToReconciledTree(ALEtree, isDead=False, isUndated=False, sepSp="_"):
    """
    Recursively builds the reconciled tree

    Takes:
        - ALEtree (ete3.TreeNode) : a tree read from a reconciled ttree in the ALE format (ie. reconciliation annotations are in the .name field)
        - isDead (bool) [default = False] : indicates whether or not this lineage starts in a dead/unsampled species

    Returns:
        (ReconciledTree)
    """

    isLeaf = ALEtree.is_leaf()

    annotation = None
    name = ALEtree.name
    if isLeaf:
        name, annotation = separateLeafNameFromLeafAnnotation(ALEtree.name,
                                                              sepSp=sepSp)
        #print("leaf parsing :", name , annotation)
    else:
        annotation = ALEtree.name

    #print "name : ",ALEtree.name

    events = parse_node_annotation(annotation,
                                   isLeaf,
                                   isDead=isDead,
                                   isUndated=isUndated)

    if isLeaf:
        ## we specify the species of the leaf event
        events[-1].species = getLeafSpeciesFromLeafName(ALEtree.name,
                                                        sepSp=sepSp)

    #print [str(e) for e in events]

    if events[-1].eventCode == "Bo":
        isDead = True  ## means that both children must begin by an event in the dead

    RT = ReconciledTree()
    RT.setName(name)

    current = RT

    for e in events:
        #        if e.eventCode.endswith("L"):
        #            #print "plep"
        #            current = treatLossEvent(current, e , ".c")
        #        else:
        #            current.addEvent(e)
        #
        current.addEvent(e)

    for c in ALEtree.children:  ##recursion on successors
        current.add_child(
            ALEtreeToReconciledTree(c, isDead, isUndated, sepSp=sepSp))

    return RT
def NHXtreeToBasicRecTree(nhxTree, spTree=None):
    """ 
    *RECURSIVE*

    From a tree read in a NHX format file to a ReconciledTree without any intermediary events (SpeciationLoss events)

    Takes:
        - nhxTree (ete3.TreeNode) : tree read from a NHX formatted line
        - spTree (ete3.Tree or None) [default = None] : if different from None, 
                                            internal node's events associated to species whose name is in the species tree will be kept as such
                                                        if equal to None,
                                            only leaves get to keep their associated species (and species of other events will have to be re-associated later)

    Returns:
        (ReconciledTree)

    """

    RT = ReconciledTree()

    eventCode = None
    species = None

    ## only terminal events in a DL context are considered here : leaf, speciation or duplication

    if nhxTree.is_leaf():
        eventCode = "C"
        species = nhxTree.S
        ## we only get the species for the leaves
        ##( as they are the only one where we   are sure the species is one that is present in the species tree)

    elif nhxTree.D == "Y":
        eventCode = "D"
    else:
        eventCode = "S"

    if not spTree is None:
        if len(spTree.search_nodes(
                name=nhxTree.S)) == 1:  ## not at all efficient ...
            species = nhxTree.S

    ##additional info:
    for f in nhxTree.features:
        RT.add_feature(f, nhxTree.__getattribute__(
            f))  ## stinks that we call thi __method__ ...

    evt = RecEvent(eventCode, species)
    RT.addEvent(evt)

    for c in nhxTree.children:
        RT.add_child(NHXtreeToBasicRecTree(c))
    return RT
def read_leaf(s):
    annot = parsePrIMEAnnotations(s)

    evt = PrIMEAnnotationToRecEvent(annot)

    leafNode = ReconciledTree()
    leafNode.setName(annot["name"])

    if annot.has_key("BL"):
        leafNode.dist = annot["BL"]

    leafNode.addEvent(evt)

    #print leafNode.getTreeRecPhyloXML()

    return leafNode
def read_leaf(s):
    annot = parseNotungAnnotations(s)

    evt = NotungAnnotationToRecEvent(annot)

    leafNode = ReconciledTree()
    leafNode.setName(annot["name"])

    if annot.has_key("BL"):
        leafNode.dist = annot["BL"]

    leafNode.addEvent(evt)

    if isSpeciationNode(leafNode):
        setNodeAsLeaf(leafNode)

    if ( not isLeafNode(leafNode) ) and (not isLossNode(leafNode)):
        AddLeafEvent(leafNode)

    return leafNode
Exemple #5
0
def MakeLossIndependentNode(node,
                            LossIndex,
                            lostSpecies="",
                            lostTS=None,
                            lostAdditional={},
                            keptChildNameSuffix=".c"):
    """
    *modifies node*

    Takes:
         - node (ReconciledTree): reconciled node where the *Loss event occurs
         - LossIndex (int): index of the speciationLoss or speciationOutLoss event
         - lostSpecies (str) [default = ""] : species of the loss
         - lostTS (int) [default = None]: timeSlice is the loss
         - lostAdditional [default = {}]: additional information to give to the new loss event
         - keptChildNameSuffix (str) [default = ".c"] : suffix to add to the name of the new child of node that is NOT a loss
    """

    # 1. create the loss child

    lossNode = ReconciledTree()
    lossNode.addEvent(
        RecEvent("loss",
                 lostSpecies,
                 ts=lostTS,
                 additionnalInfo=lostAdditional))
    lossNode.name = "LOSS"

    # 2. create the kept child

    keptNode = ReconciledTree()
    keptNode.name = node.name + keptChildNameSuffix

    while len(node.eventRecs) > (LossIndex + 1):
        #print LossIndex, LossIndex+1 , len(node.eventRecs)
        keptNode.addEvent(node.popEvent(LossIndex + 1))

    # 3. link children to kept child

    while len(node.children) > 0:
        c = node.children[0]
        c.detach()
        keptNode.add_child(c)

    # 4. branching loss and kept to original node

    node.add_child(lossNode)
    node.add_child(keptNode)

    # 5. editing the event

    e = node.eventRecs[LossIndex].eventCode
    node.eventRecs[LossIndex].eventCode = e[:-1]

    return
def readPrIMEParenthesis(s):

    if not s.startswith("("):
        print "error, should begin with a parenthesis"
        return

    #### parsiing parentheses

    i = 1
    new_n = ""
    info = ""

    childrenNodes = []

    inComment = False
    beginCommentChar = "["
    endCommentChar = "]"

    while i < len(s):

        if s[i] == beginCommentChar:
            inComment = True
        elif s[i] == endCommentChar:
            inComment = False

        #print i , s[i] , inComment

        if inComment:
            new_n += s[i]
        else:
            if s[i] == "(":  ##new parenthesis
                offset, child = readPrIMEParenthesis(s[i:])
                i += offset
                childrenNodes.append(child)
            #print "added new internal."

            if s[i] in [")", ","]:
                if not new_n == "":
                    #print "added leaf",new_n,"parent: current node"
                    childrenNodes.append(read_leaf(new_n))
                    #info = new_n
                new_n = ""
                if s[i] == ")":  ##end of the parenthesis
                    i += 1
                    break
            else:
                new_n += s[i]

        i += 1

    ##reading the internal node info

    while i < len(s):
        if s[i] == beginCommentChar:
            inComment = True
        elif s[i] == endCommentChar:
            inComment = False

        #print i , s[i] , inComment

        if not inComment:
            if s[i] in [")", ";", ","]:
                break
        info += s[i]
        i += 1

    #### building tree

    annot = parsePrIMEAnnotations(info)

    #print annot , [c.name for c in childrenNodes]

    evt = PrIMEAnnotationToRecEvent(annot)

    IntNode = ReconciledTree()
    IntNode.setName(annot["name"])

    if annot.has_key("BL"):
        IntNode.dist = annot["BL"]

    IntNode.addEvent(evt)

    ## checking if we are transfer
    if isTansferNode(IntNode):
        for c in childrenNodes:
            if not c.sameSpeciesAsParent(
                    parent=IntNode):  ## we found a children node
                addTbEvent(c)  ## we add the transferBack event

    if len(childrenNodes) > 1:
        ## two or more children, add them
        for c in childrenNodes:
            IntNode.add_child(c)
    elif len(childrenNodes) == 1:
        ## only one children. add its events to the current node
        for e in childrenNodes[0].getEvents():
            #print e
            IntNode.addEvent(e)

        for c in childrenNodes[0].get_children():
            IntNode.add_child(c)

    #print annot["name"],"-->",[n.getTreeNewick() for n in childrenNodes]

    return i, IntNode
def addSpeciationAndLoss(node , keptSpeciesNode):
    """
    *modifies node in place*

    Takes:
        - node (ReconciledTree): node where a SpeciationLoss must take place
        - keptSpeciesNode (ete3.TreeNode): node of the species tree where the lineage survived (ie. the sister species of the one where the loss occured)
    """
    parentSpeciesNode = keptSpeciesNode.up
    lossSpeciesNode = getSister(keptSpeciesNode)

    lossNode = ReconciledTree()
    lossNode.addEvent( RecEvent("loss" , lossSpeciesNode.name) )
    lossNode.name="LOSS"

    # 2. create the kept child

    keptNode = ReconciledTree()

    ##transfering the events of node to keptNode
    while len(node.eventRecs) >  0:
        keptNode.addEvent( node.popEvent(0), append=False )

    # 3. link children to kept child
    while len(node.children) > 0:
        c = node.children[0]
        c.detach()
        keptNode.add_child(c)


    # 4. branching loss and kept to original node

    node.add_child(lossNode)
    node.add_child(keptNode)

    # 5. editing the event
    e = RecEvent( "S" , keptSpeciesNode.up.name )
    node.addEvent( e,append = False) ##will insert the evt in first position
    
    return
Exemple #8
0
    def parse_clade(self, element, reconciled=True, obsoleteTagsBehaviour=1):
        """
        *recursive funtion*
    
        Takes:
            - element (Element) : element with the "clade" tag
            - reconciled (bool) [default = True] : whether the element passed should be considered a ReconciledTree or not
            - obsoleteTagsBehaviour (int) [default = 1]: 0 : ignore
                                                         1 : warning
                                                         2 : throw exception

        Returns:
            None : error
                or
            (ReconciledTree) : the reconciled tree
        """
        TAG = "clade"

        if not self.isOfTag(element, TAG):
            raise Exception('BadTagException. The element is of tag ' +
                            element.tag + " instead of " + TAG + ".")

        children = element.getchildren()

        name = None
        childrenNodes = []
        events = []

        additionnalInfo = {}

        for ch in children:
            if self.isOfTag(ch, "clade"):
                childrenNodes.append(
                    self.parse_clade(ch, reconciled, obsoleteTagsBehaviour))

            elif self.isOfTag(ch, "name"):
                name = self.parseSimpletextElement(ch)

            elif self.isOfTag(ch, "eventsRec"):
                events = self.parse_eventsRec(ch, obsoleteTagsBehaviour)

            else:
                ### treatment for other children
                additionnalInfo[self.tagCorrection(ch.tag)] = ch

        ### treatment for keys
        for k, v in element.items():
            if k != "rooted":
                additionnalInfo[k] = v

        node = None

        if reconciled:
            node = ReconciledTree()
        else:
            node = ete3.Tree()

        node.name = name

        if reconciled:
            for e in events:
                node.addEvent(e)

        for ch in childrenNodes:
            node.add_child(ch)

        if additionnalInfo.has_key("branch_length"):
            node.dist = float(additionnalInfo.pop("branch_length").text)
        if additionnalInfo.has_key("confidence"):
            node.support = float(additionnalInfo.pop("confidence").text)

        if len(additionnalInfo) > 0:
            node.add_features(**additionnalInfo)

        return node
def readNotungParenthesis(s):
    
    if not s.startswith("("):
        print "error, should begin with a parenthesis"
        return

    i = 1    
    new_n = ""
    info = "" 

    childrenNodes = []

    while i < len(s):
        if s[i] == "(":##new parenthesis
            offset , child = readNotungParenthesis(s[i:])
            i += offset
            childrenNodes.append(child)
#            print "added new internal."

        if s[i] in [")",","]:
            if not new_n == "":
                #print "added leaf",new_n,"parent: current node"
                childrenNodes.append( read_leaf(new_n) )
                #info = new_n
            new_n = ""
            if s[i] == ")":##end of the parenthesis
                i+=1
                break
        
        else:
            new_n += s[i]

        i+=1
        
    ##reading the internal node info

    while s[i] not in [")",";",","] and i < len(s):
        info += s[i]
        i+=1


    annot = parseNotungAnnotations( info )

    evt = NotungAnnotationToRecEvent(annot)

    IntNode = ReconciledTree()
    IntNode.setName(annot["name"])

    if annot.has_key("BL"):
        IntNode.dist = annot["BL"]

    IntNode.addEvent(evt)

    ## checking if : one of the child is a loss and/or a child is a transfer reception
    hasLoss = False
    hasTransfer = False
    j = 0
    while j < len(childrenNodes):
        c  = childrenNodes[j]
        if isLossNode(c):
            hasLoss = True
            #childrenNodes.pop(j)
            #continue
        if isTransferBackNode(c):
            hasTransfer = True
        j +=1


    if hasTransfer:
        setNodeAsTransfer(IntNode)

    #if hasLoss:
    #    setNodeAsXloss(IntNode)

    if len(childrenNodes) > 1:
        ## two or more children, add them
        for c in childrenNodes:
            IntNode.add_child(c)
    elif len(childrenNodes) == 1:
        ## only one children. add its events to the current node
        for e in childrenNodes[0].getEvents():
            #print e 
            IntNode.addEvent(e)

        for c in childrenNodes[0].get_children():
            IntNode.add_child(c)



    #print IntNode.getTreeRecPhyloXML()

    #print annot["name"],"-->",[n.getTreeNewick() for n in childrenNodes]
    
    return i, IntNode