Python API and extension guide
CodonAnalyzer is the primary analysis interface. Individual calculators in codonadaptpy.metrics can also be used independently. Inputs and outputs are standard-library dataclasses that can be serialized without a framework-specific schema library and remain available regardless of which optional dependencies are installed.
CDSAggregator uses a configured CodonAnalyzer to generate per-gene results, boundary-aware genome-wide results for each isolate, and results for any requested focus genes. Records identify their isolate and gene through metadata; no gene name is hard-coded.
Add a metric by implementing a focused calculation class and invoking it from CodonAnalyzer.analyze. Add a new input format in SequenceParser.parse. Add reference sources by constructing ReferenceProfile objects and registering them with ReferenceManager. Biological tables should always include database/release provenance, selection criteria, taxonomy, and checksums when available.
ComparativeAnalyzer.automatic_test(left, right, paired=False, alpha=0.05) records its normality diagnostic and selects Welch’s t test or Mann–Whitney U for independent samples, and a paired t test or Wilcoxon signed-rank test for paired samples. Normality is assessed on within-pair differences for paired designs. The returned dictionary includes the selected test, sample sizes, statistic, p value, effect-size name and value, and the documented selection policy.
ComparativeAnalyzer accepts mappings containing numeric metrics and grouping metadata. SciPy is used for inferential tests and clustering, while NumPy and scikit-learn support multivariate analyses. It exposes Welch and Mann-Whitney tests, Hedges’ g, FDR correction, PCA, correspondence analysis, stratified LDA with a reproducible train/test split, hierarchical clustering, correlations, and distances.
PlotManager provides optional self-contained interactive HTML for hover and zoom workflows. It uses Plotly only when requested and does not use Kaleido or browser automation. PublicationPlotManager returns browser-independent static Matplotlib figures with the Okabe-Ito palette, redundant markers, sample sizes, standard errors, outward-offset axes, and vector-compatible output. Its methods cover grouped PCA and LDA, an automatic RSCU PCA biplot, held-out confusion matrices, exact 59-codon RSCU profiles and group-similarity heatmaps, UpSet-style exact preferred-codon intersections, composition summaries, metric correlations, ENC-GC3s/neutrality/PR2 diagnostics, all 16 dinucleotide O/E profiles and heatmaps, scalar metric panels, sliding-window CAI, and multi-host CAI/RCDI/SiD landscapes. save exports PNG, TIFF, PDF, or SVG.
Phylogenetic and temporal API
PhylogeneticAnalyzer writes FASTA, aligns with MAFFT, trims with trimAL, and
infers an ML tree using IQ-TREE/ModelFinder with ultrafast bootstrap or
FastTree. External command arguments and result paths are returned in a
serializable PhylogenyResult. Setting trim_required=True is recommended for
publication workflows because it prevents silent use of an untrimmed alignment.
TemporalAnalyzer.temporal_signal performs a root-to-tip regression and can
search candidate roots in the style of a rapid TempEst diagnostic. The result
contains rate, fitted root date, R², p value, residuals, and the selected
outgroup. date_tree applies that deterministic strict-clock mapping while
anchoring observed tips to their collection dates. lineage_through_time
counts dated branches across a calendar grid. These methods do not implement a
relaxed clock, Bayesian posterior sampling, effective population size, or HPD
intervals and therefore must not be labeled as Bayesian skyline results.
PhylogeneticComparator.robinson_foulds prunes two trees to shared accessions
and reports raw and normalized unrooted Robinson-Foulds distance. This is useful
for quantifying whole-genome versus focus-gene topology discordance.
ETE3TreePlotter uses ETE3 for topology parsing, rooting, traversal, pruning,
and node metadata, then renders headlessly with Matplotlib. It provides ML tree,
time-tree, temporal-signal, and deterministic LTT figures as 600 dpi raster or
vector output without ETE3’s optional Qt interface.
High-level analysis API
- class codonadaptpy.analyzer.AnalysisConfig(validation=<factory>, sliding_window=30, sliding_step=1, simulate_cai=0, random_seed=1, strict=True)[source]
Configure validation, windows, simulation, and reproducibility settings.
- class codonadaptpy.analyzer.CodonAnalyzer(config=None, *, reference=None, hosts=None)[source]
Coordinate codon-usage and adaptation analyses through one interface.
Initialize an analyzer with optional target and host references.
- Parameters:
config (AnalysisConfig | None)
reference (ReferenceProfile | None)
hosts (dict[str, ReferenceProfile] | None)
- analyze(record)[source]
Analyze one sequence and return a structured result.
- Parameters:
record (SequenceRecord)
- Return type:
AnalysisResult
- analyze_many(records)[source]
Analyze records in deterministic input order.
- Parameters:
records (list[SequenceRecord])
- Return type:
list[AnalysisResult]
- analyze_cds_collection(identifier, records, *, metadata=None)[source]
Analyze pooled coding regions while preserving every CDS boundary.
Each member is validated and framed independently. Terminal stops are excluded from pooled codon and composition metrics, and sequence-word plus codon-pair calculations never span adjacent CDSs.
Sequence models and validation
- class codonadaptpy.models.SequenceRecord(identifier, sequence, description='', metadata=<factory>)[source]
Store a named nucleotide sequence and arbitrary sample metadata.
- class codonadaptpy.models.ValidationConfig(reading_frame=0, genetic_code=1, require_start=True, require_stop=True, ambiguous_policy='reject', allow_partial=False, convert_rna=True)[source]
Control normalization and coding-sequence quality checks.
Reading frames use zero-based offsets
0,1, or2. Ambiguous codons may be rejected, skipped by downstream analyses, or retained with warnings. Partial sequences relax start, stop, and divisible-by-three requirements while preserving all other diagnostics.
- class codonadaptpy.models.ValidationReport(identifier, normalized_sequence, issues=<factory>, genetic_code=1, reading_frame=0)[source]
Collect normalized sequence data and structured validation findings.
- Parameters:
- class codonadaptpy.validation.SequenceValidator(config=None)[source]
Validate and normalize coding sequences under a fixed policy.
Initialize the validator and resolve its selected genetic code.
- Parameters:
config (ValidationConfig | None)
- validate(record, *, raise_on_error=False)[source]
Validate one sequence record and return every detected issue.
- Parameters:
record (SequenceRecord) – Input record containing an identifier and nucleotide sequence.
raise_on_error (bool) – Raise
SequenceValidationErrorafter collecting errors. The default returns an invalid report for batch-friendly behavior.
- Return type:
- class codonadaptpy.parsers.SequenceParser[source]
Read supported sequence inputs into consistent sequence records.
- parse(source, *, fmt=None)[source]
Parse a path, text stream, or direct nucleotide sequence.
Format is inferred from file extensions when omitted. Plain strings that do not identify existing paths are treated as pasted sequences unless they begin with
>and therefore represent FASTA text.
- parse_fasta(handle)[source]
Yield records from FASTA-formatted text with duplicate checks.
- Parameters:
- Return type:
- parse_table(path)[source]
Yield records from CSV/TSV containing identifier and sequence columns.
- Parameters:
- Return type:
- parse_genbank(path)[source]
Yield CDS features, or whole records without CDS, from GenBank input.
- Parameters:
- Return type:
- attach_metadata(records, path, *, identifier_column='identifier')[source]
Attach CSV/TSV metadata rows to records by unique identifier.
- Parameters:
records (list[SequenceRecord])
identifier_column (str)
- Return type:
References and aggregation
- class codonadaptpy.references.ReferenceProfile(name, counts, genetic_code=1, version='1', source='user-supplied', description='', metadata=<factory>)[source]
Represent versioned codon counts and their scientific provenance.
- Parameters:
- class codonadaptpy.references.ReferenceManager[source]
Manage named codon profiles and reproducible reference persistence.
Initialize a registry containing an explicitly synthetic baseline.
- register(profile, *, replace=False)[source]
Validate and register a profile under its unique name.
- Parameters:
profile (ReferenceProfile)
replace (bool)
- Return type:
None
- from_sequences(name, records, *, genetic_code=1, version='1', source='user CDS set')[source]
Build a reference by pooling strictly validated coding sequences.
- Parameters:
- Return type:
- get(name)[source]
Return a registered profile or raise a domain-specific error.
- Parameters:
name (str)
- Return type:
- class codonadaptpy.aggregation.CDSAggregator(analyzer)[source]
Group CDS records and calculate gene-wise plus genome-wide results.
Initialize aggregation around an existing configured analyzer.
- Parameters:
analyzer (CodonAnalyzer)
Comparative analysis and visualization
- class codonadaptpy.comparative.ComparativeAnalyzer[source]
Provide group-level statistical and multivariate analysis helpers.
- group_summaries(records, *, group_key, metric_keys)[source]
Summarize selected numeric metrics for each metadata group.
- compare_two_groups(left, right, *, test='welch')[source]
Run Welch or Mann-Whitney testing and calculate Hedges’ g.
- automatic_test(left, right, *, paired=False, alpha=0.05, estimand='mean', confidence=0.95, bootstrap_replicates=2000, random_seed=1)[source]
Run an estimand-first paired or independent two-sample analysis.
estimand="mean"tests a mean difference using a paired t test or Welch’s unequal-variance t test.estimand="distribution"tests a paired shift with Wilcoxon’s signed-rank test or an independent stochastic-ordering difference with the Mann–Whitney U test. This choice is made from the scientific estimand and sampling design, not from a preliminary normality-test decision.Normality diagnostics remain available as model checks. The result also includes a percentile-bootstrap confidence interval for the corresponding location contrast and an effect size appropriate to the selected design. Missing and non-finite observations are removed; in paired mode, pairs are removed together to preserve correspondence.
- multivariate(matrix, *, components=2)[source]
Return standardized PCA scores, loadings, variance, and distances.
- hierarchical_clustering(matrix, *, method='average', metric='euclidean')[source]
Return SciPy linkage and leaf order for reproducible clustering.
- linear_discriminant(matrix, labels, *, test_size=0.3, random_seed=1)[source]
Train and evaluate stratified linear discriminant classification.
The returned projection contains every input observation, while the confusion matrix and classification report are calculated only from the held-out test subset. The split indices and random seed are retained to make reported accuracy exactly reproducible.
- repeated_grouped_discriminant(matrix, labels, groups, *, folds=5, repeats=20, random_seed=1, shrinkage=True)[source]
Evaluate LDA with repeated stratified, group-exclusive folds.
All observations sharing a group are kept in the same fold, preventing exact duplicates, isolates, or sequence clusters from appearing in both training and test data. Metrics are reported per fold and as mean, standard deviation, and percentile intervals across all held-out predictions. Shrinkage LDA is used by default for high-dimensional codon-feature matrices.
- class codonadaptpy.visualization.PlotManager[source]
Build optional interactive Plotly figures for self-contained HTML.
- sliding_cai(result)[source]
Create an interactive sliding-window CAI line profile.
- Parameters:
result (AnalysisResult)
- Return type:
- class codonadaptpy.visualization.PublicationPlotManager[source]
Create journal-ready static figures from CodonAdaptPy outputs.
The manager uses the Okabe-Ito colorblind-safe palette, redundant marker shapes, outward-offset axes, visible individual observations, and vector- compatible Matplotlib artists. Matplotlib is imported lazily so sequence analysis remains dependency-free.
- ordination(scores, labels, groups, *, x_label='Axis 1', y_label='Axis 2', title='Ordination')[source]
Plot grouped two-dimensional scores with centroid standard errors.
Individual samples are shown with color and shape encoding. Larger black-edged points show group centroids, and error bars represent the standard error independently along both axes.
- metric_panels(rows, *, metrics, group, title='Metric distributions', columns=2)[source]
Create box-and-point panels for numeric metrics grouped by metadata.
Boxes show the median and interquartile range; whiskers follow the conventional 1.5-IQR rule. Every observation is overlaid using deterministic horizontal jitter, and each category label includes its sample size.
- codon_preference_intersections(results, *, group_key, threshold=1.6)[source]
Return exact overlaps of preferred codons across metadata groups.
A codon belongs to a group’s preferred set when its group-mean RSCU is greater than or equal to
threshold. Each intersection is exact: a codon assigned to groups A and B is absent from every other displayed group. The structured result supports auditable tables as well as the UpSet-style visualization.
- codon_preference_upset(results, *, group_key, threshold=1.6, max_intersections=20, title='Shared preferred-codon signatures')[source]
Plot exact preferred-codon intersections in an UpSet-style layout.
The upper bars report the number of codons in each exact intersection, the matrix identifies participating metadata groups, and the left bars report each group’s total preferred-codon set size. This avoids the area-comparison problems of multi-set Venn diagrams.
- rscu_similarity_heatmap(results, *, group_key, title='RSCU signature similarity')[source]
Plot cosine similarity among group-mean 59-codon RSCU profiles.
- rscu_pca_biplot(results, *, group_key, max_loadings=10, title='RSCU principal-component biplot')[source]
Plot standardized 59-codon RSCU scores and influential codons.
- metric_correlation_heatmap(results, *, metrics=None, title='Codon-analysis metric correlations')[source]
Plot Pearson correlations among variable scalar analysis metrics.
- host_adaptation_landscape(results, *, group_key, title='Multi-host codon-adaptation landscape')[source]
Plot CAI against RCDI for every host, with SiD encoded by area.
- dinucleotide_heatmap(results, *, group_key, title='Mean dinucleotide observed/expected ratios')[source]
Plot mean O/E ratios for all 16 dinucleotides by metadata group.
- rscu_heatmap(results, *, group_key, title='Mean relative synonymous codon usage')[source]
Plot group-mean RSCU values for all available sense codons.
- evolutionary_diagnostics(results, *, group_key, title='Evolutionary codon-usage diagnostics')[source]
Create ENC-GC3, neutrality, and PR2 panels by metadata group.
- rscu_profiles(results, *, group_key, title='Relative synonymous codon usage profiles')[source]
Plot group-mean 59-codon RSCU profiles with standard errors.
Codons are arranged by amino-acid family and colored by their third nucleotide. Horizontal reference lines identify the conventional underrepresentation (0.6) and preference (1.6) thresholds.
- dinucleotide_profiles(results, *, group_key, title='Dinucleotide observed/expected profiles')[source]
Plot all 16 group-mean dinucleotide O/E ratios with SEM bars.
- composition_overview(results, *, group_key, title='Nucleotide composition and codon bias')[source]
Create four panels summarizing composition, positional bias, and ENC.
- lda_evaluation(analysis, groups, *, title='Linear discriminant analysis')[source]
Plot an LDA projection beside its held-out confusion matrix.
- host_adaptation(rows, *, metrics, group_key, host_key, title='Host adaptation')[source]
Plot host metrics by genotype with observations, means, and SEM.
- bland_altman_validation(panels, *, title='Method Validation: Bland-Altman and Residual Agreement')[source]
Create multi-panel Bland-Altman and residual agreement plots.
Each dictionary in
panelsmust supply: -metric: str metric label (e.g. ‘CAI’, ‘ENC’, ‘RSCU’, ‘GC3s’) -reference: list[float] reference or benchmark values -tool: list[float] CodonAdaptPy calculated values
Phylogenetics and temporal analysis
- class codonadaptpy.phylogenetics.PhylogeneticAnalyzer(*, mafft='mafft', iqtree=None, fasttree=None, trimal='trimal')[source]
Run alignment and maximum-likelihood phylogenetic inference.
- Parameters:
Notes
External tools remain optional package dependencies. Methods raise an informative
RuntimeErrorwhen the selected executable is not available. IQ-TREE ultrafast bootstrap values should generally use at least 1,000 replicates for a publication analysis.- static write_fasta(records, destination)[source]
Write unique, non-empty sequence records as wrapped FASTA.
- Parameters:
records (Iterable[SequenceRecord])
- Return type:
- align(input_fasta, output_fasta, *, method='auto', threads=1)[source]
Align sequences with MAFFT and return the output path and command.
- trim(alignment, destination, *, mode='automated1', required=False)[source]
Trim an alignment with trimAL, or retain it when trimming is optional.
- infer_tree(alignment, output_prefix, *, method='iqtree', sequence_type='nt', model='MFP', bootstrap=1000, threads=1)[source]
Infer an ML tree with IQ-TREE ModelFinder or approximate FastTree.
- class codonadaptpy.phylogenetics.TemporalAnalyzer[source]
Estimate temporal signal and deterministic dated-tree summaries.
ETE3 is imported lazily so codon-only workflows remain dependency free. The input tree should contain branch lengths in substitutions per site. Sampling dates are decimal calendar years keyed by exact leaf names.
- classmethod load_tree(tree, *, midpoint_root=True)[source]
Load or copy an ETE3 tree and optionally apply midpoint rooting.
- temporal_signal(tree, sample_dates, *, strata=None, midpoint_root=True, optimize_root=False, permutations=0, random_seed=1)[source]
Regress root-to-tip divergence on sampling date.
A positive slope is interpreted as an exploratory strict-clock rate. When
permutationsis positive, sampling dates are randomized and the complete root-selection procedure is repeated for every replicate. Whenstratais provided, dates are permuted strictly within each stratum (e.g. genotype or lineage) to avoid confounding between group membership and sampling date. The resulting empirical p value therefore accounts for optimization over candidate roots. At least three dated tips and two distinct sampling years are required.
- date_tree(tree, signal, *, midpoint_root=True)[source]
Attach deterministic calendar dates to every ETE3 node.
Internal dates follow the fitted strict-clock transform of root distance. Tips retain an additional
observed_datefeature when a sampling date is available. The returned topology is suitable for exploratory time-tree plotting and lineage-through-time summaries.
- class codonadaptpy.phylogenetics.PhylogeneticComparator[source]
Compare whole-genome and gene-tree topologies on their shared tips.
- robinson_foulds(first, second)[source]
Calculate unrooted Robinson-Foulds distance after shared-tip pruning.
The normalized distance is zero for identical shared-tip bipartitions and approaches one as topologies become maximally discordant. At least four shared tips are required for an informative unrooted comparison.
- class codonadaptpy.phylo_visualization.ETE3TreePlotter[source]
Render ETE3 phylogenies with consistent publication styling.
- tree(tree, *, groups=None, title='Maximum-likelihood phylogeny', show_support=True, minimum_support=70.0, time_scaled=False, label_tips=True, align_tip_labels=True, tip_font_size=7.0, support_font_size=6.5)[source]
Plot a branch-length or calendar-time rectangular phylogeny.
- Parameters:
groups (Mapping[str, str] | None) – Optional mapping from leaf name to genotype/group.
show_support (bool) – Label internal support at or above
minimum_support.time_scaled (bool) – Use each node’s
calendar_datefeature for x.label_tips (bool) – Show leaf names; disable for dense overview trees.
align_tip_labels (bool) – Place names in one right-hand column connected to their terminal nodes by dotted leader lines.
tip_font_size (float) – Tip-label size in points. The default remains legible when a dense tree is reproduced at journal width.
support_font_size (float) – Internal branch-support label size in points.
title (str)
minimum_support (float)
- Return type:
- temporal_signal(analysis, *, groups=None, title='Root-to-tip temporal signal')[source]
Plot root-to-tip regression with sample identities and group encoding.
- lineage_through_time(trajectories, *, title='Lineage-through-time trajectories', normalize=True)[source]
Plot deterministic dated-tree lineage trajectories.
This figure is an exploratory demographic proxy. It does not estimate effective population size and its lines are not Bayesian posterior medians or highest-posterior-density intervals.
Sequence design and reporting
- class codonadaptpy.optimizer.OptimizationConfig(direction='optimize', candidates=5, iterations=5000, seed=1, target_gc=None, gc_tolerance=0.05, avoid_motifs=(), preserve_motifs=(), remove_restriction_sites=(), add_restriction_sites=(), max_homopolymer=6, target_cpg=None, target_upa=None, cai_weight=1.0, gc_weight=1.0, motif_penalty=10.0, pair_weight=0.0)[source]
Configure candidate search objectives and hard/soft constraints.
- Parameters:
- class codonadaptpy.optimizer.CodonOptimizer(reference_counts, *, genetic_code=1, pair_scores=None)[source]
Generate and rank synonymous sequences using seeded stochastic search.
Initialize optimizer with a target reference profile.
- Parameters:
- optimize(sequence, config=None)[source]
Generate several ranked synonymous candidate coding sequences.
- Parameters:
sequence (str)
config (OptimizationConfig | None)
- Return type:
OptimizationResult
- class codonadaptpy.reporting.ReportGenerator[source]
Export package results to machine-readable and publication-friendly files.
- write_table(results, path, *, delimiter=None)[source]
Write one flattened scalar-metric row per sequence as CSV or TSV.
- write_html(results, path)[source]
Write a self-contained HTML summary without a template dependency.