Metadata-Version: 2.4
Name: telinker
Version: 0.1.0
Summary: Genotype polymorphic transposable elements from VCF, PLINK, array, BED or BAM/CRAM files
License-Expression: MIT
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=1.20
Provides-Extra: reads
Requires-Dist: pysam>=0.19; extra == "reads"
Provides-Extra: test
Requires-Dist: pytest; extra == "test"
Dynamic: license-file

# teLinker

Genotype polymorphic transposable elements in your own data.

```
pip install telinker                 # numpy is the only dependency
pip install 'telinker[reads]'        # + pysam, only for BAM/CRAM input

telinker genotype cohort.vcf.gz -o tes.tsv
```

## Report bugs

https://github.com/jaleesr/teLinker

## Inputs

The input type and genome build are detected automatically. Pass `--build t2t|hg38|hg19`
if the build information is not present in the file header.

| Input | How TEs are called | `method` |
|---|---|---|
| SNP VCF (WGS, or imputed with `DS`) | Imputed from nearby SNPs | `ridge`, `tagN` |
| PLINK `.bed/.bim/.fam` | Imputed | `ridge`, `tagN` |
| 23andMe / AncestryDNA raw file (`.txt` or `.zip`) | Imputed (mostly single tags: arrays are sparse) | `tagN`, `ridge` |
| SV VCF (Sniffles, SVAN, MELT, PAV, …) | Matched to the catalog | `sv` |
| BED of TE insertion calls | Matched; presence only | `bed` |
| Long-read BAM/CRAM on T2T-CHM13 | Read directly from indels in the alignments | `reads` |
| Short-read BAM/CRAM | SNPs piled up, then imputed | `ridge`, `tagN` |

BCF is not read directly; convert it with `bcftools view -Oz`.

### Several samples

**Multi-sample files.** VCF and PLINK inputs give one column per sample. A BAM/CRAM whose
read groups carry several `SM` tags is split by read group into one column per `SM`

**Several files.** These are merged into one table:

```
telinker genotype donor1.bam donor2.bam donor3.bam -o cohort.tsv
telinker genotype cohort.chr*.vcf.gz -o cohort.tsv     # per-chromosome splits
```

- Every input must be on the same build. 
- Sample names are matched across files.
- If two files genotype the same TE in the same sample, the first file wins.
- Single-sample files (a one-sample BAM, a 23andMe file, a BED) are named after the file,
  up to the first dot. So `donor1.sorted.bam` becomes `donor1`.
- If the same sample name comes from more than one file, telinker merges them and warns. That
  is right for a cohort split by chromosome. If the files are different people rename them.

In long-read mode, chrY pseudoautosomal loci are skipped. Their reads are shared with chrX,
so a chrY call would just repeat the chrX genotype.

## Output

One TSV. Each row is a TE, and each sample column is a **TE-presence dosage** (0–2):

```
te_id                   chrom  pos        type  subfamily  method  r2    S1    S2
10_102771350_INS_306_0  10     103646104  INS   AluYa5     tag1    1.00  0     1
10_100722374_INS_226_0  10     .          INS   SVA_F      tag1    0.70  0.92  1.78
```

- **Dosage cells:** dosage always counts copies of the TE, for both INS and DEL loci.
  Imputed calls are continuous. `.` means the TE could not be called in that sample.
- **`r2`:** the panel's held-out accuracy for that TE's model. It is empty for direct calls.
- **`pos`:** the position in your input's build. `.` means the locus does not lift to that build.
- **`--vcf`:** writes the same calls as a VCF with `GT:DS`, ready for plink2, regenie
  or tensorQTL. Its ALT allele is `<TE>` (TE present).


## Layout

```
telinker/         the installed package (numpy only; pysam imported lazily for BAM/CRAM)
  cli.py          argument parsing, input detection, dispatch, summary log
  inputs.py       format sniffing + readers: VCF (SNPs and SVs), PLINK, 23andMe/Ancestry, BED
  impute.py       allele matching and the linear-model prediction / fallback
  match.py        SV and BED calls -> catalog loci
  reads.py        BAM/CRAM: long-read CIGAR genotyper, short-read SNP pileup
  output.py       TSV and VCF writers
  panel.py        loads telinker/panel/ (loci.tsv.gz, models.tsv.gz, PANEL.md)
tests/            pytest suite on a hand-built four-TE panel
```

## Tests

```
pip install '.[test,reads]'
pytest tests
```
