Skip to content

Commit 1eec981

Browse files
committed
Add custom branch sorting and padding, update publications.
1 parent 2dc9542 commit 1eec981

File tree

3 files changed

+63
-44
lines changed

3 files changed

+63
-44
lines changed

baltic/baltic.py

Lines changed: 47 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -344,25 +344,17 @@ def renameTips(self,d=None):
344344
# k.name=d[k.numName] ## change its name
345345
k.name=d[k.name] ## change its name
346346

347-
def sortBranches(self,descending=True):
347+
def sortBranches(self,descending=True,sort_function=None):
348348
""" Sort descendants of each node. """
349-
if descending==True:
350-
modifier=-1 ## define the modifier for sorting function later
351-
elif descending==False:
352-
modifier=1
349+
mod=-1 if descending else 0
350+
if sort_function==None: sort_function=lambda k: (k.is_node(),-len(k.leaves)*mod,k.length*mod) if k.is_node() else (k.is_node(),k.length*mod)
353351

354352
for k in self.getInternal(): ## iterate over nodes
355-
## split node's offspring into nodes and leaves, sort each list individually
356-
nodes=sorted([x for x in k.children if x.branchType=='node'],key=lambda q:(-len(q.leaves)*modifier,q.length*modifier))
357-
leaves=sorted([x for x in k.children if x.branchType=='leaf'],key=lambda q:q.length*modifier)
358-
359-
if modifier==1: ## if sorting one way - nodes come first, leaves later
360-
k.children=nodes+leaves
361-
elif modifier==-1: ## otherwise sort the other way
362-
k.children=leaves+nodes
353+
k.children=sorted(k.children,key=sort_function)
354+
363355
self.drawTree() ## update x and y positions of each branch, since y positions will have changed because of sorting
364356

365-
def drawTree(self,order=None,width_function=None,verbose=False):
357+
def drawTree(self,order=None,width_function=None,pad_nodes=None,verbose=False):
366358
""" Find x and y coordinates of each branch. """
367359
if order==None:
368360
order=self.traverse_tree() ## order is a list of tips recovered from a tree traversal to make sure they're plotted in the correct order along the vertical tree dimension
@@ -383,42 +375,57 @@ def drawTree(self,order=None,width_function=None,verbose=False):
383375
k.x=None
384376
k.y=None
385377

