def A(parasiteTree, hostTree, phi, ep, eh): ''' The A table for the dynamic program. ''' global Amemo if (ep, eh) in Amemo: return Amemo[(ep, eh)] if tipEdge(eh, hostTree): if tipEdge(ep, parasiteTree) and \ phi[endVertex(ep, parasiteTree)] == endVertex(eh, hostTree): return [CostVector(0, 0, 0, 0, 1)] else: return [CostVector(INF, INF, INF, INF, 0)] else: ehLeftChild = leftChildEdge(eh, hostTree) ehRightChild = rightChildEdge(eh, hostTree) # Cospeciation if tipEdge(ep, parasiteTree): cospeciation = [CostVector(INF, INF, INF, INF, 0)] else: epLeftChild = leftChildEdge(ep, parasiteTree) epRightChild = rightChildEdge(ep, parasiteTree) cospeciation1 = merge(C(parasiteTree, hostTree, phi, \ epLeftChild, ehLeftChild), \ C(parasiteTree, hostTree, phi, \ epRightChild, ehRightChild), \ ep, eh, epLeftChild, ehLeftChild, \ epRightChild, ehRightChild, "cospeciation") cospeciation2 = merge(C(parasiteTree, hostTree, phi, \ epLeftChild, ehRightChild), \ C(parasiteTree, hostTree, phi, \ epRightChild, ehLeftChild), \ ep, eh, epLeftChild, ehRightChild, \ epRightChild, ehLeftChild, "cospeciation") cospeciation = cospeciation1 + cospeciation2 # Loss loss1 = lossmerge(ep, eh, ehLeftChild, \ C(parasiteTree, hostTree, phi, ep, ehLeftChild)) loss2 = lossmerge(ep, eh, ehRightChild, \ C(parasiteTree, hostTree, phi, ep, ehRightChild)) loss = loss1 + loss2 output = paretoFilter(cospeciation + loss) Amemo[(ep, eh)] = output return output
def merge(CVlist1, CVlist2, ep, eh, epChild1, ehChild1, epChild2, \ ehChild2, eventType): ''' Given two lists of CostVectors, returns a new list of CostVectors, each of which is the sum of a pair of vectors from the two given lists.''' global CVevents global CVallEvents global CandidateCVlist intersection = CONFIG.intersection if intersection: global CVseen global CVcommonEvents output = [] for v in CVlist1: for w in CVlist2: if eventType == "cospeciation": newCV = CostVector(1, 0, 0, 0, 1) + v + w elif eventType == "duplication": newCV = CostVector(0, 1, 0, 0, 1) + v + w else: # eventType == "switch": newCV = CostVector(0, 0, 1, 0, 1) + v + w keepnewCV = True for cv in CandidateCVlist: if cv < newCV: keepnewCV = False break if keepnewCV: output.append(newCV) vsoln = (epChild1, ehChild1) + v.toTupleCDSL() wsoln = (epChild2, ehChild2) + w.toTupleCDSL() if eventType == "switch": eventType = "switch to " + str(ehChild2) nswe = (ep, eh, eventType) + newCV.toTupleCDSL() ns = (ep, eh) + newCV.toTupleCDSL() CVevents[nswe].add(nswe) CVevents[nswe] = CVevents[nswe].\ union(CVallEvents[vsoln]).\ union(CVallEvents[wsoln]) CVallEvents[ns] = CVallEvents[ns].union(CVevents[nswe]) if intersection: key = newCV.toTupleCDSL() if CVseen[key]: CVcommonEvents[key] = CVcommonEvents[key].\ intersection(CVevents[nswe]) else: CVcommonEvents[key] = CVevents[nswe] CVseen[key] = True return output
def C(parasiteTree, hostTree, phi, ep, eh): ''' The C table for the dynamic program. ''' global Cmemo if (ep, eh) in Cmemo: return Cmemo[(ep, eh)] # Option 1: Pass through passThrough = A(parasiteTree, hostTree, phi, ep, eh) if tipEdge(ep, parasiteTree): # The options below don't apply to tips return passThrough else: epLeftChild = leftChildEdge(ep, parasiteTree) epRightChild = rightChildEdge(ep, parasiteTree) # Option 2: Duplicate here duplicate = CostVector(0, 1, 0, 0, 1) * \ merge(C(parasiteTree, hostTree, phi, epLeftChild, eh), \ C(parasiteTree, hostTree, phi, epRightChild, eh)) # Option 3: Switch here switch1 = CostVector(0, 0, 1, 0, 1) * \ merge(C(parasiteTree, hostTree, phi, epLeftChild, eh), \ switches(parasiteTree, hostTree, phi, epRightChild, eh)) switch2 = CostVector(0, 0, 1, 0, 1) * \ merge(C(parasiteTree, hostTree, phi, epRightChild, eh), \ switches(parasiteTree, hostTree, phi, epLeftChild, eh)) switch = switch1 + switch2 output = paretoFilter(passThrough + duplicate + switch) Cmemo[(ep, eh)] = output return output
def lossmerge(ep, eh, ehChild, CVlist): global CVevents global CVallEvents global CandidateCVlist intersection = CONFIG.intersection if intersection: global CVseen global CVcommonEvents output = [] for v in CVlist: newCV = CostVector(0, 0, 0, 1, 1) + v keepnewCV = True for cv in CandidateCVlist: if cv < newCV: keepnewCV = False break if keepnewCV: output.append(newCV) vsoln = (ep, ehChild) + v.toTupleCDSL() nswe = (ep, eh, "loss " + str(ehChild)) + newCV.toTupleCDSL() ns = (ep, eh) + newCV.toTupleCDSL() CVevents[nswe].add(nswe) CVevents[nswe] = CVevents[nswe].union(CVallEvents[vsoln]) CVallEvents[ns] = CVallEvents[ns].union(CVevents[nswe]) if intersection: key = newCV.toTupleCDSL() if CVseen[key]: CVcommonEvents[key] = CVcommonEvents[key].\ intersection(CVevents[nswe]) else: CVcommonEvents[key] = CVevents[nswe] CVseen[key] = True return output
def lossmerge(ep, eh, ehChild, CVlist): global CVevents global CVallEvents global CandidateCVlist intersection = CONFIG.intersection if intersection: global CVseen global CVcommonEvents output = [] for v in CVlist: newCV = CostVector(0, 0, 0, 1, 1) + v keepnewCV = True for cv in CandidateCVlist: if cv < newCV: keepnewCV = False break if keepnewCV: output.append(newCV) vsoln = (ep, ehChild) + v.toTupleCDSL() nswe = (ep, eh, "loss "+str(ehChild)) + newCV.toTupleCDSL() ns = (ep, eh) + newCV.toTupleCDSL() CVevents[nswe].add(nswe) CVevents[nswe] = CVevents[nswe].union(CVallEvents[vsoln]) CVallEvents[ns] = CVallEvents[ns].union(CVevents[nswe]) if intersection: key = newCV.toTupleCDSL() if CVseen[key]: CVcommonEvents[key] = CVcommonEvents[key].\ intersection(CVevents[nswe]) else: CVcommonEvents[key] = CVevents[nswe] CVseen[key] = True return output
def merge(CVlist1, CVlist2, ep, eh, epChild1, ehChild1, epChild2, \ ehChild2, eventType): ''' Given two lists of CostVectors, returns a new list of CostVectors, each of which is the sum of a pair of vectors from the two given lists.''' global CVevents global CVallEvents global CandidateCVlist intersection = CONFIG.intersection if intersection: global CVseen global CVcommonEvents output = [] for v in CVlist1: for w in CVlist2: if eventType == "cospeciation": newCV = CostVector(1, 0, 0, 0, 1) + v + w elif eventType == "duplication": newCV = CostVector(0, 1, 0, 0, 1) + v + w else: # eventType == "switch": newCV = CostVector(0, 0, 1, 0, 1) + v + w keepnewCV = True for cv in CandidateCVlist: if cv < newCV: keepnewCV = False break if keepnewCV: output.append(newCV) vsoln = (epChild1, ehChild1) + v.toTupleCDSL() wsoln = (epChild2, ehChild2) + w.toTupleCDSL() if eventType == "switch": eventType = "switch to "+str(ehChild2) nswe = (ep, eh, eventType) + newCV.toTupleCDSL() ns = (ep, eh) + newCV.toTupleCDSL() CVevents[nswe].add(nswe) CVevents[nswe] = CVevents[nswe].\ union(CVallEvents[vsoln]).\ union(CVallEvents[wsoln]) CVallEvents[ns] = CVallEvents[ns].union(CVevents[nswe]) if intersection: key = newCV.toTupleCDSL() if CVseen[key]: CVcommonEvents[key] = CVcommonEvents[key].\ intersection(CVevents[nswe]) else: CVcommonEvents[key] = CVevents[nswe] CVseen[key] = True return output
def tupleToCV(entry): return CostVector(entry[0], entry[1], entry[2], entry[3], entry[4])