AnnoOddities 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,308 @@
1
+ Metadata-Version: 2.3
2
+ Name: AnnoOddities
3
+ Version: 0.1.0
4
+ Summary: AnnoOddities is a Python utility for detecting, identifying and characterising oddities in genome annotations
5
+ Author: Gemy Kaithakottil, David Swarbreck
6
+ Author-email: Gemy Kaithakottil <Gemy.Kaithakottil@earlham.ac.uk>, David Swarbreck <David.Swarbreck@earlham.ac.uk>
7
+ License: MIT
8
+ Requires-Dist: pyfaidx>=0.5.9.5
9
+ Requires-Dist: pyyaml>=6.0.1
10
+ Requires-Dist: toml>=0.10.2
11
+ Requires-Python: >=3.9
12
+ Description-Content-Type: text/markdown
13
+
14
+ # AnnoOddities
15
+
16
+ AnnoOddies is a Python utility for detecting, identifying and characterising oddities in genome annotations. It parses and integrates statistics from multiple tools - including [AGAT](https://github.com/NBISweden/AGAT), [Mikado](https://github.com/EI-CoreBioinformatics/mikado), and [GFFread](https://github.com/gpertea/gffread), to generate a harmonised set of extended metrics that help assess annotation quality and highlight potential anomalies within genome annotations.
17
+
18
+ In addition to summarising standard outputs, AnnoOddities computes a range of additional “oddity” measures, for example, counts of unusually large or small introns, exons, and untranslated regions; detection of transcripts lacking start or stop codons; identification of in-frame stop codons; estimation of canonical intron proportions; and more. These metrics help flag potential structural inconsistencies or systematic issues in gene models. The consolidated outputs include both summary statistics and detailed per-transcript results, exported in widely used machine- and human-readable formats (TSV, CSV, JSON, YAML, TOML) for flexible downstream analysis and visualisation.
19
+
20
+ Currently, AnnoOddities runs [AGAT](https://github.com/NBISweden/AGAT), [Mikado](https://github.com/EI-CoreBioinformatics/mikado), and [GFFread](https://github.com/gpertea/gffread) to generate and combine statistics into unified reports. Future developments will focus on extending the workflow to incorporate additional quality assessment tools such as BUSCO and OMArk, enabling integrated comparisons of annotation and genome completeness metrics.
21
+
22
+ This tool was developed as part of **[BioHackathon 2025](https://biohackathon-europe.org/), Project 23: Streamlining FAIR Metadata for Biodiversity Genome Annotations**.
23
+ Project details: https://github.com/elixir-europe/biohackathon-projects-2025/blob/main/23.md
24
+
25
+
26
+ ## Installation
27
+
28
+ All installation methods below will install AnnoOddities along with its dependencies.
29
+
30
+ ### Docker Installation
31
+ AnnoOddities can be installed with Docker. If you don't have Docker, please install [docker](https://docs.docker.com/get-docker/) first. Then you can pull the Docker image with AnnoOddities installed
32
+
33
+ ```console
34
+ VERSION=0.1.0
35
+ docker run gemygk/annooddities:v${VERSION} annooddities -h
36
+ ```
37
+
38
+ ### Singularity Installation
39
+ AnnoOddities can be installed with Singularity. If you don't have Singularity, please install [singularity](https://docs.sylabs.io/guides/3.9/user-guide/quick_start.html#quick-installation-steps) first. Then you can pull the singularity image with AnnoOddities installed.
40
+
41
+ We can directly run AnnoOddities from the Singularity image hosted on DockerHub
42
+ ```console
43
+ VERSION=0.1.0
44
+ singularity exec docker://gemygk/annooddities:v${VERSION} annooddities -h
45
+ ```
46
+
47
+ Or, we can build and run a Singularity image, following the steps below:
48
+ ```console
49
+ # Create a Singularity definition file, like below:
50
+
51
+ $ cat annooddities-0.1.0.def
52
+ bootstrap: docker
53
+ from: gemygk/annooddities:v0.1.0
54
+
55
+ # Build the Singularity image
56
+ $ sudo singularity build annooddities-0.1.0.sif annooddities-0.1.0.def
57
+
58
+ # Execute AnnoOddities from the Singularity image
59
+ $ singularity exec annooddities-0.1.0.sif annooddities -h
60
+ ```
61
+
62
+ ### Usage
63
+ ```console
64
+ $ annooddities -h
65
+ usage: annooddities.py [-h] --genome_fasta GENOME_FASTA --gff3_file GFF3_FILE [--five_prime_utr_length FIVE_PRIME_UTR_LENGTH] [--three_prime_utr_length THREE_PRIME_UTR_LENGTH] [--five_utr_num FIVE_UTR_NUM] [--three_utr_num THREE_UTR_NUM]
66
+ [--min_intron_length MIN_INTRON_LENGTH] [--max_intron_length MAX_INTRON_LENGTH] [--min_exon_length MIN_EXON_LENGTH] [--max_exon_length MAX_EXON_LENGTH] [--selected_cds_fraction SELECTED_CDS_FRACTION]
67
+ [--canonical_intron_motifs CANONICAL_INTRON_MOTIFS] [--output_prefix OUTPUT_PREFIX] [--force] [--verbosity {debug,info,warning,error,critical}]
68
+
69
+ Find annotation oddities from GFF3 and genome FASTA files
70
+
71
+ optional arguments:
72
+ -h, --help show this help message and exit
73
+ --genome_fasta GENOME_FASTA
74
+ Provide Genome FASTA file
75
+ --gff3_file GFF3_FILE
76
+ Provide GFF3 file with transcript annotations
77
+ --output_prefix OUTPUT_PREFIX
78
+ Provide sample prefix for the output table [default:output]
79
+ --force Force rerun even if output files exist
80
+ --verbosity {debug,info,warning,error,critical}
81
+ Set logging verbosity level [default:info]
82
+
83
+ Oddity Thresholds:
84
+ --five_prime_utr_length FIVE_PRIME_UTR_LENGTH
85
+ Threshold for 5' UTR length oddity [default:10000]
86
+ --three_prime_utr_length THREE_PRIME_UTR_LENGTH
87
+ Threshold for 3' UTR length oddity [default:10000]
88
+ --five_utr_num FIVE_UTR_NUM
89
+ Threshold for 5' UTR exon number oddity [default:5]
90
+ --three_utr_num THREE_UTR_NUM
91
+ Threshold for 3' UTR exon number oddity [default:4]
92
+ --min_intron_length MIN_INTRON_LENGTH
93
+ Threshold for minimum intron length oddity [default:5]
94
+ --max_intron_length MAX_INTRON_LENGTH
95
+ Threshold for maximum intron length oddity.
96
+ Below are some guidelines:
97
+ - For fungi species, consider setting this to 1000 bp.
98
+ - For plant species, consider setting this to 10000 bp.
99
+ - For invertebrates species, consider setting this to 60000 bp.
100
+ - For vertebrates species, consider setting this to 120000 bp.
101
+ [default:120000]
102
+ --min_exon_length MIN_EXON_LENGTH
103
+ Threshold for minimum exon length oddity [default:5]
104
+ --max_exon_length MAX_EXON_LENGTH
105
+ Threshold for maximum exon length oddity [default:10000]
106
+ --selected_cds_fraction SELECTED_CDS_FRACTION
107
+ Threshold for selected CDS fraction oddity.
108
+ This is the proportion of coding sequence to that of the transcript.
109
+ Values range from 0.0 to 1.0 [default:0.3]
110
+ --canonical_intron_motifs CANONICAL_INTRON_MOTIFS
111
+ Comma-separated list of canonical intron motifs. [default:'GT-AG,GC-AG,AT-AC']
112
+ ```
113
+
114
+ ## Running AnnoOddities
115
+
116
+ ### Example Command
117
+ To run AnnoOddities, use the command line interface with the required arguments for the genome FASTA file and GFF3 annotation file. For example:
118
+ ```console
119
+ annooddities \
120
+ --genome_fasta input_genome.fna \
121
+ --gff3_file input_genome.gff
122
+ ```
123
+
124
+ You can also specify optional parameters to customise the oddity detection thresholds. For example, to set custom thresholds for minimum exon length and maximum intron length (for plants), you can run:
125
+ ```console
126
+ annooddities \
127
+ --genome_fasta input_genome.fna \
128
+ --gff3_file input_genome.gff \
129
+ --min_exon_length 3 \
130
+ --max_intron_length 10000
131
+ ```
132
+
133
+ Or, if you want to restrict canonical intron motifs to only 'GT-AG', you can run:
134
+ ```console
135
+ annooddities \
136
+ --genome_fasta input_genome.fna \
137
+ --gff3_file input_genome.gff \
138
+ --canonical_intron_motifs 'GT-AG'
139
+ ```
140
+
141
+ ## Output
142
+
143
+ An example output directory structure:
144
+ ```console
145
+ CMD: annooddities --genome_fasta input_genome.fna --gff3_file input_genome.gff
146
+
147
+ DIRECTORY: output_directory
148
+ ├── input_genome.fna
149
+ ├── input_genome.gff
150
+ ├── input_genome.agat.log
151
+ ├── output.agat_standardised.gff
152
+ ├── output.agat_standardised.log
153
+ ├── output.agat_standardised.agat.log
154
+ ├── output.agat_sp_statistics.yaml
155
+ ├── output.agat_sp_statistics.txt
156
+ ├── output.agat_sp_statistics.log
157
+ ├── output.agat_sp_statistics.json
158
+ ├── output.agat_sp_statistics.toml
159
+ ├── input_genome.fna.fai
160
+ ├── output.gffread_table.log
161
+ ├── output.gffread_table.tbl
162
+ ├── output.mikado_tab_stats.log
163
+ ├── output.mikado_tab_stats.tsv
164
+ ├── output.mikado_stats.tsv
165
+ ├── output.mikado_stats.yaml
166
+ ├── output.mikado_summary_stats.tsv
167
+ ├── output.mikado_stats.json
168
+ ├── output.mikado_stats.toml
169
+ ├── oddity_files
170
+ │   ├── output.AnnoOddities.has_inframe_stop.gff
171
+ │   ├── output.AnnoOddities.max_exon_length_gt_10000.gff
172
+ │   ├── output.AnnoOddities.min_exon_length_lte_5.gff
173
+ │   ├── output.AnnoOddities.exon_num_eq_1.gff
174
+ │   ├── output.AnnoOddities.exon_num_gt_1.gff
175
+ │   ├── output.AnnoOddities.is_fragment.gff
176
+ │   ├── output.AnnoOddities.not_has_start_codon.gff
177
+ │   ├── output.AnnoOddities.not_has_stop_codon.gff
178
+ │   ├── output.AnnoOddities.not_is_complete.gff
179
+ │   └── output.AnnoOddities.selected_cds_fraction_lte_0.3.gff
180
+ ├── output.AnnoOddities.combined_statistics.yaml
181
+ ├── output.AnnoOddities.combined_statistics.json
182
+ ├── output.AnnoOddities.combined_statistics.toml
183
+ ├── output.AnnoOddities.all_stats.tsv
184
+ ├── output.AnnoOddities.gff
185
+ └── output.AnnoOddities.oddity_summary.txt
186
+
187
+ ```
188
+
189
+ ### AnnoOddities Summary
190
+ Provides both high-level summaries and more granular diagnostic reports to support manual review or automated pipelines.
191
+
192
+ Below is an example of the `AnnoOddities.oddity_summary.txt` output file:
193
+ ```console
194
+ FILE: output.AnnoOddities.oddity_summary.txt
195
+ AnnoOddities output
196
+ exon_num == 1 4520
197
+ exon_num > 1 12900
198
+ five_utr_length > 10000 0
199
+ five_utr_num > 5 0
200
+ three_utr_length > 10000 0
201
+ three_utr_num > 4 0
202
+ not is_complete 428
203
+ not has_start_codon 174
204
+ not has_stop_codon 280
205
+ is_fragment 26
206
+ has_inframe_stop 1
207
+ max_exon_length > 10000 8
208
+ max_intron_length > 120000 0
209
+ min_exon_length <= 5 308
210
+ 0 < min_intron_length <= 5 0
211
+ selected_cds_fraction <= 0.3 158
212
+ canonical_intron_proportion != 1 0
213
+ only_non_canonical_splicing 0
214
+ suspicious_splicing 0
215
+ ```
216
+
217
+ ### AnnoOddities All Stats
218
+ Detailed per-transcript statistics (as detailed below) computed by AnnoOddities.
219
+
220
+ Below are the columns included in the `AnnoOddities.all_stats.tsv` output file:
221
+ ```console
222
+ FILE: output.AnnoOddities.all_stats.tsv
223
+ 1 transcript_id - transcript identifier
224
+ 2 gene_id - gene identifier
225
+ 3 chromosome - chromosome name or number
226
+ 4 start - start position
227
+ 5 end - end position
228
+ 6 region - genomic region in the format chr:start-end
229
+ 7 strand - strand information
230
+ 8 exon_num - number of exons
231
+ 9 exons - list of exon positions
232
+ 10 exon_lengths - list of exon lengths
233
+ 11 max_exon_length - maximum exon length
234
+ 12 min_exon_length - minimum exon length
235
+ 13 total_exon_length - total length of all exons
236
+ 14 cds_exon_num - number of CDS exons
237
+ 15 cds_exons - list of CDS exon positions
238
+ 16 cds_exon_lengths - list of CDS exon lengths
239
+ 17 max_cds_length - maximum CDS exon length
240
+ 18 min_cds_length - minimum CDS exon length
241
+ 19 total_cds_length - total length of all CDS exons
242
+ 20 cds_cdna_ratio - ratio of CDS length to cDNA length
243
+ 21 intron_num - number of introns
244
+ 22 introns - list of intron positions
245
+ 23 intron_lengths - list of intron lengths
246
+ 24 max_intron_length - maximum intron length
247
+ 25 min_intron_length - minimum intron length
248
+ 26 total_intron_length - total length of all introns
249
+ 27 five_utr_num - number of 5' UTRs
250
+ 28 five_utr_length - total length of 5' UTRs
251
+ 29 three_utr_num - number of 3' UTRs
252
+ 30 three_utr_length - total length of 3' UTRs
253
+ 31 has_start_codon - presence of start codon
254
+ 32 has_stop_codon - presence of stop codon
255
+ 33 is_complete - completeness of the transcript
256
+ 34 is_fragment - whether the transcript is a fragment
257
+ 35 has_inframe_stop - presence of in-frame stop codons
258
+ 36 known_strand_junctions_dict - dictionary of known strand junctions
259
+ 37 known_strand_junctions_str - string representation of known strand junctions
260
+ 38 unknown_strand_junctions_dict - dictionary of unknown strand junctions
261
+ 39 unknown_strand_junctions_str - string representation of unknown strand junctions
262
+ 40 canonical_intron_count - count of canonical introns
263
+ 41 non_canonical_intron_count - count of non-canonical introns
264
+ 42 suspicious_intron_count - count of suspicious introns
265
+ 43 unknown_canonical_intron_count - count of unknown canonical introns
266
+ 44 unknown_non_canonical_intron_count - count of unknown non-canonical introns
267
+ 45 unknown_suspicious_intron_count - count of unknown suspicious introns
268
+ 46 unknown_predicted_strand - predicted strand for unknown introns
269
+ 47 canonical_intron_proportion - proportion of canonical introns
270
+ 48 only_non_canonical_splicing - whether only non-canonical splicing is present
271
+ 49 suspicious_splicing - presence of suspicious splicing
272
+ 50 matched_oddities - matched oddities
273
+ ```
274
+
275
+ ### AnnoOddities Combined Statistics
276
+ Consolidated statistics from AGAT, Mikado, GFFread, and AnnoOddities.
277
+ ```console
278
+ FILE: output.AnnoOddities.combined_statistics.yaml
279
+ FILE: output.AnnoOddities.combined_statistics.json
280
+ FILE: output.AnnoOddities.combined_statistics.toml
281
+ ```
282
+
283
+ ### AnnoOddities Individual Oddity GFFs
284
+ Separate GFF3 files for each detected oddity, facilitating targeted review and analysis.
285
+ ```console
286
+ DIRECTORY: oddity_files
287
+ FILE: output.AnnoOddities.has_inframe_stop.gff
288
+ FILE: output.AnnoOddities.max_exon_length_gt_10000.gff
289
+ FILE: output.AnnoOddities.min_exon_length_lte_5.gff
290
+ FILE: output.AnnoOddities.exon_num_eq_1.gff
291
+ FILE: output.AnnoOddities.exon_num_gt_1.gff
292
+ FILE: output.AnnoOddities.is_fragment.gff
293
+ FILE: output.AnnoOddities.not_has_start_codon.gff
294
+ FILE: output.AnnoOddities.not_has_stop_codon.gff
295
+ FILE: output.AnnoOddities.not_is_complete.gff
296
+ FILE: output.AnnoOddities.selected_cds_fraction_lte_0.3.gff
297
+ ```
298
+
299
+ ### AnnoOddities GFF File
300
+ A GFF3 file containing all transcripts annotated with their respective oddities. The oddities are included in the attributes column for easy identification, appeneded to the 'Note' field to the respective transcript entries.
301
+ ```console
302
+ FILE: output.AnnoOddities.gff
303
+ ```
304
+
305
+
306
+ ## License
307
+
308
+ MIT
@@ -0,0 +1,295 @@
1
+ # AnnoOddities
2
+
3
+ AnnoOddies is a Python utility for detecting, identifying and characterising oddities in genome annotations. It parses and integrates statistics from multiple tools - including [AGAT](https://github.com/NBISweden/AGAT), [Mikado](https://github.com/EI-CoreBioinformatics/mikado), and [GFFread](https://github.com/gpertea/gffread), to generate a harmonised set of extended metrics that help assess annotation quality and highlight potential anomalies within genome annotations.
4
+
5
+ In addition to summarising standard outputs, AnnoOddities computes a range of additional “oddity” measures, for example, counts of unusually large or small introns, exons, and untranslated regions; detection of transcripts lacking start or stop codons; identification of in-frame stop codons; estimation of canonical intron proportions; and more. These metrics help flag potential structural inconsistencies or systematic issues in gene models. The consolidated outputs include both summary statistics and detailed per-transcript results, exported in widely used machine- and human-readable formats (TSV, CSV, JSON, YAML, TOML) for flexible downstream analysis and visualisation.
6
+
7
+ Currently, AnnoOddities runs [AGAT](https://github.com/NBISweden/AGAT), [Mikado](https://github.com/EI-CoreBioinformatics/mikado), and [GFFread](https://github.com/gpertea/gffread) to generate and combine statistics into unified reports. Future developments will focus on extending the workflow to incorporate additional quality assessment tools such as BUSCO and OMArk, enabling integrated comparisons of annotation and genome completeness metrics.
8
+
9
+ This tool was developed as part of **[BioHackathon 2025](https://biohackathon-europe.org/), Project 23: Streamlining FAIR Metadata for Biodiversity Genome Annotations**.
10
+ Project details: https://github.com/elixir-europe/biohackathon-projects-2025/blob/main/23.md
11
+
12
+
13
+ ## Installation
14
+
15
+ All installation methods below will install AnnoOddities along with its dependencies.
16
+
17
+ ### Docker Installation
18
+ AnnoOddities can be installed with Docker. If you don't have Docker, please install [docker](https://docs.docker.com/get-docker/) first. Then you can pull the Docker image with AnnoOddities installed
19
+
20
+ ```console
21
+ VERSION=0.1.0
22
+ docker run gemygk/annooddities:v${VERSION} annooddities -h
23
+ ```
24
+
25
+ ### Singularity Installation
26
+ AnnoOddities can be installed with Singularity. If you don't have Singularity, please install [singularity](https://docs.sylabs.io/guides/3.9/user-guide/quick_start.html#quick-installation-steps) first. Then you can pull the singularity image with AnnoOddities installed.
27
+
28
+ We can directly run AnnoOddities from the Singularity image hosted on DockerHub
29
+ ```console
30
+ VERSION=0.1.0
31
+ singularity exec docker://gemygk/annooddities:v${VERSION} annooddities -h
32
+ ```
33
+
34
+ Or, we can build and run a Singularity image, following the steps below:
35
+ ```console
36
+ # Create a Singularity definition file, like below:
37
+
38
+ $ cat annooddities-0.1.0.def
39
+ bootstrap: docker
40
+ from: gemygk/annooddities:v0.1.0
41
+
42
+ # Build the Singularity image
43
+ $ sudo singularity build annooddities-0.1.0.sif annooddities-0.1.0.def
44
+
45
+ # Execute AnnoOddities from the Singularity image
46
+ $ singularity exec annooddities-0.1.0.sif annooddities -h
47
+ ```
48
+
49
+ ### Usage
50
+ ```console
51
+ $ annooddities -h
52
+ usage: annooddities.py [-h] --genome_fasta GENOME_FASTA --gff3_file GFF3_FILE [--five_prime_utr_length FIVE_PRIME_UTR_LENGTH] [--three_prime_utr_length THREE_PRIME_UTR_LENGTH] [--five_utr_num FIVE_UTR_NUM] [--three_utr_num THREE_UTR_NUM]
53
+ [--min_intron_length MIN_INTRON_LENGTH] [--max_intron_length MAX_INTRON_LENGTH] [--min_exon_length MIN_EXON_LENGTH] [--max_exon_length MAX_EXON_LENGTH] [--selected_cds_fraction SELECTED_CDS_FRACTION]
54
+ [--canonical_intron_motifs CANONICAL_INTRON_MOTIFS] [--output_prefix OUTPUT_PREFIX] [--force] [--verbosity {debug,info,warning,error,critical}]
55
+
56
+ Find annotation oddities from GFF3 and genome FASTA files
57
+
58
+ optional arguments:
59
+ -h, --help show this help message and exit
60
+ --genome_fasta GENOME_FASTA
61
+ Provide Genome FASTA file
62
+ --gff3_file GFF3_FILE
63
+ Provide GFF3 file with transcript annotations
64
+ --output_prefix OUTPUT_PREFIX
65
+ Provide sample prefix for the output table [default:output]
66
+ --force Force rerun even if output files exist
67
+ --verbosity {debug,info,warning,error,critical}
68
+ Set logging verbosity level [default:info]
69
+
70
+ Oddity Thresholds:
71
+ --five_prime_utr_length FIVE_PRIME_UTR_LENGTH
72
+ Threshold for 5' UTR length oddity [default:10000]
73
+ --three_prime_utr_length THREE_PRIME_UTR_LENGTH
74
+ Threshold for 3' UTR length oddity [default:10000]
75
+ --five_utr_num FIVE_UTR_NUM
76
+ Threshold for 5' UTR exon number oddity [default:5]
77
+ --three_utr_num THREE_UTR_NUM
78
+ Threshold for 3' UTR exon number oddity [default:4]
79
+ --min_intron_length MIN_INTRON_LENGTH
80
+ Threshold for minimum intron length oddity [default:5]
81
+ --max_intron_length MAX_INTRON_LENGTH
82
+ Threshold for maximum intron length oddity.
83
+ Below are some guidelines:
84
+ - For fungi species, consider setting this to 1000 bp.
85
+ - For plant species, consider setting this to 10000 bp.
86
+ - For invertebrates species, consider setting this to 60000 bp.
87
+ - For vertebrates species, consider setting this to 120000 bp.
88
+ [default:120000]
89
+ --min_exon_length MIN_EXON_LENGTH
90
+ Threshold for minimum exon length oddity [default:5]
91
+ --max_exon_length MAX_EXON_LENGTH
92
+ Threshold for maximum exon length oddity [default:10000]
93
+ --selected_cds_fraction SELECTED_CDS_FRACTION
94
+ Threshold for selected CDS fraction oddity.
95
+ This is the proportion of coding sequence to that of the transcript.
96
+ Values range from 0.0 to 1.0 [default:0.3]
97
+ --canonical_intron_motifs CANONICAL_INTRON_MOTIFS
98
+ Comma-separated list of canonical intron motifs. [default:'GT-AG,GC-AG,AT-AC']
99
+ ```
100
+
101
+ ## Running AnnoOddities
102
+
103
+ ### Example Command
104
+ To run AnnoOddities, use the command line interface with the required arguments for the genome FASTA file and GFF3 annotation file. For example:
105
+ ```console
106
+ annooddities \
107
+ --genome_fasta input_genome.fna \
108
+ --gff3_file input_genome.gff
109
+ ```
110
+
111
+ You can also specify optional parameters to customise the oddity detection thresholds. For example, to set custom thresholds for minimum exon length and maximum intron length (for plants), you can run:
112
+ ```console
113
+ annooddities \
114
+ --genome_fasta input_genome.fna \
115
+ --gff3_file input_genome.gff \
116
+ --min_exon_length 3 \
117
+ --max_intron_length 10000
118
+ ```
119
+
120
+ Or, if you want to restrict canonical intron motifs to only 'GT-AG', you can run:
121
+ ```console
122
+ annooddities \
123
+ --genome_fasta input_genome.fna \
124
+ --gff3_file input_genome.gff \
125
+ --canonical_intron_motifs 'GT-AG'
126
+ ```
127
+
128
+ ## Output
129
+
130
+ An example output directory structure:
131
+ ```console
132
+ CMD: annooddities --genome_fasta input_genome.fna --gff3_file input_genome.gff
133
+
134
+ DIRECTORY: output_directory
135
+ ├── input_genome.fna
136
+ ├── input_genome.gff
137
+ ├── input_genome.agat.log
138
+ ├── output.agat_standardised.gff
139
+ ├── output.agat_standardised.log
140
+ ├── output.agat_standardised.agat.log
141
+ ├── output.agat_sp_statistics.yaml
142
+ ├── output.agat_sp_statistics.txt
143
+ ├── output.agat_sp_statistics.log
144
+ ├── output.agat_sp_statistics.json
145
+ ├── output.agat_sp_statistics.toml
146
+ ├── input_genome.fna.fai
147
+ ├── output.gffread_table.log
148
+ ├── output.gffread_table.tbl
149
+ ├── output.mikado_tab_stats.log
150
+ ├── output.mikado_tab_stats.tsv
151
+ ├── output.mikado_stats.tsv
152
+ ├── output.mikado_stats.yaml
153
+ ├── output.mikado_summary_stats.tsv
154
+ ├── output.mikado_stats.json
155
+ ├── output.mikado_stats.toml
156
+ ├── oddity_files
157
+ │   ├── output.AnnoOddities.has_inframe_stop.gff
158
+ │   ├── output.AnnoOddities.max_exon_length_gt_10000.gff
159
+ │   ├── output.AnnoOddities.min_exon_length_lte_5.gff
160
+ │   ├── output.AnnoOddities.exon_num_eq_1.gff
161
+ │   ├── output.AnnoOddities.exon_num_gt_1.gff
162
+ │   ├── output.AnnoOddities.is_fragment.gff
163
+ │   ├── output.AnnoOddities.not_has_start_codon.gff
164
+ │   ├── output.AnnoOddities.not_has_stop_codon.gff
165
+ │   ├── output.AnnoOddities.not_is_complete.gff
166
+ │   └── output.AnnoOddities.selected_cds_fraction_lte_0.3.gff
167
+ ├── output.AnnoOddities.combined_statistics.yaml
168
+ ├── output.AnnoOddities.combined_statistics.json
169
+ ├── output.AnnoOddities.combined_statistics.toml
170
+ ├── output.AnnoOddities.all_stats.tsv
171
+ ├── output.AnnoOddities.gff
172
+ └── output.AnnoOddities.oddity_summary.txt
173
+
174
+ ```
175
+
176
+ ### AnnoOddities Summary
177
+ Provides both high-level summaries and more granular diagnostic reports to support manual review or automated pipelines.
178
+
179
+ Below is an example of the `AnnoOddities.oddity_summary.txt` output file:
180
+ ```console
181
+ FILE: output.AnnoOddities.oddity_summary.txt
182
+ AnnoOddities output
183
+ exon_num == 1 4520
184
+ exon_num > 1 12900
185
+ five_utr_length > 10000 0
186
+ five_utr_num > 5 0
187
+ three_utr_length > 10000 0
188
+ three_utr_num > 4 0
189
+ not is_complete 428
190
+ not has_start_codon 174
191
+ not has_stop_codon 280
192
+ is_fragment 26
193
+ has_inframe_stop 1
194
+ max_exon_length > 10000 8
195
+ max_intron_length > 120000 0
196
+ min_exon_length <= 5 308
197
+ 0 < min_intron_length <= 5 0
198
+ selected_cds_fraction <= 0.3 158
199
+ canonical_intron_proportion != 1 0
200
+ only_non_canonical_splicing 0
201
+ suspicious_splicing 0
202
+ ```
203
+
204
+ ### AnnoOddities All Stats
205
+ Detailed per-transcript statistics (as detailed below) computed by AnnoOddities.
206
+
207
+ Below are the columns included in the `AnnoOddities.all_stats.tsv` output file:
208
+ ```console
209
+ FILE: output.AnnoOddities.all_stats.tsv
210
+ 1 transcript_id - transcript identifier
211
+ 2 gene_id - gene identifier
212
+ 3 chromosome - chromosome name or number
213
+ 4 start - start position
214
+ 5 end - end position
215
+ 6 region - genomic region in the format chr:start-end
216
+ 7 strand - strand information
217
+ 8 exon_num - number of exons
218
+ 9 exons - list of exon positions
219
+ 10 exon_lengths - list of exon lengths
220
+ 11 max_exon_length - maximum exon length
221
+ 12 min_exon_length - minimum exon length
222
+ 13 total_exon_length - total length of all exons
223
+ 14 cds_exon_num - number of CDS exons
224
+ 15 cds_exons - list of CDS exon positions
225
+ 16 cds_exon_lengths - list of CDS exon lengths
226
+ 17 max_cds_length - maximum CDS exon length
227
+ 18 min_cds_length - minimum CDS exon length
228
+ 19 total_cds_length - total length of all CDS exons
229
+ 20 cds_cdna_ratio - ratio of CDS length to cDNA length
230
+ 21 intron_num - number of introns
231
+ 22 introns - list of intron positions
232
+ 23 intron_lengths - list of intron lengths
233
+ 24 max_intron_length - maximum intron length
234
+ 25 min_intron_length - minimum intron length
235
+ 26 total_intron_length - total length of all introns
236
+ 27 five_utr_num - number of 5' UTRs
237
+ 28 five_utr_length - total length of 5' UTRs
238
+ 29 three_utr_num - number of 3' UTRs
239
+ 30 three_utr_length - total length of 3' UTRs
240
+ 31 has_start_codon - presence of start codon
241
+ 32 has_stop_codon - presence of stop codon
242
+ 33 is_complete - completeness of the transcript
243
+ 34 is_fragment - whether the transcript is a fragment
244
+ 35 has_inframe_stop - presence of in-frame stop codons
245
+ 36 known_strand_junctions_dict - dictionary of known strand junctions
246
+ 37 known_strand_junctions_str - string representation of known strand junctions
247
+ 38 unknown_strand_junctions_dict - dictionary of unknown strand junctions
248
+ 39 unknown_strand_junctions_str - string representation of unknown strand junctions
249
+ 40 canonical_intron_count - count of canonical introns
250
+ 41 non_canonical_intron_count - count of non-canonical introns
251
+ 42 suspicious_intron_count - count of suspicious introns
252
+ 43 unknown_canonical_intron_count - count of unknown canonical introns
253
+ 44 unknown_non_canonical_intron_count - count of unknown non-canonical introns
254
+ 45 unknown_suspicious_intron_count - count of unknown suspicious introns
255
+ 46 unknown_predicted_strand - predicted strand for unknown introns
256
+ 47 canonical_intron_proportion - proportion of canonical introns
257
+ 48 only_non_canonical_splicing - whether only non-canonical splicing is present
258
+ 49 suspicious_splicing - presence of suspicious splicing
259
+ 50 matched_oddities - matched oddities
260
+ ```
261
+
262
+ ### AnnoOddities Combined Statistics
263
+ Consolidated statistics from AGAT, Mikado, GFFread, and AnnoOddities.
264
+ ```console
265
+ FILE: output.AnnoOddities.combined_statistics.yaml
266
+ FILE: output.AnnoOddities.combined_statistics.json
267
+ FILE: output.AnnoOddities.combined_statistics.toml
268
+ ```
269
+
270
+ ### AnnoOddities Individual Oddity GFFs
271
+ Separate GFF3 files for each detected oddity, facilitating targeted review and analysis.
272
+ ```console
273
+ DIRECTORY: oddity_files
274
+ FILE: output.AnnoOddities.has_inframe_stop.gff
275
+ FILE: output.AnnoOddities.max_exon_length_gt_10000.gff
276
+ FILE: output.AnnoOddities.min_exon_length_lte_5.gff
277
+ FILE: output.AnnoOddities.exon_num_eq_1.gff
278
+ FILE: output.AnnoOddities.exon_num_gt_1.gff
279
+ FILE: output.AnnoOddities.is_fragment.gff
280
+ FILE: output.AnnoOddities.not_has_start_codon.gff
281
+ FILE: output.AnnoOddities.not_has_stop_codon.gff
282
+ FILE: output.AnnoOddities.not_is_complete.gff
283
+ FILE: output.AnnoOddities.selected_cds_fraction_lte_0.3.gff
284
+ ```
285
+
286
+ ### AnnoOddities GFF File
287
+ A GFF3 file containing all transcripts annotated with their respective oddities. The oddities are included in the attributes column for easy identification, appeneded to the 'Note' field to the respective transcript entries.
288
+ ```console
289
+ FILE: output.AnnoOddities.gff
290
+ ```
291
+
292
+
293
+ ## License
294
+
295
+ MIT
@@ -0,0 +1,23 @@
1
+ [project]
2
+ name = "AnnoOddities"
3
+ version = "0.1.0"
4
+ description = "AnnoOddities is a Python utility for detecting, identifying and characterising oddities in genome annotations"
5
+ readme = "README.md"
6
+ authors = [
7
+ { name = "Gemy Kaithakottil", email = "Gemy.Kaithakottil@earlham.ac.uk" },
8
+ { name = "David Swarbreck", email = "David.Swarbreck@earlham.ac.uk" },
9
+ ]
10
+ license = { text = "MIT" }
11
+ requires-python = ">=3.9"
12
+ dependencies = [
13
+ "pyfaidx>=0.5.9.5",
14
+ "pyyaml>=6.0.1",
15
+ "toml>=0.10.2",
16
+ ]
17
+
18
+ [project.scripts]
19
+ annooddities = "annooddities.__main__:main"
20
+
21
+ [build-system]
22
+ requires = ["uv_build>=0.9.16,<0.10.0"]
23
+ build-backend = "uv_build"
File without changes