378+
drawn={} ## drawn keeps track of what's been drawn
379+
for k in order: ## iterate over tips
380+
x=k.height ## x position is height
381+
y_idx=name_order[k.name] ## assign y index
382+
y=sum(skips[y_idx:])-skips[y_idx]/2.0 ## sum across skips to find y position
383+
384+
k.x=x ## set x and y coordinates
385+
k.y=y
386+
drawn[k.index]=None ## remember that this objects has been drawn
387+
388+
if pad_nodes!=None: ## will be padding nodes
389+
for n in pad_nodes: ## iterate over nodes whose descendants will be padded
390+
idx=sorted([name_order[lf] for lf in n.leaves]) if n.is_node() else [order.index(n)] ## indices of all tips to be padded
391+
for i,k in enumerate(order): ## iterate over all tips
392+
393+
if i<idx[0]: ## tip below clade
394+
k.y+=pad_nodes[n] ## pad
395+
396+
if (i-1)<idx[-1]: ## tip above clade
397+
k.y+=pad_nodes[n] ## pad again
398+
399+
all_ys=filter(None,self.getParameter('y')) ## get all y positions in tree that aren't None
400+
minY=min(all_ys) ## get min
401+
for k in self.getExternal(): ## reset y positions so tree starts at y=0.5
402+
k.y-=minY-0.5
403+
386404
assert len(self.getExternal())==len(order),'Number of tips in tree does not match number of unique tips, check if two or more collapsed clades were assigned the same name.'
387405
storePlotted=0
388-
drawn={} ## drawn keeps track of what's been drawn
406+
389407
while len(drawn)!=len(self.Objects): # keep drawing the tree until everything is drawn
390408
if verbose==True: print('Drawing iteration %d'%(len(drawn)))
391-
for k in filter(lambda w:w.index not in drawn,self.getExternal()+self.getInternal()): ## iterate through objects that have not been drawn
392-
if k.branchType=='leaf': ## if leaf - get position of leaf, draw branch connecting tip to parent node
393-
if verbose==True: print('Setting leaf %s y coordinate to'%(k.index)),
409+
for k in filter(lambda w:w.index not in drawn,self.getInternal()): ## iterate through internal nodes that have not been drawn
410+
if len([q.y for q in k.children if q.y!=None])==len(k.children): ## all y coordinates of children known
411+
if verbose==True: print('Setting node %s coordinates to'%(k.index)),
394412
x=k.height ## x position is height
395-
y_idx=name_order[k.name]
396-
y=sum(skips[y_idx:])-skips[y_idx]/2.0 ## sum across skips to find y position
397-
k.x=x ## set x and y coordinates
413+
children_y_coords=[q.y for q in k.children if q.y!=None] ## get all existing y coordinates of the node
414+
y=sum(children_y_coords)/float(len(children_y_coords)) ## internal branch is in the middle of the vertical bar
415+
k.x=x
398416
k.y=y
399417
drawn[k.index]=None ## remember that this objects has been drawn
400418
if verbose==True: print('%s (%s branches drawn)'%(k.y,len(drawn)))
401-
if k.parent and hasattr(k.parent,'yRange')==False: ## if parent doesn't have a maximum extent of its children's y coordinates
402-
setattr(k.parent,'yRange',[k.y,k.y]) ## assign it
403-
404-
if k.branchType=='node': ## if parent is non-root node and y positions of all its children are known
405-
if len([q.y for q in k.children if q.y!=None])==len(k.children):
406-
if verbose==True: print('Setting node %s coordinates to'%(k.index)),
407-
x=k.height ## x position is height
408-
children_y_coords=[q.y for q in k.children if q.y!=None] ## get all existing y coordinates of the node
409-
y=sum(children_y_coords)/float(len(children_y_coords)) ## internal branch is in the middle of the vertical bar
410-
k.x=x
411-
k.y=y
412-
drawn[k.index]=None ## remember that this objects has been drawn
413-
if verbose==True: print('%s (%s branches drawn)'%(k.y,len(drawn)))
414-
minYrange=min([min(child.yRange) if child.branchType=='node' else child.y for child in k.children]) ## get lowest y coordinate across children
415-
maxYrange=max([max(child.yRange) if child.branchType=='node' else child.y for child in k.children]) ## get highest y coordinate across children
416-
setattr(k,'yRange',[minYrange,maxYrange]) ## assign the maximum extent of children's y coordinates
419+
minYrange=min([min(child.yRange) if child.branchType=='node' else child.y for child in k.children]) ## get lowest y coordinate across children
420+
maxYrange=max([max(child.yRange) if child.branchType=='node' else child.y for child in k.children]) ## get highest y coordinate across children
421+
setattr(k,'yRange',[minYrange,maxYrange]) ## assign the maximum extent of children's y coordinates
417422

418423
if len(self.Objects)>len(drawn):
419-
assert len(drawn)>storePlotted,'Got stuck trying to find y positions of objects (%d branches drawn this iteration, %d branches during previous iteration out of %d total)'%(len(drawn),storePlotted,len(self.Objects))
420-
storePlotted=len(drawn)
421-
self.ySpan=sum(skips)
424+
assert len(drawn)>storePlotted,'Got stuck trying to find y positions of objects (%d branches drawn this iteration, %d branches during previous iteration out of %d total)'%(len(drawn),storePlotted,len(tree.Objects))
425+
storePlotted=len(drawn) ## remember how many branches were drawn this iteration
426+
427+
yvalues=[k.y for k in self.Objects] ## all y values
428+
self.ySpan=max(yvalues)-min(yvalues)+min(yvalues)*2 ## determine appropriate y axis span of tree
422429

