Metadata-Version: 2.4
Name: lncnova
Version: 0.1.2
Summary: LncNova: an integrated RNA-seq pipeline for novel lncRNA discovery and characterization
License-Expression: MIT
Keywords: lncRNA,RNA-seq,novel transcripts,bioinformatics,StringTie
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Intended Audience :: Science/Research
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE.txt
Requires-Dist: numpy
Requires-Dist: pandas
Requires-Dist: scipy
Requires-Dist: openpyxl
Requires-Dist: pysam
Requires-Dist: pydeseq2>=0.4
Provides-Extra: test
Requires-Dist: pytest; extra == "test"
Dynamic: license-file

# LncNova

| | |
|---|---|
| **Package** | [![PyPI](https://img.shields.io/pypi/v/lncnova?label=PyPI)](https://pypi.org/project/lncnova/) [![Downloads](https://img.shields.io/pypi/dm/lncnova)](https://pypi.org/project/lncnova/) [![Wheel](https://img.shields.io/pypi/wheel/lncnova)](https://pypi.org/project/lncnova/#files) [![PyPI status](https://img.shields.io/pypi/status/lncnova)](https://pypi.org/project/lncnova/) |
| **Meta** | [![License: MIT](https://img.shields.io/pypi/l/lncnova)](LICENSE.txt) [![Python versions](https://img.shields.io/pypi/pyversions/lncnova)](https://pypi.org/project/lncnova/) |
| **Author** | AIIMS New Delhi |
<!--
Add these rows once the identifiers exist (replace the <...> parts):
| **CI**        | [![CI](https://github.com/<owner>/<repo>/actions/workflows/<workflow>.yml/badge.svg)](https://github.com/<owner>/<repo>/actions) |
| **Container** | [![Docker Pulls](https://img.shields.io/docker/pulls/<namespace>/lncnova)](https://hub.docker.com/r/<namespace>/lncnova) [![Docker Image Size](https://img.shields.io/docker/image-size/<namespace>/lncnova)](https://hub.docker.com/r/<namespace>/lncnova) |
| **Meta**      | [![DOI](https://zenodo.org/badge/DOI/<doi>.svg)](https://doi.org/<doi>) [![bio.tools](https://img.shields.io/badge/bio.tools-<tool_id>-blue)](https://bio.tools/<tool_id>) [![OpenEBench](https://img.shields.io/badge/OpenEBench-<id>-blue)](https://openebench.bsc.es/tool/<id>) |
| **Author**    | [![ORCID](https://img.shields.io/badge/ORCID-<0000--0000--0000--0000>-a6ce39?logo=orcid&logoColor=white)](https://orcid.org/<0000-0000-0000-0000>) |
-->

**An integrated RNA-seq pipeline for novel lncRNA discovery and characterization.**

LncNova takes raw RNA-seq reads and returns a curated set of **novel lncRNAs**: transcripts that
are absent from the GENCODE reference and from the LNCipedia lncRNA catalogue. It then
characterizes them: how they change between conditions, which genes they sit near or move with,
which miRNAs they may bind, and which diseases their target genes are linked to.

It runs on a **single sample** or on a **case/control cohort**. Everything it needs, the software
and the reference databases, is packaged in one container image, so nothing else has to be
installed.

## How the pipeline works

The pipeline has three phases. Each phase feeds the next, and finished work is cached so an
interrupted run can be resumed.

```
 reads ─► 1 CLEAN ─► 2 ALIGN ─► 3 STRAND ─► 4 ASSEMBLE ─┐   (repeated for every sample)
                                                         ▼
        5 MERGE & CLASSIFY ─► 6 QUANTIFY ─► 7 FILTER ─► 8 CODING CHECK ─► 9 COUNT
                                                                           │  novel lncRNA set
        ┌──────────────────────────────────────────────────────────────────┘
        ▼
 10 DIFFERENTIAL EXPRESSION* ─► 11 NEARBY GENES ─► 12 CO-EXPRESSION & PATHWAYS*
        ─► 13 miRNA BINDING & ceRNA* ─► 14 DISEASE PRECEDENT ─► 15 REPORT
                                                          (* cohort mode only, see below)
```

### Phase 1: process each sample (steps 1 to 4)

1. **Clean the reads.** Adapters are detected and removed, low-quality bases are trimmed, and very
   short reads are dropped. Paired-end and single-end data are both handled.
2. **Align to the genome.** Reads are mapped to human GRCh38 with a splice-aware aligner, using the
   known GENCODE splice junctions as guides, and written as a sorted, indexed alignment file.
3. **Work out the library strandedness.** About 200,000 uniquely aligned reads that fall in
   single-strand genes are checked against the strand of those genes. If at least 80% agree, the
   library is called stranded (and which kind); otherwise it is treated as unstranded. You can
   override this with `--strandedness`.
4. **Assemble transcripts.** Each sample is assembled on its own, guided by the GENCODE annotation
   but free to build transcripts that are not in it. This is where novel transcripts first appear.

### Phase 2: find the novel lncRNAs (steps 5 to 9)

5. **Merge and classify.** The per-sample assemblies are combined into one non-redundant transcript
   set. Every transcript is then compared with GENCODE and given a class code that says how it
   relates to a known gene: identical, new isoform, intergenic, antisense, intronic and so on.
6. **Quantify.** Each sample is re-measured against the merged set, producing a TPM value for every
   transcript in every sample.
7. **Filter the candidates.** A transcript is kept only if all of these hold:
   - it lies in a new place: intergenic (`u`), antisense to a known gene (`x`) or intronic (`i`);
   - it is at least 200 nt long and has at least 2 exons;
   - it does not overlap, on the same strand, a transcript already in LNCipedia 5.2;
   - it is expressed: TPM of at least 0.5 in enough samples. "Enough" is 1 sample for a single
     sample, otherwise the size of the smaller group (never fewer than 2).
8. **Check coding potential.** The candidate sequences are extracted and scored by two independent
   coding-potential predictors. A transcript survives only if **both** call it non-coding, which is
   the strict default (`--consensus any` relaxes it). The survivors are the **novel lncRNA set**.
9. **Count reads per gene.** Known genes are counted against the GENCODE annotation and novel genes
   against the novel set, then joined into one gene-by-sample count table. They are counted
   separately because the merged assembly relabels many known genes, so it cannot serve both.

### Phase 3: characterize them (steps 10 to 15)

The **query set** is the group of lncRNAs examined in this phase. In cohort mode it is the novel
lncRNAs that are significantly changed between case and control. In single mode it is all novel
lncRNAs, limited to the 200 most highly expressed.

10. **Differential expression** *(cohort only)*. Genes are compared between cases and controls with
    a negative-binomial model, optionally adjusting for batch. Results are split into novel
    lncRNAs, known lncRNAs and protein-coding genes. Defaults are adjusted p < 0.05 and
    |log2 fold change| of at least 1.
11. **Nearby genes (cis).** Protein-coding genes within 10 kb of each query lncRNA are listed as
    possible cis targets.
12. **Co-expressed genes and pathways (trans)** *(cohort only, at least 6 samples)*. Each query
    lncRNA is correlated with every expressed protein-coding gene. Group averages are removed
    first, so a correlation cannot arise merely because both genes differ between case and
    control. Genes with |r| of at least 0.6 and adjusted p < 0.05 are kept. The combined target
    genes are then tested for over-representation of GO biological processes and KEGG pathways.
13. **miRNA binding and ceRNA triads.** Each query lncRNA is tested for binding sites of all human
    miRNAs (7-bp seed, interaction energy of -20 kcal/mol or lower). In cohort mode the strongest
    co-expressed mRNAs of each lncRNA are then tested, using their 3′UTRs, against the miRNAs that
    bound a lncRNA. A **ceRNA triad** is a lncRNA and an mRNA that are co-expressed and share a
    predicted miRNA. A positive correlation matches the sponge model, and negative ones are kept
    but flagged.
14. **Disease precedent.** Each cis and top trans target gene is looked up in RNADisease, and the
    diseases linked to it are listed. A novel lncRNA has no disease entry of its own, so this is
    guilt by association.
15. **Report.** Everything is written to one Excel workbook plus plain tables.

### What each mode produces

| | Single mode | Cohort mode |
|---|:--:|:--:|
| Mode is chosen when | one sample, or several without a `condition` column | every sample has `case`/`control`, at least 2 per group |
| Novel lncRNA set (GTF, FASTA, table) and TPM | yes | yes |
| Nearby genes, miRNA binding, disease precedent | yes | yes |
| Differential expression (step 10) | no | yes |
| Co-expression, pathways, ceRNA triads (steps 12, 13) | no | yes, with at least 6 samples |

### Resuming

Finished per-sample steps are skipped when you re-run. If the set of samples changes, the merge,
quantification and everything after them are recomputed so no result mixes old and new samples.

## Install

LncNova is a small Python launcher plus a container image. You need Python 3.9 or later and one of
Docker, Apptainer or Singularity.

```bash
pip install lncnova                                        # the `lncnova` command (launcher only)
```

The PyPI package holds only the launcher. The software and databases live in the container image,
which you build once from the `Dockerfile` in the source repository:

```bash
git clone <this-repository> && cd LncNova
docker build -t lncnova:0.1.0 --build-arg THREADS=16 .    # downloads and bakes in all data (~20 GB image)
lncnova check                                              # verifies every component in the image
```

The build downloads the GENCODE v49 reference, builds the alignment index, and fetches LNCipedia
5.2, miRBase, the coding-potential models, the GO and KEGG gene sets and RNADisease v4.0. It needs a
good connection and roughly an hour. `docker/README.md` in the repository explains running the
image directly, on a cluster, or offline.

## Run

```bash
lncnova template > samples.tsv        # edit the paths
lncnova run -s samples.tsv -o results -t 16
```

`samples.tsv` (TSV or CSV) has one row per sample:

| column | required | meaning |
|--------|----------|---------|
| `sample` | yes | unique sample name |
| `fastq_1` | yes | read 1 (`.fastq.gz`) |
| `fastq_2` | no | read 2 for paired-end data |
| `condition` | no | `case` or `control` (change the labels with `--case` and `--control`) |
| `batch` | no | adjusted for in the differential-expression model |

Your input and output folders are made available to the container automatically.

### Options

| Option | Default | Meaning |
|--------|---------|---------|
| `-t`, `--threads` | 8 | threads for alignment, assembly and miRNA prediction |
| `--strandedness` | `auto` | detected from the alignments; or `unstranded`, `rf`, `fr` |
| `--classes` | `u,x,i` | class codes counted as novel |
| `--min-length`, `--min-exons` | 200, 2 | structural filters (`--min-exons 1` keeps single-exon transcripts) |
| `--min-tpm`, `--min-samples` | 0.5, automatic | expression filter |
| `--coding-tools`, `--consensus` | both predictors, `all` | non-coding only if every predictor agrees; `any` is permissive |
| `--keep-lncipedia` | off | keep transcripts that already exist in LNCipedia |
| `--padj`, `--lfc` | 0.05, 1 | differential-expression thresholds |
| `--mirna-max-energy` | -20 | miRNA interaction-energy cutoff (kcal/mol), more negative is stricter |
| `--max-mrna-per-lncrna` | 50 | co-expressed mRNAs per lncRNA tested for shared miRNAs |
| `--no-mirna`, `--no-disease` | | skip those layers |

Run `lncnova run --help` for the full list.

## Output

```
results/
├── lncnova_report.xlsx        summary and every table
├── 06_novel_lncrna/           novel_lncrna.gtf, novel_lncrna.fa, novel_lncrna_transcripts.tsv
├── 05_quant/                  transcript_tpm.csv, gene_counts.csv
├── 07_de/                     differential-expression tables (cohort)
├── 08_targets/                cis_targets.csv, trans_targets.csv (cohort)
├── 09_mirna/                  miRNA binding sites and ceRNA triads
├── 10_disease_precedent.csv
└── 01_trim … 04_merge/        intermediate files and logs of each step
```

## Limits

- Human GRCh38 and GENCODE v49 only. Paired-end or single-end reads.
- The aligner uses a plain genome index plus the known splice junctions at run time, because the
  index that embeds the junctions needs far more memory than most machines have.
- Differential expression is a Python implementation of the negative-binomial approach, close to but
  not identical to the R original.
- Co-expression and ceRNA results are hypothesis-generating and are only convincing with roughly 10
  or more samples. The miRNA and disease layers are computational associations, not evidence for
  a specific lncRNA. Validate candidates experimentally.
- Tested end to end on subsampled data (up to 6 samples of 2 million read pairs each). Runtime and
  results on full-depth cohorts have not been benchmarked.

## Development

```bash
pip install -e ".[test]" && pytest
python -m build            # wheel and sdist in dist/
```

## License

LncNova's code is MIT-licensed (see `LICENSE.txt`). The container image also bundles third-party
software and reference data that keep their own licenses and terms of use; `LICENSE.txt` lists
them. Review those terms before redistributing the image, especially commercially.
