Metadata-Version: 2.1
Name: gffkit
Version: 0.6.0
Summary: GFF annotation integration and analysis toolkit
Author: caijunhao
License: MIT
Project-URL: Homepage, https://github.com/qunjie-zhang/gffkit
Project-URL: Repository, https://github.com/qunjie-zhang/gffkit
Project-URL: Issues, https://github.com/qunjie-zhang/gffkit/issues
Keywords: GFF3,GTF,genome annotation,bioinformatics,UTR,gene annotation
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Operating System :: OS Independent
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE

# gffkit

`gffkit` is a lightweight toolkit for GFF/GTF annotation integration and analysis.
Version 0.6.0 provides six standalone utilities:

1. `detect-bridge`: detect suspicious merged-gene artifacts caused by bridge transcripts.
2. `complement`: complement/merge annotations, with optional region-swap mode.
3. `add-utr`: reconstruct `five_prime_UTR` and `three_prime_UTR` features from exon/CDS coordinates.
4. `rename-sort`: rename gene/transcript/child IDs with a prefix and sort the final GFF3.
5. `get_longest_transcript`: retain one longest transcript isoform per gene.
6. `stat`: calculate basic gene-annotation statistics for one GFF or a directory of GFF files.

The `integrate` workflow continues to use only the original four integration
utilities. `get_longest_transcript` and `stat` are independent commands and are
not automatically run by `integrate`.

## Installation

```bash
pip install gffkit
```


## Quick start

### Full integration pipeline

```bash
gffkit integrate \
  --annotation-a EviAnn.gff3 \
  --annotation-b ANNEVO.gff3 \
  --outdir gffkit_out \
  --prefix sample \
  -t 8
```

Outputs:

- `gffkit_out/sample.suspicious.tsv`
- `gffkit_out/sample.merged.gff3`
- `gffkit_out/sample.final.withUTR.gff3.pre_rename.gff3`
- `gffkit_out/sample.final.withUTR.gff3`
- `gffkit_out/sample.final.withUTR.gff3.id_map.tsv`

In `integrate`, `--prefix sample` is also used for final ID renaming. Final gene IDs are written like `sample_C01g00001`, transcript IDs like `sample_C01g00001.t1`, and child IDs like `sample_C01g00001.t1.exon1`.

### Step-by-step usage

```bash
# 1. Detect suspicious merged genes in Annotation A
gffkit detect-bridge -i EviAnn.gff3 -o suspicious.tsv -t 8

# 2. Use A as the global reference, but switch to B in suspicious regions
gffkit complement \
  --ref EviAnn.gff3 \
  --add ANNEVO.gff3 \
  --swap_region_tsv suspicious.tsv \
  --swap_region_flank 100 \
  --output merged.gff3 \
  -t 8

# 3. Add UTR features
gffkit add-utr -i merged.gff3 -o final.annotation.withUTR.pre_rename.gff3

# 4. Rename IDs, drop unplaced seqids, and sort the final GFF3
gffkit rename-sort \
  -i final.annotation.withUTR.pre_rename.gff3 \
  -o final.annotation.withUTR.gff3 \
  --prefix sample
```

### Merge three or more annotations

Use repeated `--add` arguments. Files are merged in the order provided.

```bash
gffkit complement \
  --ref EviAnn.gff3 \
  --add ANNEVO.gff3 \
  --add Helixer.gff3 \
  --add PASA.gff3 \
  --output merged.multi.gff3 \
  -t 8
```

### Extract the longest transcript

For each gene, `get_longest_transcript` selects the isoform with the longest
concatenated CDS. If none of a gene's isoforms has CDS features, it uses the
longest concatenated exon length. Ties retain the first isoform encountered in
the input file.

Process one GFF/GFF3 file:

```bash
gffkit get_longest_transcript \
  -i annotation.gff3 \
  -o longest_gff
```

Process all `.gff`/`.gff3` files directly inside a directory:

```bash
gffkit get_longest_transcript \
  -f input_gff_directory \
  -o longest_gff
```

Compressed `.gff.gz` and `.gff3.gz` inputs are also supported by this command.
Output files are named `*.longest.gff` or `*.longest.gff3`. Existing output
files are refused unless `--force` is supplied.

