Both return tale_id, rvds, subj_seq_id, start, end, strand,
ebe_seq and score, in that order, then their own column (rank for
Talvez, pval for PrediTALE). tales_predict_targets() puts its method
column before the tool's own. Three columns are renamed to follow the
package's snake_case rule: taleId to tale_id, subjSeqId to
subj_seq_id and ebeSeq to ebe_seq.
The score next to each TALE name is printed with two decimals and no leading zeros (PrediTALE's 0.24 used to read "00.24"). The legend names the three match levels: the RVD's preferred base, an intermediate one, and its least preferred.
Any argument passed through it made the call fail, gap_symbol included.
tales_align() stores the column it aligned on (residue_col), the
scoring it was given (domain_distances) and MAFFT's options with the
alignment. The new tales_msa_params() returns them, so an alignment
holding both rvd and dom_code says which one it was made from.
group_col defaults to "group", the column tales_group_kmedoids() and
tales_group_hclust() add.
A terminus is coded NTERM or CTERM only when its protein segment
matches the TALE terminal-domain profile over at least 90% of the profile
(new argument terminus_min_cover of tell_tales() and
tales_from_annotale()), on top of the E-value and the requirement to
reach the repeats. A truncated terminus, such as the C-terminus of a
truncTALE, is now XXXXX. The threshold was set on the curated TALEs of
tale_annotations: their canonical termini cover 0.93 of the profile or
more, the truncTALE termini 0.84 or less. tales_anomalies() reports such
termini as terminus_noncanonical (formerly terminus_unmatched).
tales_anomalies() gains a kind column. "noncanonical" marks a TALE of
non-standard structure, with a terminus that is not canonical or none on
one side; "integrity" marks data that are inconsistent or incomplete,
and arrays without repeats. sanitize = TRUE (in tales(),
tales_bind(), tales_from_telltales() and tales_from_annotale()) now
drops only the arrays with an anomaly of kind "integrity", and keeps
truncTALEs and other non-canonical TALEs with a message.
sanitize = "canonical" drops every array with an anomaly of either kind,
so that only canonical TALEs remain.
array_report.tsv now says, for each terminus, how much of the TALE
terminal-domain profile its protein segment covers (*_aa_cover), how far
the match stops from the far end of the profile (*_aa_far_gap), in how
many pieces it matches (*_aa_domains) and its bit score (*_aa_score).
At the DNA level, it reports the best nhmmer hit of the terminus profile
next to the repeats even when it scores below nterm_min_score or
cterm_min_score (*_dna_score, *_dna_evalue), the fraction of the
profile those hits cover (*_dna_cover) and how many there are
(*_dna_pieces). A truncated terminus, or one split by a deletion, can now
be read from the report. hits_report.tsv and the two GFF files carry each
hit's score, E-value and profile positions.
tell_tales() always merges overlapping nhmmer hits of the same domain
type, and the merge_hits argument is gone. With merge_hits = FALSE, a
repeat reported as two overlapping hits was counted twice in n_dna_hits
and by min_array_length, with no other effect. The unmerged hits are
still written to all_ranges.gff, beside the merged ranges.
With plot_type = "all" and the default margins, the strain names, the
group names and the title get the room their text takes, whatever the size
of the device, so they are no longer clipped or overlapped in a small
figure. Images written with save_path are 300 dpi (formerly 1440).
Talvez, the only Perl program tantale runs, uses the Perl of
tantale's conda environment. tantale_setup() no longer looks for Perl
on the PATH, and the README and DESCRIPTION no longer list it.
When no conda or mamba installation can be found, the functions that run
MAFFT, HMMER or mmseqs2 stop with a message that says so and points to
tantale_setup(), under the condition class tantale_error_tool_missing.
The error used to come from reticulate, wrapped in an unrelated message
about %in%.
run_annotale_load_classes() fetches AnnoTALE's curated catalogue of TALE
classes, and run_annotale_assign() places a set of TALEs into it,
proposing the systematic names the literature uses (TalAH, TalBK).
Until now tantale wrapped only run_annotale_build(), which groups the
TALEs you give it among themselves and cannot say what the rest of the
world calls them. The catalogue takes about a quarter of an hour to
download and is around 440 MB, so keep it and reuse it rather than
fetching it per call.
A new dataset gives the TALEs of ten complete, published Xanthomonas
oryzae genomes, 128 of them, with the names the literature uses, AnnoTALE
classes, RVD strings, the nine naturally truncated TALEs flagged, and
notes on the arrays with an unusual structure. The AnnoTALE class is
given without the member index that usually follows it (TalAH, not
TalAH30): that index numbers a class's members as of the day it is
read, and the catalogue grows. 127 of the 128 TALEs carry a class. Three of the ten genomes
are the ones tantale_setup() installs, so a tell_tales() run on MAI1,
BAI3 or PXO86 can be checked against it. Compiled by Bao Tram Vi; see
?tale_annotations.
tell_tales(), run_annotale_predict() and run_annotale_build() no
longer write to the working directory when output_dir is not given, and
correct_tales() no longer writes correctedTALEs.fa there: the
defaults are now a new directory, or file, under tempdir(), which R
deletes when the session ends. Give output_dir or corrected_path to
keep the results. A package should not write to the working directory
unasked (CRAN policy, rOpenSci review).
run_annotale_predict() and run_annotale_build() now return their
output directory invisibly, as tell_tales() does, in place of 0. Calls
compose: tales_from_telltales(tell_tales(genome)),
tales_from_annotale(run_annotale_predict(genome)),
tell_tales(correct_tales(genome)).
library(tantale) no longer prints a greeting.
citation("tantale") gives a reference for the package and lists the
papers of the methods it wraps or reimplements. DESCRIPTION declares the
system requirements (Java 8 or later, Perl, and conda, mamba or
micromamba) and lists Alvaro L. Pérez-Quintero as copyright holder of the
bundled TALVEZ and FuncTAL material.
run_annotale_predict() and run_annotale_build() gain opt_param, a
string of options passed to AnnoTALE, as preditale() already had. Their
defaults write out AnnoTALE's own: "Sensitive=false" for predict (its
sensitive scan needs more than 1 GB of Java memory) and "c=5 s=0.01"
for build (the class cutoff and the significance level). The two, and
preditale(), refuse an opt_param that sets a key they set themselves
(an input file, outdir=): AnnoTALE and PrediTALE would silently keep
only one of the two values.
These three functions and correct_tales() gain java_args, options for
the Java virtual machine, such as "-Xmx8G" to raise its memory limit.
The memory settings that were fixed in the code are now its defaults:
"-Xms512M -Xmx6G" for run_annotale_build(), "-Xms512M -Xmx2G" for
preditale().
AnnoTALE, PrediTALE and TALEcorrection (about 60 MB) and the four example
genomes of the articles (about 20 MB) are no longer part of the package,
which shrinks from 57 MB to about 1 MB. They are attached to the releases
tools-1 and genomes-1 of the GitHub repository, and
tantale_setup(install = TRUE) downloads them, checks them against
checksums recorded in the package, and unpacks them into
tools::R_user_dir("tantale", "data"), or into the directory named by the
environment variable TANTALE_DATA_DIR. tantale_setup(archive_dir = )
installs them from archives downloaded beforehand, for a machine without
internet access. The wrappers' tool arguments default to the downloaded
copies and still accept a path to another version. The new
tantale_genome() returns the path of an example genome, in place of
system.file("extdata", "MAI1.fa", package = "tantale"). tantale now
needs R 4.0.0 or later.
inst/legacy/, which kept retired code and the QueTAL FuncTAL program,
is deleted; nothing used it. The FuncTAL table behind
rvd_dna_specificity is unchanged.
tell_tales(correct_array = TRUE) now aligns each candidate array against
the 50 closest references by default, where it used to try all of them.
On the four genomes shipped with the package, 50 gives the same corrected
sequences as the full search in a quarter of the time or less (61 s
against 455 s on BAI3-1-1). Fewer than 50 left one BAI3-1-1 array badly
corrected; ?tell_tales gives the measurements. max_comparisons = NULL
still searches the whole reference.
tales_from_telltales() warns about every candidate array that has a
TALE terminus DNA hit in array_report.tsv but that AnnoTALE could not
split into parts. Such an array is absent from the result, so
tales_anomalies() cannot report it, and until now only tell_tales.log
recorded it.
tales_anomalies() returns its rows sorted by array_id, then by check.
plot() on a tales lists the arrays from the top in alphabetical order
of array_id. Both compare identifiers byte by byte, as the other
functions of the package do, so the order does not depend on the locale.
talomes_heatmap() also accepts a tales object that carries a group and
a strain column, with one value per array, such as the output of
tales_group_kmedoids() or tales_group_hclust() once a strain column
is added. It computes the RVD sequences itself with
tales_rvd_strings(), so rvd_col is not needed. A data frame with one
row per TALE still works as before.
All plots now draw on one colour style, built from Paul Tol's colour
schemes and checked against the three common forms of colour blindness.
plot() on a tales colours each part by its role: the canonical 34-aa
repeat and the final 20-aa half-repeat in calm colours, other repeat
lengths in strong ones, N-termini in shades of wine and C-termini in
shades of teal, lighter when shorter. The outline gives the domain type;
the fill legend gives the length, each key outlined like its parts. Termini are labelled N- and -C, or ?? when they do not match
their TALE domain profile. RVD labels are black or white, whichever reads
better on the fill; panel labels sit on a pale band. plot() on a
tales now returns the plot without drawing it, as ggplot2 functions do,
so the console draws it once and a composition of several plots draws
only the composition. In plot() on a
tales_msa, the cell text is black where it matches the consensus and red
where it does not, and all fills are pale enough for both to read.
The dendrogram of tales_group_hclust(plot_tree = TRUE) prints each
group's number under its clade, and its colours only tell neighbouring
clades apart, so it stays readable with 25 groups or more; the cut height
moved to the subtitle. In plot_target_preds() the match score is shown
in shades of purple, from pale for a good match to dark for a poor one,
and the DNA bases keep their colours. In talomes_heatmap() the variant
colours run from pale wine for the most common variant to dark wine for
the rarest present, however many variants a group has; colors now gives
the end points of that range. A strain with no member in a group gets a
white cell. The dendrograms take space in proportion to the heatmap
(margins = NULL, the new default), so they no longer dominate a small
talome. The package no longer imports biovizBase or
viridis.
tales_names(x) returns the identifiers of the TALEs in a tales or
tales_msa object, once each, in the order they appear. It replaces
unique(x$array_id) and gives the same values as the names of
tales_rvd_strings(x). names(x) still returns the column names, as for
any data frame.
A contributing guide (.github/CONTRIBUTING.md) explains how to report a
problem and how to prepare a change. is_tales(), is_tales_msa(),
is_pairwise_distances(), validate_tales_msa(),
validate_pairwise_distances() and tales_msa_width() have examples. The
PDF manual builds (the package logo is shown in the HTML help only).
Internal loops and per-element computations no longer assume a non-empty
input or a particular result type.
A segment that AnnoTALE reports on either side of the repeats is now coded
NTERM/CTERM only if its match to the TALE terminal-domain profile also
reaches, within 10 positions, the end of the profile that adjoins the
repeats. A frameshift inside a terminus puts its repeat-side part in
another reading frame, so such a segment matched the profile strongly up
to the frameshift and was coded as a terminus; it is now XXXXX, and
tales_anomalies() reports it as terminus_unmatched. Genuine termini
truncated at their far end, as in truncTALEs, are unaffected. In the raw
BAI3-1-1 assembly, four N-termini change. array_report.tsv gains
nterm_aa_profile_gap and cterm_aa_profile_gap, the number of profile
positions between the match and that end. tell_tales() output written
before this change keeps its old codes until it is rerun.
The x-axis of plot.tales_msa() counts alignment columns, and its title
now says so. It read "Position in array", which is the title
plot.tales() uses for a domain's position within its own array.
The last errors that carried only the generic tantale_error class now
also carry a specific one (tantale_error_bad_argument,
tantale_error_missing_file, tantale_error_annotale_file), so code
that calls tantale can tell them apart. correct_tales() now names the
input file it cannot find.
The summary tell_tales() prints at the end of a run is now shown as it
is written in tell_tales.log, one line per entry. It used to be wrapped
into a single paragraph, and a subject file or output directory whose
path contained braces ({...}) made tell_tales() fail at that last
step.
tales_rvd_strings(), tales_coded_strings(), tales_get_protein_seq(),
tales_get_dna_seq() and tales_align() order arrays by array_id
compared character code by character code (the C locale), whatever the
session's language settings. Before, the order followed the session's
alphabetical rules, so "BAI3-1-1_ROI_00001" came after
"BAI3_ROI_00001" in an English or French session and before it
elsewhere.
The new facet_by argument of plot.tales() names the columns that split
the plot into panels: "seqnames" (the default, as before), "strain"
for a set of genomes, several columns at once, or NULL for a single
panel. Each column must hold one value per array.
The main vignette is now vignettes/tantale.qmd, which the website links
as "Get started" in its menu bar.
tales_anomalies(), and so the warning of tales(), now report every
array that is not a standard TALE: an N-terminus, one or more repeats and
a C-terminus, both termini matched by the profile of their TALE domain.
The new checks are terminus_absent, no_repeat and
terminus_unmatched (a terminus coded XXXXX). They need a
domain_type column, and terminus_unmatched an rvd column.
tales(x, sanitize = TRUE) drops these arrays. tales_assign_domain_codes()
and tales_align() no longer repeat the anomaly warning already given
when their input was built.
tales_from_annotale() builds a tales object from AnnoTALE's own TALE
predictions, the output of run_annotale_predict(). Termini are coded as
in tell_tales(), from a search with the TALE N- and C-terminal protein
profiles. array_id is AnnoTALE's TALE name, and seqnames comes from
AnnoTALE's GFF3 file when it is present. An example output ships in
inst/extdata/annotaleExampleOutput.
tales_from_telltale() is now tales_from_telltales(), since it reads
the output of tell_tales(). tales_width() is now tales_msa_width(),
since it applies to tales_msa objects only. The rvd_only argument of
tales_rvd_strings() is now repeats_only, as in
tales_coded_strings().
tale_parts_to_rvd() is gone; tales_rvd_strings(x, repeats_only = FALSE) returns the same strings. repeat_to_rvd_map() and
repeat_to_rvd_map_distalr() are gone: the dom_code and rvd columns
of a tales object hold that mapping, and tales() reports an amino acid
sequence paired with more than one RVD as an anomaly.
tales() and pairwise_distances() (with tale_distances() and
domain_distances()) no longer rename the camelCase columns of earlier
versions (arrayID, positionInArray, TAL1, RepU1, Sim,
arlemScore...). A table saved by an earlier version needs its columns
renamed to the current names first (array_id, position_in_array,
id1, sim, arlem_score...).
tell_tales() now searches the segment AnnoTALE reports on each side of
the repeats with the TALE N- and C-terminal protein profiles shipped in
inst/extdata/hmmProfile/ (hmmsearch). NTERM and CTERM mark a
segment that matches its profile with an E-value at most
terminus_max_evalue (new argument, default 1e-5); XXXXX marks a
segment that does not match. The codes used to record whether an nhmmer
hit of that terminus type was found anywhere in the array's DNA. That
labelled as termini some segments of unrelated sequence, where the ORF
starts or ends in a frameshifted region, and coded as XXXXX genuine
termini too short for the DNA search, such as a C-terminus truncated to
42 residues.
tales_from_telltales() reads the codes from array_report.tsv. A
directory written by an earlier tell_tales() is an error; run
tell_tales() again on the same sequences.
n_domain_hits is now n_dna_hits, and has_all_domains is replaced by
nterm_dna_hit and cterm_dna_hit. New columns nterm_aa_evalue,
cterm_aa_evalue, nterm_aa_hit and cterm_aa_hit hold the result of
the protein-profile search. ?tell_tales describes every column. The
argument min_domain_hits of tell_tales() is now min_dna_hits.
When AnnoTALE reports no terminus on one side of the repeats, the array
now has no part on that side, with a warning, and its positions are
counted from its first part. It used to receive an empty part. An array
whose AnnoTALE protein and DNA parts disagree is left out with a warning,
and tell_tales() deletes the DNA parts AnnoTALE writes for an ORF it
could not translate. Repeat RVDs are read from AnnoTALE's own RVD file.
The warning about overlapping nhmmer hits now concerns only hits of the
same domain type, which make n_dna_hits count a domain twice; it
appears only with merge_hits = FALSE. A terminus hit overlapping the
adjacent repeat hit by a few nucleotides is normal and no longer
reported. Two warnings from the underlying Bioconductor packages are
gone: "invalid seqlevels ... ignored", issued when a subject sequence
carried no TALE, and "GRanges object contains ... out-of-bound ranges",
issued when an array lies within extend_len of a sequence end (the
extended range was, and still is, clipped to the sequence).
tell_tales() no longer writes a .fai index next to the subject file,
and Rsamtools is no longer a dependency. Sequence lengths now come from
the full fasta headers: with a header containing a space, they used to
be lost, so an array near the end of such a sequence could be extended
past it. A subject file with duplicated or empty sequence names is an
error.
inst/COPYRIGHTS lists every program and data file tantale bundles from
other projects, with its authors, licence, upstream download and source
code: AnnoTALE, PrediTALE and TALEcorrection (GNU GPL 3 or later, from
the Jstacs project), TALVEZ 3.2 and QueTAL FuncTAL (redistributed by
permission of their author). The GPL text ships as
inst/tools/COPYING.GPL-3. tantale's own code stays under the MIT
licence.
The row for the RVD NA (Asn-Ala) had a missing name, because the table
was read with the string "NA" taken as a missing value. As a result,
tales_to_universalmotif() and tales_compare_functal() gave every NA
repeat the flat XX profile instead of its own (1/2/1/0). Fixed; no
other row changed.
plot.tales_msa(fill_type = "rvd_sim") takes its RVD similarities from
TALVEZ's table, which covers 17 RVDs. Any other RVD (NV, for example)
was left grey, even where it was identical to the reference's. It now
scores 1 there, as it already did in tales_align()'s RVD scoring
matrix; other pairs involving it stay grey. The legend says what grey
means.
From version 1.0.0 on, changes to exported functions and their arguments follow the lifecycle conventions: deprecation with a warning first, removal in a later release.
tales_to_universalmotif() and tales_compare_functal() read the
rvd_dna_specificity table by a name that resolved only once tantale was
attached, so calling them as tantale::tales_to_universalmotif() failed
with "object 'rvd_dna_specificity' not found". Fixed.
With the default plot_type = "all", the title, x_lab and y_lab
arguments were ignored (the default text was drawn whatever was passed),
and saving to save_path left an extra graphics device open. Both fixed;
the default figure is unchanged. An explicit save_path = NULL now draws
on the current device, and an unknown plot_type is an error instead of
drawing nothing.
nHMMER (in tell_tales() and correct_tales()), AnnoTALE
(run_annotale_predict(), run_annotale_build()), PrediTALE
(preditale()) and TALEcorrection (correct_tales()) were run without
checking their exit status, so a failing program could leave empty or
partial output for later steps to trip over. Each call now stops with an
error naming the program. Inside tell_tales(), an AnnoTALE failure on
one array still skips that array with a warning, which now gives
AnnoTALE's own error as its cause. run_annotale_predict() and
run_annotale_build() return 0 invisibly on success; their paths are
now quoted in the shell command, so paths with spaces work.
plot.tales_msa() and plot_target_preds() used arguments ggplot2 has
deprecated (label.size, and size for a line width), so every plot
raised warnings. They now use linewidth, and the figures are unchanged.
tantale now requires ggplot2 3.5.0 or later.
nterm_aa_length and cterm_aa_length counted AnnoTALE's * as a residue
whenever the stop codon fell inside the terminal part, which is common for
C-termini. They now count residues only, matching the tales object's
aa_seq: for example, a 278-residue C-terminus is reported as 278, not 279.
tales_domain_distances(aln_method = "Biostrings") now aligns with free end
gaps (DisTAL's "sliding ends") instead of a global alignment that charged a
length difference twice. A half-repeat is now about 41 from the full repeat
it matches (it was 64.7), as with the other two backends. Pairs differing
only by substitutions are unchanged.
tales_domain_distances()'s default "DECIPHER" backend ignored gaps, so
a half-repeat was at distance 0 from any full repeat it is a prefix of, and
indels between domains went uncounted. It now follows DisTAL's published
definition (percentage of amino acids that change, normalised by the longer
domain), as the "mmseq2" backend already did: a 20-residue half-repeat is
about 41 from the 34-residue repeat it matches. Domain and array distances
change for pairs that differ in length or align with gaps; on the three
genomes in the articles the grouping is unchanged. With a
domain_distances scoring matrix, tales_align() no longer pulls a
half-repeat away from its identical match.
Every exported function's help page was re-read against the code. Among
the corrections: the pairwise_distances family is now described as the
distance table it is (it stores dissim), repeat_to_rvd_map_distalr()
and tale_parts_to_rvd() document the input they actually take,
rvd_dna_specificity explains its special rows (N*/H*, OO, XX),
talomes_heatmap() explains what its colours mean, and the package page
and README no longer claim that tantale bundles none of the programs it
drives (the Java tools ship with it).
tales_tale_distances(), and so tales_compare_distal(), aligns the
coded arrays with an R implementation of ARLEM's minisatellite alignment
model (Abouelhoda et al., 2009)
in place of the ARLEM 1.0 executable that shipped in inst/tools/arlem/.
The scores are identical to the executable's: checked on about 6000 random
array pairs and on real TALE arrays, and recorded in a test fixture. The
executable ran only on Linux x86-64, and its licence did not clearly allow
redistribution; it has been removed from the package. This also clears the
"undeclared executable file" warning from R CMD check.
The R version takes about 4 ms per pair of 20-domain arrays, roughly five
times the executable's time; the domain-level alignment in
tales_domain_distances() remains the slow step. matrixStats is now
imported. Column names are unchanged (arlem_score, max_length).
as_tales() (and tales()) on a tales_msa returned a plain tales
that still carried the alignment's width, so tales_msa_width() kept
answering on an object that no longer claims to be an alignment. The
width is now removed on demotion, as it already was when
alignment_position is dropped with select().
Every article, the README and the home page were re-read against what
their code actually renders. Statements that disagreed with a table or a
figure are corrected, notably: the truncTALE article (ROI_00001's
N-terminus is reduced like ROI_00019's; correct_tales() leaves
ROI_00001's C-terminus length unchanged), the alignment article (a
domain_distances scoring matrix does not make this group's alignment
more compact; it moves the final half-repeat away from its identical
match), and the home-page dendrogram description (it shows nine groups). The
classification article's motif tree now has tip labels, and its
silhouette plot is described and drawn on every build.
TALEs are not always broken when they are short. PXO86 carries two
naturally truncated TAL effectors (truncTALEs), documented in
Ji et al. 2016 and
Read et al. 2016, and the two
differ enough at the DNA level that they respond differently to
automatic frameshift correction: tell_tales(correct_array = TRUE)
extends one of them as if it were an assembly error, while
correct_tales() leaves both alone. See the new
Genuine truncTALEs and frameshift correction
article for the full comparison.
The "Correcting frameshifts, two ways" and "How much did either
correction actually help?" sections were written against the pre-fix,
swapped-flags correct_tales() (see the bug fix entry below) and
described it as fixing only one of BAI3-1-1's two frameshifted arrays.
With the flags corrected, correct_tales() fixes both on its own; the
article's prose, timing table and coverage figure are updated to match,
verified against a real re-run rather than assumed.
Some of plot.tales_msa()'s internal column names claimed a
repeat-specificity the underlying computation never had (termini are
scored identically to repeats) -- matchConsensusRepeat, repeatClusterId
and repeatSimVsRef are now matchConsensusDomain, domainClusterId and
domainSimVsRef. This only affects code reading plot(msa)'s returned
$data/$plotlist[[i]]$data by column name to compose further layers, per
its own documented pattern -- the figure itself, and every other argument
and return value, are unchanged. The consensus/match computation behind
the alignment's text colour no longer round-trips through a matrix
internally; not user-visible, part of an ongoing internal simplification
(dev/restructuring-notes.md §21, not finished this round).
correct_tales() built its call to TALEcorrection.jar with the repeat-
and C-terminus-domain nHMMER search results assigned to the wrong CLI
flags -- confirmed against the tool's own printed usage, which documents
r= as wanting the repeats file and c= the C-terminus file, exactly
backwards from what every prior call supplied. Every correction run has
therefore been telling the external tool the wrong domain for those two
inputs. Fixed; corrected sequences from correct_tales() may now differ
from previous runs on the same input.
Every exported function and S3 method's documentation was checked for
accuracy against its actual current behaviour, completeness (arguments,
return value, a real runnable example), and consistency of tone --
several stale or copy-pasted descriptions, wrong defaults, and missing
@examples fixed along the way. See dev/restructuring-notes.md §17
for the full record.
functal(), the wrapper around QueTAL's vendored Perl FuncTAL script, is
retired: moved to inst/legacy/ along with the Perl tool itself
(inst/tools/QueTAL_v1.1/ -> inst/legacy/QueTAL_v1.1/), unexported, no
longer built. It could not be fixed in place -- the script needs
Bio::Perl, dropped by BioPerl in the 1.7 reorganisation, and no
perl/bioperl combination available restores it.
In its place: tales_to_universalmotif() converts a tales object into a
list of universalmotif PWMs (one per array, from each array's RVD-to-DNA
binding-specificity weights), and tales_compare_functal() compares them
via universalmotif::compare_motifs(). This is not a port of the old
script's numbers -- compare_motifs()'s Pearson correlation over matched
columns is a different statistic from FuncTAL's single correlation over
the whole flattened, padded region, and the two do not agree. Once a
tales object is a list of real universalmotif motifs, the rest of that
package's toolkit becomes directly usable: motif_tree(), view_motifs(),
scan_sequences(), merge_motifs(), and more.
The pipeline now passes typed objects rather than named lists of plain data
frames. tales_compare() (formerly distalr()) returns three of them:
| element | class |
|---|---|
| tales | tales — the parts table, stamped with a dom_code namespace |
| domain_distances | domain_distances / pairwise_distances |
| tale_distances | tale_distances / pairwise_distances |
These were deprecated in an earlier development commit and are now gone. There
is no alias; master still carries the old API if you need a reference.
| removed | replacement |
|---|---|
| distalr() | tales_compare() |
| tale_parts() | tales_from_telltales() |
| split_list() | as_tales() |
| build_repeat_msa() | tales_align() |
| group_tales() | tales_group() |
distalr()'s six-element list is reduced to the three typed elements above.
coded.repeats.str, repeats.code and repeats.cluster were verified to be
pure projections of the parts table or to have no consumer at all, and are
replaced by tales_coded_strings(), tales_domain_codes() and an explicit
clustering call respectively.
.repeat_to_cluster_align(), which colours the repeat-cluster fill in
plot_tales_msa() and msa_heatmap(), passed a similarity matrix straight
to as.dist(). as.dist() expects a distance, so the dendrogram was built
upside down and the resulting clusters were wrong.
Fixed by inverting to a distance first. Because the cut height is now read on a
distance scale, the h_cut default changes from 90 to 10 in both plotting
functions; if you pass h_cut explicitly, subtract it from 100.
The clusters change: on the reference output, cutting the corrected tree yields 45 clusters where the old code gave 59, with 93.8% pair-agreement between the two partitions.
.cluster_repeats() had the same defect but became unreachable when
distalr() was removed, and has been deleted.
msa_heatmap() is retiredSuperseded by plot_tales_msa() and moved to inst/legacy/. Its six
plot_type values were combinations of features that plot_tales_msa()
exposes as orthogonal arguments; the one thing it did that `plot_tales_msa()
could not -- draw the consensus row -- is now implemented there.
| msa_heatmap(plot_type =) | plot_tales_msa() |
|---|---|
| "repeat.similarity" | fill_type = "repeat_sim" |
| "repeat.clusters" | fill_type = "repeat_clust" |
| "with.rvd" | pass rvd_align |
| "repeat.clusters.with.rvd" | both of those |
| "reference" | pass ref_pattern |
| "consensus" | consensus = TRUE |
save_path has no equivalent because none is needed: the returned ggplot is
ggsave()-able. note_colors likewise -- add a scale to the returned plot.
plot_tales_msa() can draw the consensusconsensus = TRUE now adds a consensus row above the alignment, where it
previously did nothing and the argument was documented as "NOT IMPLEMENTED
YET". The consensus is the most frequent element per column, taken from
rvd_align when supplied and repeat_align otherwise, so it always matches
what the cells are labelled with.
It is drawn as its own panel above the alignment rather than as an extra row.
That is not cosmetic: aplot reorders the alignment's y axis onto the tree's
leaves, so a row the tree has no leaf for is silently dropped.
This was the one feature msa_heatmap() still provided that
plot_tales_msa() did not.
The package mixed four messaging idioms: logger, cat(), base message()
and base stop()/warning(). It now uses cli only, and logger has been
dropped from Imports.
This also fixes a class of bug rather than being cosmetic. Twenty-three call
sites wrote their diagnostic to the logger and then raised a bare stop() or
warning() -- conditions whose message was the empty string. tryCatch() saw
nothing, tests could not assert on them, and if your logger threshold excluded
ERROR the failure was silent. Errors now carry their message on the condition,
with a tantale_error class.
One guard was simply broken: distalr() tested aln_method with
logger::log_errors() && stop("..."). log_errors() installs a global error
handler rather than returning a predicate, so the helpful message was
unreachable and an invalid aln_method produced an unrelated complaint about
calling handlers.
pairwise_distances (formerly pairwise_sim) stores dissim, not sim, and
tale_sim/repeat_sim are now tale_distances/domain_distances.
Two reasons. First, repeat_sim understated its content: 71 of the 251 ids in
the reference output (28%) are terminus domains rather than repeats, so
domain is the accurate word. Second, the distance is the native quantity in
both tables — the aligners emit a dissimilarity, and the TALE-level score is an
ARLEM cost divided by array length — while Sim was a derived 100 - x that
every consumer immediately inverted back. Storing one quantity rather than two
also removes the risk of the two drifting apart.
Legacy tables are still accepted on input: a data frame carrying Sim,
TAL1/TAL2, RepU1/RepU2 or normArlemScore is converted to the
canonical id1/id2/dissim form at construction.
Note the changed reading of the numbers: what used to display as a TALE similarity of 91.75–100 is the same information shown as a distance of 0–8.25.
The tables tantale returns used four naming conventions at once, one of them
with a literal space in a column name. They now use one.
tales tablearrayID, domainType, positionInCrd, dnaSeq, sourceDirectory,
positionInArray, aaSeq and domCode become array_id, domain_type,
position_in_crd, dna_seq, source_directory, position_in_array,
aa_seq and dom_code.
tales() still accepts the old spellings and renames them, so a tell_tales() output directory written by an earlier version still loads.
domain_distances and tale_distances previously disagreed about how to name
the pair being compared -- RepU1/RepU2 in one, TAL1/TAL2 in the other,
and in opposite column orders. Both now use id1, id2 and dissim, with
arlem_score and max_length alongside for the TALE table.
pairwise_distances() accepts TAL1/RepU1/Sim/Dissim/arlemScore and
renames them, and plot_tales_msa() puts its tal_sim and repeat_sim
arguments through it, so passing an old-format table still works.
tell_tales() writes array_id instead of arrayID in arrayReport.tsv,
domainsReport.tsv and hitsReport.tsv, and the GFFs derived from them carry
an array_id attribute. Scripts that read these files by column name need
updating.
.tale_parts_from_file() named its column arrayIDs when the input was
empty and arrayID otherwise, so the two returns had incompatible schemas.repeat_to_rvd_map_distalr() and tale_parts_to_rvd() are documented as
taking a tales_compare() result but read the pre-class column names, so
both had been broken against that result..repeat_to_cluster_align() recovered a distance by computing 100 - Sim
before clustering, which assumed the scale ran 0-100. It now reads the
stored distance.if (class(x) == "...") comparisons became inherits().The package had accumulated two incompatible naming styles (camelCase, snake_case, and some dot.case) across its history, which made the API hard to predict and, in argument names, occasionally collided with R's own S3 dispatch conventions. Every exported function, and most internal ones, have been renamed to a single consistent snake_case style. There is no backward-compatible alias for any old name — this is a clean break, not a deprecation cycle. If you have scripts using the old API, use the master branch, which still has the old names, as a reference while you update.
| Old name | New name |
|---|---|
| FuncTAL() | functal() |
| analyzeAnnoTALE() | run_annotale_predict() |
| buildAnnoTALE() | run_annotale_build() |
| buildRepeatMsa() | build_repeat_msa() |
| convertRepeat2RvdAlign() | repeat_to_rvd_align() |
| correcTales() | correct_tales() |
| diagnoseTaleParts() | diagnose_tale_parts() |
| getRepeat2RvdMapping() | repeat_to_rvd_map() |
| getRepeat2RvdMappingFromDistalr() | repeat_to_rvd_map_distalr() |
| getTaleParts() | tale_parts() |
| ggplotTalesMsa() | plot_tales_msa() |
| groupTales() | group_tales() |
| heatmap_msa() | msa_heatmap() |
| heatmap_talomes() | talomes_heatmap() |
| matchConsensus() | tales_consensus_match() |
| plotTaleComposition() | plot_tale_composition() |
| plotTaleTargetPred() | plot_target_preds() |
| taleAlignConsensus() | tales_consensus() |
| taleParts2RvdStringSet() | tale_parts_to_rvd() |
| tellTale() | tell_tales() |
| tellTale2() | removed (was a deprecated alias for tellTale()) |
| toListOfSplitedStr() | split_list() |
| preditale(), talvez(), distalr() | unchanged |
condaBinPath -> conda_binoutputDir / outDir -> output_dir (previously inconsistent across functions)taleSim / talsim -> tal_simrepeatAlign / rvdAlign / repeatSim -> repeat_align / rvd_align / repeat_simrepeat.clust.h.cut / repeats.cluster.h.cut (dot.case) -> h_cutrvdSeqs / subjDnaSeqFile -> rvd_seqs / subj_filetaleParts -> tale_partsPlus function-specific cleanups, notably:
tell_tales()'s verbose scoring arguments (e.g. TALE_NtermDNAHitMinScore -> nterm_min_score, minDomainHitsPerSubjSeq -> min_domain_hits).talomes_heatmap()'s cryptic column-selector arguments (col/row/value -> group_col/strain_col/rvd_col; truncTaleLab -> trunc_tales_col; mapcol/sepwid/sepcol/mar.side -> colors/sep_width/sep_color/margins).Roughly 35 non-exported helper functions were also renamed to snake_case, and every non-exported function now consistently starts with a leading . (this was previously applied only in some files). Since these were never part of the public API, this isn't a breaking change for package users, but it's listed here for anyone reading the source or a diff against an older version. Notable ones, since they change behavior-adjacent naming rather than pure casing:
.distalPairwiseAlign() / 2 / 3 -> .pairwise_align_biostrings() / .pairwise_align_mmseq2() / .pairwise_align_decipher() (named after the actual backend instead of an arbitrary number)convertRepeat2SimAlign(), convertRepeat2ClusterIDAlign(), convertRvd2RepeatAlign(), convertRvd2MatchAlign() -> .repeat_to_sim_align(), .repeat_to_cluster_align(), .rvd_to_repeat_align(), .rvd_to_match_align() (joining the _to_ naming family used by the exported conversion functions)computeRVDSeqEBESeqMatchQualityString() -> .compute_match_string()systemInCondaEnv() / createTantaleEnv() -> .run_in_conda() / .create_tantale_env()group_tales() and talomes_heatmap() called cluster::pam(), viridis::scale_color_viridis() and tidytree::MRCA()/groupClade() without declaring cluster, viridis, or tidytree in DESCRIPTION. Fixed.annoTALE -> annotale_jar argument rename (e.g. "Now running AnnoTALE predict for..." was at risk of becoming "Now running annotale_jar predict for...").