423430
if self.root.branchType=='node':
424431
self.root.x=min([q.x-q.length for q in self.root.children if q.x!=None]) ## set root x and y coordinates

docs/publications.rst

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,30 @@ Publications using baltic
88

99
baltic was used in the following publications:
1010

11-
- Miller D, Martin MA, Harel N, Kustin T, Tirosh O, Meir M, Sorek N, ..., Kopelman N, Huppert A, Koelle K, Stern A, 2020. _Full genome viral sequences inform patterns of SARS-CoV-2 spread into and within Israel, `medRxiv`: 2020.05.21.20104521; `doi <https://doi.org/10.1101/2020.05.21.20104521>`__.
11+
- Muller N, Kunze M, ..., Zeitlmann N, and Corman VM, 2021. _Severe Acute Respiratory Syndrome Coronavirus 2 Outbreak Related to a Nightclub, Germany, 2020_, `Emerging Infectious Diseases` 27(2): 645-648; `doi <https://doi.org/10.3201/eid2702.204443>`__.
12+
- Washington NL, Gangavarapu K, Zeller M, Bolze A, ..., Chiu C, Suchard MA, Lu JT, Lee W, Andersen KG, 2021. _Genomic epidemiology identifies emergence and rapid transmission of SARS-CoV-2 B.1.1.7 in the United States_, `medRxiv` 2021.02.06.21251159; `doi <https://doi.org/10.1101/2021.02.06.21251159>`__.
13+
- Alpert T, Lasek-Nesselquist E, Brito AF, ..., Lauring AS, St. George K, MacCannell DR, Grubaugh ND, 2021. _Early introductions and community transmission of SARS-CoV-2 variant B.1.1.7 in the United States_, `medRxiv` 2021.02.10.21251540; `doi <https://doi.org/10.1101/2021.02.10.21251540>`__.
14+
- Zeller M, Gangavarapu K, Anderson C, Smither AR, ..., Kamil JP, Garry RF, Suchard MA, Andersen KG, 2021. _Emergence of an early SARS-CoV-2 epidemic in the United States_, `medRxiv` 2021.02.05.21251235; `doi <https://doi.org/10.1101/2021.02.05.21251235>`__.
15+
- Thomson EC, Rosen LE, Shepherd JG, ..., Corti D, Robertson DL, Snell G, 2021. _Circulating SARS-CoV-2 spike N439K variants maintain fitness while evading antibody-mediated immunity_, `Cell` 184: 1-17; `doi <https://doi.org/10.1016/j.cell.2021.01.037>`__.
16+
- Hodcroft EB, Domman DB, Oguntuyo K, ..., Cooper VS, Kamil JP, 2021. _Emergence in late 2020 of multiple lineages of SARS-CoV-2 Spike protein variants affecting amino acid position 677_, `medRxiv` 2021.02.12.21251658; `doi <https://doi.org/10.1101/2021.02.12.21251658>`__.
17+
- Moreno GK, Braun KM, Riemersma KK, ..., Kawaoka Y, Koelle K, O’Connor DH, Friedrich TC, 2020. _Revealing fine-scale spatiotemporal differences in SARS-CoV-2 introduction and spread_, `Nature Communications` 11, 5558; `doi <https://doi.org/10.1038/s41467-020-19346-z>`__.
18+
- Miller D, Martin MA, Harel N, Kustin T, Tirosh O, Meir M, Sorek N, ..., Kopelman N, Huppert A, Koelle K, Stern A, 2020. _Full genome viral sequences inform patterns of SARS-CoV-2 spread into and within Israel_, `Nature Communications` 11, 5518; `doi <https://doi.org/10.1038/s41467-020-19248-0>`__.
19+
- Moncla LH, Black A, DeBolt C, Lang M, Graff NR, Perez-Osorio AC, Mueller NF, Haselow D, Lindquist S, Bedford T, 2020. _Repeated introductions and intensive community transmission fueled a mumps virus outbreak in Washington State_, `medRxiv`: 2020.10.19.20215442; `doi <https://doi.org/10.1101/2020.10.19.20215442>`__.
20+
- Ladner JT, Larsen BB, Bowers JR, Hepp CM, ..., Worobey M, Keim P, 2020. _An Early Pandemic Analysis of SARS-CoV-2 Population Structure and Dynamics in Arizona_, `mBio` 11 (5): e02107-20; `doi <https://doi.org/10.1128/mBio.02107-20>`__.
21+
- Brito AF, Lais Machado C, ..., da Fonseca BAL, Wallau GL, Grubaugh ND, 2020. _Lying in wait: the resurgence of dengue virus after the Zika epidemic in Brazil_, `medRxiv` 2020.08.10.20172247; `doi <https://doi.org/10.1101/2020.08.10.20172247>`__.
22+
- Alm E, Broberg EK, Connor T, Hodcroft EB, Komissarov AB, Maurer-Stroh S, Melidou A, Neher RA, O’Toole Á,
23+
- Pereyaslov D, 2020. _Geographical and temporal distribution of SARS-CoV-2 clades in the WHO European Region, January to June 2020_, `Euro Surveillance` 25(32):pii=2001410; `doi <https://doi.org/10.2807/1560-7917.ES.2020.25.32.2001410>`__.
1224
- Pawestri HA, Nugraha AA, Han AX, Pratiwi E, Parker E, Richard M, van der Vliet S, Fouchier RAM, Muljono DH, de Jong MD, Setiawaty V, Eggink D, 2020. _Genetic and antigenic characterization of influenza A/H5N1 viruses isolated from patients in Indonesia, 2008–2015. `Virus Genes` 56(4): 417-429. `doi <https://doi.org/10.1007/s11262-020-01765-1>`__.
13-
- Ladner JT, Larsen BB, Bowers JR, Hepp CM, ..., Worobey M, Keim P, 2020. _Defining the Pandemic at the State Level: Sequence-Based Epidemiology of the SARS-CoV-2 virus by the Arizona COVID-19 Genomics Union (ACGU), __medRxiv__: 2020.05.08.20095935; `doi <https://doi.org/10.1101/2020.05.08.20095935>`__.
1425
- Sikkema RS, Pas S, Nieuwenhuijse DF, O'Toole A, ..., Munnink BBO, Kluytmans M, Koopmans MPG, 2020. _COVID-19 in health-care workers in three hospitals in the south of the Netherlands: a cross-sectional study, `Lancet Infect Dis`; `doi <https://doi.org/10.1016/S1473-3099(20)30527-2>`__.
1526
- Munnink BBO, Nieuwenhuijse DF, Stein M, O'Toole A, Haverkarte M, ..., Meijer A, Rambaut A, van Dissel J, Sikkema R, Timen A, Koopmans M, 2020. _Rapid SARS-CoV-2 whole genome sequencing for informed public health decision making in the Netherlands, `Nature Medicine`; `doi <https://doi.org/10.1038/s41591-020-0997-y>`__.
1627
- Müller NF, Stolz U, Dudas G, Stadler T, Vaughan TG, 2020. _Bayesian inference of reassortment networks reveals fitness benefits of reassortment in human influenza viruses, `PNAS`: 117 (29) 17104-17111; `doi <https://doi.org/10.1073/pnas.1918304117>`__.
1728
- Venkatesh D, Brouwer A, Ellis R, Goujgoulova G, Seekings J, Brown IH, Lewis NS, 2020. _Regional transmission and reassortment of 2.3.4.4b highly pathogenic avian influenza (HPAI) viruses in Bulgarian poultry 2017/18, `Viruses` 12(6): 605; `doi <https://dx.doi.org/10.3390/v12060605>`__.
1829
- Suárez-Esquivel M, Hernández-Mora G, Ruiz-Villalobos N, ..., Thomson NR, Moreno E, Guzmán-Verri C, 2020. _Persistence of Brucella abortus lineages revealed by genomic characterization and phylodynamic analysis, `PLOS Neglected Tropical Diseases` 14(4): e0008235; `doi <https://doi.org/10.1371/journal.pntd.0008235>`__.
1930
- Moncla LH, Bedford T, Dussart P, ..., Guan Y, Friedrich TC, Horwood PF, 2020. _Quantifying within-host evolution of H5N1 influenza in humans and poultry in Cambodia, `PLOS Pathogens` 16(1): e1008191; `doi <https://doi.org/10.1371/journal.ppat.1008191>`__.
2031
- Dudas G, Bedford T, 2020. The ability of single genes vs full genomes to resolve time and space in outbreak analysis. `BMC Evolutionary Biology` 19, 232; `doi <https://doi.org/10.1186/s12862-019-1567-0>`__.
21-
- Wiley R, Fakoli L, Letizia AG, Welch SR, Ladner JT, Albariño CG, Fallah M, Palacios G, 2019. _Lassa virus circulating in Liberia: a retrospective genomic characterisation, `Lancet Infect Dis`
32+
- Wiley R, Fakoli L, Letizia AG, Welch SR, Ladner JT, Albariño CG, Fallah M, Palacios G, 2019. _Lassa virus circulating in Liberia: a retrospective genomic characterisation, `Lancet Infect Dis` 19(12): 1371-1378; `doi <https://doi.org/10.1016/S1473-3099(19)30486-4>`__.
2233
- Theys K, Lemey P, Vandamme AM, Baele G, 2019. _Advances in Visualization Tools for Phylogenomic and Phylodynamic Studies of Viral Diseases, `Front. Public Health`, 7: 208; `doi <https://doi.org/10.3389/fpubh.2019.00208>`__.
34+
- Grubaugh ND, Saraf S, Gangavarapu K, Watts A, ..., Isern S, Michael SF, Andersen KG, 2019. _Travel Surveillance and Genomics Uncover a Hidden Zika Outbreak during the Waning Epidemic_. `Cell` 178(5): 1057-1071; `doi <https://doi.org/10.1016/j.cell.2019.07.018>`__.
2335
- Müller NF, Dudas G, Stadler T, 2019. _Inferring time-dependent migration and coalescence patterns from genetic sequence and predictor data in structured populations, `Virus Evolution`, 5(2): vez030; `doi <https://doi.org/10.1093/ve/vez030>`__.
2436
- Mbala-Kingebeni P, Aziza A, Di Paola N, Wiley MR, ..., Peeters M, Palacios G, Ahuka-Mundeke S, 2019. _Medical countermeasures during the 2018 Ebola virus disease outbreak in the North Kivu and Ituri Provinces of the Democratic Republic of the Congo: a rapid genomic assessment, `Lancet Infect Dis` 19(6): 648-657; `doi <https://doi.org/10.1016/S1473-3099(19)30118-5>`__.
2537
- Work TM, Dagenais J, Stacy BA, Ladner JT, ..., Rameyer RA, Taylor DR, Waltzek TB, 2019. _A novel host-adapted strain of Salmonella Typhimurium causes renal disease in olive ridley turtles (Lepidochelys olivacea) in the Pacific, `Scientific Reports` 9: 9313; `doi <https://doi.org/10.1038/s41598-019-45752-5>`__.

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
setup(
1010
name="baltic",
11-
version="0.1.5",
11+
version="0.1.6",
1212
packages=find_packages(),
1313
url="https://github.com/evogytis/baltic",
1414
download_url="https://github.com/evogytis/baltic/archive/v0.1.5.tar.gz",

0 commit comments

Comments
 (0)