### Calculate annotation statistics

Process one GFF/GFF3 file and write the default `gffstat.txt`:

```bash
gffkit stat -i annotation.gff3
```

Process all `.gff`/`.gff3` files directly inside a directory and select an
output path:

```bash
gffkit stat \
  -f input_gff_directory \
  -o annotation.gffstat.txt
```

The tab-separated output contains species/file name, gene count, average gene
span, average transcript span, average CDS length per gene, average exon count
per gene, average exon length, and average UTR length per gene. Gene and
transcript lengths use their GFF genomic spans (`end - start + 1`); they are not
spliced mature-transcript lengths.

## Command overview

```bash
gffkit --help
gffkit detect-bridge --help
gffkit complement --help
gffkit add-utr --help
gffkit rename-sort --help
gffkit get_longest_transcript --help
gffkit stat --help
gffkit integrate --help
```

## Parallel Processing

Use `-t/--threads` to select the number of worker processes. The option name is
kept for command-line compatibility, but version 0.5.0 and later uses processes for
CPU-bound work so that Python's GIL does not restrict execution to one core.

- `detect-bridge` analyzes genes with a process pool and batches tasks to reduce process communication overhead.
- `complement` parses the reference and supplementary files in parallel, then merges them in the original command-line order.
- `complement` uses a dynamic chromosome interval index to compare each supplementary gene only with nearby overlapping reference genes.
- `integrate` passes the worker count to the detect and complement steps. `add-utr` and `rename-sort` remain single-process.

Example:

```bash
gffkit integrate --annotation-a EviAnn.gff3 --annotation-b ANNEVO.gff3 -t 16
```

During `detect-bridge`, multiple worker processes should be visible in `top` or
`htop`. CPU usage naturally drops during the single-process UTR and rename/sort
steps. More workers also increase memory use; start with `-t 4` or `-t 8` for
large annotations.

## Annotation integration strategy

- Annotation A, for example EviAnn/RNA-seq-supported GFF, is used as the global primary reference.
- Annotation B, for example ANNEVO/deep-learning GFF, is used as the local primary reference only in suspicious merged-gene regions.
- UTR features are reconstructed after merging using an exon-minus-CDS strategy.
- Version 0.4.0 and later run `rename-sort` as the final `integrate` step. The final GFF3 keeps chromosome-mounted records, removes unplaced/scaffold/contig records, sorts features, rewrites `ID`/`Parent`, and writes an ID map next to the output.
- Version 0.5.0 replaces CPU-bound threads with worker processes and adds a dynamic interval index for faster annotation overlap searches.
- Version 0.6.0 adds the independent `get_longest_transcript` and `stat` commands. Neither command is included in `integrate`.
- When multiple tools annotate the same gene locus, the GFF source column is combined with `|`, for example `EviAnn|ANNEVO`.

## Rename and Sort

Run this step independently when you already have a merged GFF3:

```bash
gffkit rename-sort \
  -i merged.withUTR.gff3 \
  -o sample.renamed.sorted.gff3 \
  --prefix sample \
  --digits 5 \
  --keep-old-ids
```

This writes `sample.renamed.sorted.gff3` and `sample.renamed.sorted.gff3.id_map.tsv`.

## Version 0.6.0 changes

- Added `gffkit get_longest_transcript` using the longest-CDS/longest-exon selection logic from `get_longest_transcript.py`.
- Added mutually exclusive `-i/--input` single-file and `-f/--folder` directory input modes for longest-transcript extraction.
- Added `gffkit stat` using the GFF statistics implementation from `gffstat.py`.
- Added mutually exclusive `-i/--input` single-file and `-f/--folder` directory input modes for annotation statistics.
- Kept both new commands independent from the four-step `gffkit integrate` workflow.
- Updated the package version from 0.5.0 to 0.6.0.
- Updated package author and credits to `caijunhao`.

## Maintainer notes

When command-line options or behavior changes, update this `README.md` in the versioned package directory before building and uploading to PyPI.

## License

MIT License.

## Credits

Author: caijunhao
