Skip to content

Commit 4d95f40

Browse files
committed
Add sponsor badge
1 parent f484bd9 commit 4d95f40

1 file changed

Lines changed: 261 additions & 0 deletions

File tree

README.md

Lines changed: 261 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,261 @@
1+
[![Sponsor](https://img.shields.io/badge/Sponsor-%E2%9D%A4-pink?logo=github)](https://github.com/sponsors/hyperpolymath)
2+
3+
// SPDX-License-Identifier: MPL-2.0
4+
// SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
5+
6+
= Cladistics.jl
7+
:toc: preamble
8+
:icons: font
9+
10+
image:https://img.shields.io/badge/OpenSSF-Best_Practices-green?logo=opensourcesecurity[OpenSSF Best Practices,link="https://www.bestpractices.dev/en/projects/new?repo_url=https://github.com/hyperpolymath/Cladistics.jl"]
11+
image:https://img.shields.io/badge/License-PMPL--1.0-blue.svg[License: PMPL-1.0,link="https://github.com/hyperpolymath/palimpsest-license"]
12+
image:https://api.thegreenwebfoundation.org/greencheckimage/github.com[Green Web,link="https://www.thegreenwebfoundation.org/green-web-check/?url=github.com"]
13+
image:https://img.shields.io/badge/Project-Topology-9558B2[Project Topology,link="TOPOLOGY.md"]
14+
image:https://img.shields.io/badge/Completion-75%25-yellow[Completion Status,link="TOPOLOGY.md"]
15+
image:https://img.shields.io/badge/license-PMPL--1.0--or--later-blue.svg[License,link="LICENSE"]
16+
image:https://img.shields.io/badge/julia-1.6+-purple.svg[Julia,link="https://julialang.org"]
17+
18+
A Julia package for phylogenetic analysis and cladistics — the study of
19+
evolutionary relationships among organisms.
20+
21+
== Overview
22+
23+
Cladistics is a method of biological classification that groups organisms based
24+
on their evolutionary ancestry and shared derived characteristics (synapomorphies).
25+
This package provides computational tools for reconstructing and analyzing
26+
phylogenetic trees from molecular sequence data and morphological characters.
27+
28+
=== What is Cladistics?
29+
30+
* *Clade*: A monophyletic group consisting of an ancestor and all its descendants
31+
* *Synapomorphy*: A shared derived characteristic that defines a clade
32+
* *Phylogenetic Tree*: A branching diagram showing evolutionary relationships
33+
* *Parsimony*: The principle that the simplest evolutionary explanation (fewest changes) is preferred
34+
* *Bootstrap Analysis*: Statistical method to assess confidence in tree topology
35+
36+
== Features
37+
38+
=== Distance-Based Methods
39+
40+
* *Multiple Distance Metrics*: Hamming, p-distance, Jukes-Cantor 1969, Kimura 2-parameter
41+
* *UPGMA*: Unweighted Pair Group Method with Arithmetic Mean (assumes molecular clock)
42+
* *Neighbor-Joining*: Does not assume molecular clock, handles rate variation
43+
44+
=== Character-Based Methods
45+
46+
* *Maximum Parsimony*: Find trees requiring fewest evolutionary changes
47+
* *Fitch Algorithm*: Efficient parsimony score calculation
48+
* *Parsimony-Informative Sites*: Identify characters useful for phylogenetic inference
49+
50+
=== Tree Analysis
51+
52+
* *Bootstrap Support*: Assess confidence in tree topology (1000+ replicates)
53+
* *Clade Identification*: Extract well-supported monophyletic groups
54+
* *Robinson-Foulds Distance*: Compare tree topologies quantitatively
55+
* *Tree Rooting*: Root unrooted trees using outgroup taxa
56+
* *Newick Format*: Export trees in standard phylogenetic format
57+
58+
== Installation
59+
60+
[source,julia]
61+
----
62+
using Pkg
63+
Pkg.add("Cladistics")
64+
----
65+
66+
== Quick Start
67+
68+
[source,julia]
69+
----
70+
using Cladistics
71+
using Plots
72+
73+
# 1. DNA sequence data (aligned)
74+
sequences = [
75+
"ATCGATCGATCG", # Species A
76+
"ATCGATCGATCG", # Species B (same as A)
77+
"ATCGTTCGATCG", # Species C
78+
"TTCGATCGATCG", # Species D
79+
"TTCGTTCGATCC" # Species E (outgroup)
80+
]
81+
taxa_names = ["Species_A", "Species_B", "Species_C", "Species_D", "Species_E"]
82+
83+
# 2. Calculate evolutionary distances
84+
dmat = distance_matrix(sequences, method=:jc69)
85+
86+
# 3. Build phylogenetic tree using UPGMA
87+
upgma_tree = upgma(dmat, taxa_names=taxa_names)
88+
newick = tree_to_newick(upgma_tree)
89+
90+
# 4. Build tree using Neighbor-Joining
91+
nj_tree = neighbor_joining(dmat, taxa_names=taxa_names)
92+
93+
# 5. Compare tree topologies
94+
rf_distance = tree_distance(upgma_tree, nj_tree)
95+
96+
# 6. Bootstrap analysis for confidence
97+
support = bootstrap_support(sequences, replicates=1000, method=:nj)
98+
99+
# 7. Identify well-supported clades
100+
clades = identify_clades(upgma_tree, 0.95)
101+
----
102+
103+
== Distance Methods Comparison
104+
105+
[source,julia]
106+
----
107+
using Cladistics
108+
sequences = ["ATCG", "ATCG", "TTCG", "TTCC"]
109+
110+
hamming = distance_matrix(sequences, method=:hamming) # Simple counting
111+
p_dist = distance_matrix(sequences, method=:p_distance) # Proportion of differences
112+
jc69 = distance_matrix(sequences, method=:jc69) # Jukes-Cantor
113+
k2p = distance_matrix(sequences, method=:k2p) # Kimura 2-parameter
114+
----
115+
116+
== Tree Construction Methods
117+
118+
=== UPGMA: Simple but assumes molecular clock
119+
120+
[source,julia]
121+
----
122+
dmat = [0.0 0.2 0.4; 0.2 0.0 0.3; 0.4 0.3 0.0]
123+
tree = upgma(dmat, taxa_names=["Human", "Chimp", "Gorilla"])
124+
# Good for: recent divergences, molecular clock valid
125+
# Not good for: ancient divergences, variable rates
126+
----
127+
128+
=== Neighbor-Joining: No molecular clock assumption
129+
130+
[source,julia]
131+
----
132+
dmat = [0.0 0.5 0.8 1.0; 0.5 0.0 0.6 0.9; 0.8 0.6 0.0 0.4; 1.0 0.9 0.4 0.0]
133+
tree = neighbor_joining(dmat, taxa_names=["A", "B", "C", "D"])
134+
# Good for: variable evolutionary rates, large datasets
135+
----
136+
137+
== Bootstrap Analysis
138+
139+
[source,julia]
140+
----
141+
using Cladistics, Random
142+
Random.seed!(42)
143+
sequences = [
144+
"ATCGATCGATCGATCG",
145+
"ATCGATCGATCGATCG",
146+
"ATCGTTCGATCGATCG",
147+
"TTCGATCGATCGATCG",
148+
"TTCGTTCGATCGTTCC"
149+
]
150+
# 1000 bootstrap replicates — resamples alignment columns with replacement
151+
support = bootstrap_support(sequences, replicates=1000, method=:nj)
152+
# Interpret: >95% Strong, 70-95% Moderate, <70% Weak
153+
----
154+
155+
== Maximum Parsimony
156+
157+
[source,julia]
158+
----
159+
using Cladistics
160+
alignment = ["ATCG", "ATCG", "TTCG", "TTCC"]
161+
char_matrix = character_state_matrix(alignment)
162+
informative_sites = parsimony_informative_sites(char_matrix)
163+
dmat = distance_matrix(alignment, method=:hamming)
164+
tree = upgma(dmat, taxa_names=["Tax1", "Tax2", "Tax3", "Tax4"])
165+
score = calculate_parsimony_score(tree, char_matrix)
166+
# Lower score = more parsimonious (preferred)
167+
----
168+
169+
== Real-World Example: Primate Phylogeny
170+
171+
[source,julia]
172+
----
173+
using Cladistics
174+
primate_sequences = [
175+
"ATCGATCGATCGATCGATCG", # Human
176+
"ATCGATCGATCGATCGATCG", # Chimp
177+
"ATCGATCGTTCGATCGATCG", # Gorilla
178+
"ATCGTTCGTTCGATCGTTCG", # Orangutan
179+
"TTCGTTCGTTCGTTCGTTCG" # Lemur (outgroup)
180+
]
181+
taxa = ["Human", "Chimp", "Gorilla", "Orangutan", "Lemur"]
182+
dmat = distance_matrix(primate_sequences, method=:k2p)
183+
tree = neighbor_joining(dmat, taxa_names=taxa)
184+
rooted_tree = root_tree(tree, "Lemur")
185+
support = bootstrap_support(primate_sequences, replicates=100, method=:nj)
186+
newick = tree_to_newick(rooted_tree)
187+
----
188+
189+
== Key Concepts
190+
191+
=== Molecular Clock
192+
193+
* Assumption: constant evolutionary rate across lineages
194+
* When valid: recent species, similar generation times
195+
* Methods: UPGMA assumes molecular clock
196+
* When violated: use Neighbor-Joining
197+
198+
=== Bootstrap Support Interpretation
199+
200+
* `>95%`: Publish with confidence
201+
* `70–95%`: Mention uncertainty
202+
* `<70%`: Weak support, collect more data
203+
204+
=== Parsimony vs Distance
205+
206+
* *Parsimony*: Find tree requiring fewest character changes; NP-hard but theoretically clear
207+
* *Distance*: Fast, scales to large datasets; loses some information from pairwise comparisons
208+
209+
== References
210+
211+
=== Classic Papers
212+
213+
* Felsenstein, J. (1985). "Confidence limits on phylogenies: An approach using the bootstrap." _Evolution_, 39(4), 783–791.
214+
* Saitou, N., & Nei, M. (1987). "The neighbor-joining method." _Molecular Biology and Evolution_, 4(4), 406–425.
215+
* Fitch, W. M. (1971). "Toward defining the course of evolution." _Systematic Zoology_, 20(4), 406–416.
216+
217+
=== Textbooks
218+
219+
* Felsenstein, J. (2004). _Inferring Phylogenies_. Sinauer Associates.
220+
* Lemey, P. et al. (2009). _The Phylogenetic Handbook_. Cambridge University Press.
221+
* Hall, B. G. (2011). _Phylogenetic Trees Made Easy_. Sinauer Associates.
222+
223+
=== Evolutionary Models
224+
225+
* Jukes, T. H., & Cantor, C. R. (1969). "Evolution of protein molecules." _Mammalian Protein Metabolism_, pp. 21–132.
226+
* Kimura, M. (1980). "A simple method for estimating evolutionary rates." _Journal of Molecular Evolution_, 16(2), 111–120.
227+
228+
== Citation
229+
230+
[source,bibtex]
231+
----
232+
@software{cladistics_jl,
233+
author = {Jewell, Jonathan D.A.},
234+
title = {Cladistics.jl: Phylogenetic Analysis in Julia},
235+
year = {2026},
236+
url = {https://github.com/hyperpolymath/Cladistics.jl}
237+
}
238+
----
239+
240+
== Related Projects
241+
242+
* https://github.com/BioJulia[BioJulia] — Broader bioinformatics ecosystem
243+
* https://github.com/crsl4/PhyloNetworks.jl[PhyloNetworks.jl] — Phylogenetic networks
244+
* https://github.com/richardreeve/Phylo.jl[Phylo.jl] — Alternative phylogenetics package
245+
246+
== External Visualization Tools
247+
248+
* http://tree.bio.ed.ac.uk/software/figtree/[FigTree]
249+
* https://itol.embl.de/[iTOL]
250+
* http://etetoolkit.org/[ETE Toolkit]
251+
252+
== Contributing
253+
254+
See link:CONTRIBUTING.md[CONTRIBUTING.md] for guidelines.
255+
256+
Wondering how this works? See link:EXPLAINME.adoc[].
257+
258+
== License
259+
260+
SPDX-License-Identifier: MPL-2.0 +
261+
See link:LICENSE[LICENSE].

0 commit comments

Comments
 (0)