nanomd 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.
- nanomd-0.1.0/PKG-INFO +144 -0
- nanomd-0.1.0/README.md +128 -0
- nanomd-0.1.0/nanomd/__init__.py +0 -0
- nanomd-0.1.0/nanomd/main.py +24 -0
- nanomd-0.1.0/nanomd/modules/__init__.py +0 -0
- nanomd-0.1.0/nanomd/modules/detectMod.py +58 -0
- nanomd-0.1.0/nanomd/modules/gene.py +39 -0
- nanomd-0.1.0/nanomd/modules/isoform.py +39 -0
- nanomd-0.1.0/nanomd/modules/isoformAS.py +22 -0
- nanomd-0.1.0/nanomd/modules/nascentRNA.py +22 -0
- nanomd-0.1.0/nanomd/scripts/gene.R +0 -0
- nanomd-0.1.0/nanomd/scripts/isoform.R +0 -0
- nanomd-0.1.0/nanomd/scripts/m6a.sh +23 -0
- nanomd-0.1.0/nanomd/scripts/metaplot.R +133 -0
- nanomd-0.1.0/nanomd/scripts/newRNA.R +65 -0
- nanomd-0.1.0/nanomd/scripts/selectM6A.R +487 -0
- nanomd-0.1.0/nanomd/static/env.yaml +5 -0
- nanomd-0.1.0/nanomd/utils/__init__.py +0 -0
- nanomd-0.1.0/nanomd/utils/abs_position.py +102 -0
- nanomd-0.1.0/nanomd/utils/basetools.py +12 -0
- nanomd-0.1.0/nanomd/utils/map.py +41 -0
- nanomd-0.1.0/nanomd/utils/modifications.py +168 -0
- nanomd-0.1.0/nanomd/utils/modmutil.py +180 -0
- nanomd-0.1.0/nanomd/utils/modtools.py +33 -0
- nanomd-0.1.0/nanomd/utils/oldmodifications.py +212 -0
- nanomd-0.1.0/nanomd/utils/split.py +48 -0
- nanomd-0.1.0/pyproject.toml +18 -0
nanomd-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: nanomd
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary:
|
|
5
|
+
Author: DeYing Zhang
|
|
6
|
+
Author-email: legendzdy@dingtalk.com
|
|
7
|
+
Requires-Python: >=3.10,<4.0
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
13
|
+
Requires-Dist: pysam (>=0.22.1,<0.23.0)
|
|
14
|
+
Requires-Dist: typer (>=0.15.1,<0.16.0)
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
|
|
17
|
+
# nanoMD
|
|
18
|
+
|
|
19
|
+
nanoMD(Nanopore direct RNA sequencing Multi-dimensional analysis) was developed to synchronously analyze the changes in m6A sites, genes, and isoforms, and new mRNA.
|
|
20
|
+
|
|
21
|
+
# Table of Contents
|
|
22
|
+
<!-- TOC -->
|
|
23
|
+
|
|
24
|
+
- [1. nanoMD](#1-nanomd)
|
|
25
|
+
- [2. Table of Contents](#2-table-of-contents)
|
|
26
|
+
- [3. Overview](#3-overview)
|
|
27
|
+
- [4. Requirements](#4-requirements)
|
|
28
|
+
- [5. nanoMD modules](#5-nanomd-modules)
|
|
29
|
+
- [5.1. nanomd gene](#51-nanomd-gene)
|
|
30
|
+
- [5.2. Usage](#52-usage)
|
|
31
|
+
- [5.3. nanomd isoform](#53-nanomd-isoform)
|
|
32
|
+
- [5.4. Usage](#54-usage)
|
|
33
|
+
- [5.5. nanomd m6A sites](#55-nanomd-m6a-sites)
|
|
34
|
+
- [5.6. Usage](#56-usage)
|
|
35
|
+
- [5.7. nanomd new mRNA](#57-nanomd-new-mrna)
|
|
36
|
+
- [5.8. Usage](#58-usage)
|
|
37
|
+
- [6. Scripts](#6-scripts)
|
|
38
|
+
- [6.1. detect5EU.py](#61-detect5eupy)
|
|
39
|
+
- [6.2. Usage](#62-usage)
|
|
40
|
+
- [7. Docker](#7-docker)
|
|
41
|
+
- [8. Conda Environment](#8-conda-environment)
|
|
42
|
+
- [9. Cite nanoMD](#9-cite-nanomd)
|
|
43
|
+
|
|
44
|
+
<!-- /TOC -->
|
|
45
|
+
|
|
46
|
+
# Overview
|
|
47
|
+
|
|
48
|
+
nanoMD is designed to work with the output of the ONT direct RNA sequencing platform and can be used to identify new m6A sites, genes, and isoforms, as well as detect and quantify new mRNA.
|
|
49
|
+
|
|
50
|
+
It is recommended to use the docker or conda environment to run the pipeline.
|
|
51
|
+
|
|
52
|
+
# Requirements
|
|
53
|
+
|
|
54
|
+
1. Python 3.6+
|
|
55
|
+
2. Python modules:
|
|
56
|
+
- pandas
|
|
57
|
+
- numpy
|
|
58
|
+
- scipy
|
|
59
|
+
- sklearn
|
|
60
|
+
- matplotlib
|
|
61
|
+
- seaborn
|
|
62
|
+
- pysam
|
|
63
|
+
3. minimap2
|
|
64
|
+
4. samtools
|
|
65
|
+
5. bedtools
|
|
66
|
+
6. flair
|
|
67
|
+
7. tombo
|
|
68
|
+
8. mines
|
|
69
|
+
9. metaPlotR
|
|
70
|
+
|
|
71
|
+
# nanoMD modules
|
|
72
|
+
|
|
73
|
+
nanomd.py is the main module of nanoMD, which includes the following sub-modules:
|
|
74
|
+
- gene
|
|
75
|
+
- isoform
|
|
76
|
+
- detectm6A
|
|
77
|
+
- detectnewmRNA
|
|
78
|
+
|
|
79
|
+
## nanomd gene
|
|
80
|
+
|
|
81
|
+
## test
|
|
82
|
+
```bash
|
|
83
|
+
nohup python ./modifications.py -i ./treat.pass.fq.gz -s Treat.sam -b genes.bed -o test.treat.mod.bed > test.treat.mod.log 2>&1 &
|
|
84
|
+
nohup nanomd detectMod -i ./treat.pass.fq.gz -s Treat.sam -b genes.bed -o test.treat.mod.detectMod.bed > test.treat.mod.detectMod.log 2>&1 &
|
|
85
|
+
nohup nanomd detectMod -i ../input/LPS3/pass.fq.gz -s ../01_map_gene/LPS3_gene.sam -b ../reference/genes/genes.bed -o ./LPS3_modfi.bed &
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Usage
|
|
89
|
+
|
|
90
|
+
`nanomd.py gene -i sample -f genome.cdna.fa -e 0.005 -o gene`
|
|
91
|
+
|
|
92
|
+
## nanomd isoform
|
|
93
|
+
|
|
94
|
+
## Usage
|
|
95
|
+
|
|
96
|
+
`nanomd.py isoform -i sample -f genome.cdna.fa -e 0.005 -o isoform`
|
|
97
|
+
|
|
98
|
+
## nanomd m6A sites
|
|
99
|
+
|
|
100
|
+
## Usage
|
|
101
|
+
|
|
102
|
+
`nanomd.py detectm6A -i sample -f genome.cdna.fa -e 0.005 -o m6A`
|
|
103
|
+
|
|
104
|
+
## nanomd new mRNA
|
|
105
|
+
|
|
106
|
+
## Usage
|
|
107
|
+
|
|
108
|
+
`nanomd.py detectnewmRNA -i sample -f genome.cdna.fa -e 0.005 -o newmRNA`
|
|
109
|
+
|
|
110
|
+
# Scripts
|
|
111
|
+
|
|
112
|
+
We provide a set of standalone scripts for 5EU detection and quantification.
|
|
113
|
+
|
|
114
|
+
## detect5EU.py
|
|
115
|
+
|
|
116
|
+
This script detects 5' untranslated regions (5EU) from the ONT direct RNA sequencing data.
|
|
117
|
+
|
|
118
|
+
## Usage
|
|
119
|
+
|
|
120
|
+
`python detect5EU.py -i sample.fastq -o 5EU.bed`
|
|
121
|
+
|
|
122
|
+
# Docker
|
|
123
|
+
|
|
124
|
+
If the user has docker installed, the following command can be used to run the pipeline in a docker container:
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
docker run -v /path/to/data:/data -it nanomd/nanomd:latest /bin/bash
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
# Conda Environment
|
|
131
|
+
|
|
132
|
+
If the user has conda installed, the following command can be used to create a conda environment for nanoMD:
|
|
133
|
+
|
|
134
|
+
1. Install conda
|
|
135
|
+
2. Create a new conda environment: `conda create -n nanomd python=3.6`
|
|
136
|
+
3. Activate the environment: `conda activate nanomd`
|
|
137
|
+
4. Install the required packages: `conda install -c bioconda minimap2 samtools bedtools flair tombo mines`
|
|
138
|
+
5. Install the required python packages: `pip install pandas numpy scipy sklearn matplotlib seaborn pysam`
|
|
139
|
+
6. Clone the nanoMD repository: `git clone https://github.com/epibiotek/nanomd.git`
|
|
140
|
+
7. Run the pipeline: `python nanomd/nanomd.py gene -i sample -f genome.cdna.fa -e 0.005 -o gene`
|
|
141
|
+
|
|
142
|
+
# Cite nanoMD
|
|
143
|
+
|
|
144
|
+
If you use nanoMD in your research, please cite the following paper:
|
nanomd-0.1.0/README.md
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# nanoMD
|
|
2
|
+
|
|
3
|
+
nanoMD(Nanopore direct RNA sequencing Multi-dimensional analysis) was developed to synchronously analyze the changes in m6A sites, genes, and isoforms, and new mRNA.
|
|
4
|
+
|
|
5
|
+
# Table of Contents
|
|
6
|
+
<!-- TOC -->
|
|
7
|
+
|
|
8
|
+
- [1. nanoMD](#1-nanomd)
|
|
9
|
+
- [2. Table of Contents](#2-table-of-contents)
|
|
10
|
+
- [3. Overview](#3-overview)
|
|
11
|
+
- [4. Requirements](#4-requirements)
|
|
12
|
+
- [5. nanoMD modules](#5-nanomd-modules)
|
|
13
|
+
- [5.1. nanomd gene](#51-nanomd-gene)
|
|
14
|
+
- [5.2. Usage](#52-usage)
|
|
15
|
+
- [5.3. nanomd isoform](#53-nanomd-isoform)
|
|
16
|
+
- [5.4. Usage](#54-usage)
|
|
17
|
+
- [5.5. nanomd m6A sites](#55-nanomd-m6a-sites)
|
|
18
|
+
- [5.6. Usage](#56-usage)
|
|
19
|
+
- [5.7. nanomd new mRNA](#57-nanomd-new-mrna)
|
|
20
|
+
- [5.8. Usage](#58-usage)
|
|
21
|
+
- [6. Scripts](#6-scripts)
|
|
22
|
+
- [6.1. detect5EU.py](#61-detect5eupy)
|
|
23
|
+
- [6.2. Usage](#62-usage)
|
|
24
|
+
- [7. Docker](#7-docker)
|
|
25
|
+
- [8. Conda Environment](#8-conda-environment)
|
|
26
|
+
- [9. Cite nanoMD](#9-cite-nanomd)
|
|
27
|
+
|
|
28
|
+
<!-- /TOC -->
|
|
29
|
+
|
|
30
|
+
# Overview
|
|
31
|
+
|
|
32
|
+
nanoMD is designed to work with the output of the ONT direct RNA sequencing platform and can be used to identify new m6A sites, genes, and isoforms, as well as detect and quantify new mRNA.
|
|
33
|
+
|
|
34
|
+
It is recommended to use the docker or conda environment to run the pipeline.
|
|
35
|
+
|
|
36
|
+
# Requirements
|
|
37
|
+
|
|
38
|
+
1. Python 3.6+
|
|
39
|
+
2. Python modules:
|
|
40
|
+
- pandas
|
|
41
|
+
- numpy
|
|
42
|
+
- scipy
|
|
43
|
+
- sklearn
|
|
44
|
+
- matplotlib
|
|
45
|
+
- seaborn
|
|
46
|
+
- pysam
|
|
47
|
+
3. minimap2
|
|
48
|
+
4. samtools
|
|
49
|
+
5. bedtools
|
|
50
|
+
6. flair
|
|
51
|
+
7. tombo
|
|
52
|
+
8. mines
|
|
53
|
+
9. metaPlotR
|
|
54
|
+
|
|
55
|
+
# nanoMD modules
|
|
56
|
+
|
|
57
|
+
nanomd.py is the main module of nanoMD, which includes the following sub-modules:
|
|
58
|
+
- gene
|
|
59
|
+
- isoform
|
|
60
|
+
- detectm6A
|
|
61
|
+
- detectnewmRNA
|
|
62
|
+
|
|
63
|
+
## nanomd gene
|
|
64
|
+
|
|
65
|
+
## test
|
|
66
|
+
```bash
|
|
67
|
+
nohup python ./modifications.py -i ./treat.pass.fq.gz -s Treat.sam -b genes.bed -o test.treat.mod.bed > test.treat.mod.log 2>&1 &
|
|
68
|
+
nohup nanomd detectMod -i ./treat.pass.fq.gz -s Treat.sam -b genes.bed -o test.treat.mod.detectMod.bed > test.treat.mod.detectMod.log 2>&1 &
|
|
69
|
+
nohup nanomd detectMod -i ../input/LPS3/pass.fq.gz -s ../01_map_gene/LPS3_gene.sam -b ../reference/genes/genes.bed -o ./LPS3_modfi.bed &
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Usage
|
|
73
|
+
|
|
74
|
+
`nanomd.py gene -i sample -f genome.cdna.fa -e 0.005 -o gene`
|
|
75
|
+
|
|
76
|
+
## nanomd isoform
|
|
77
|
+
|
|
78
|
+
## Usage
|
|
79
|
+
|
|
80
|
+
`nanomd.py isoform -i sample -f genome.cdna.fa -e 0.005 -o isoform`
|
|
81
|
+
|
|
82
|
+
## nanomd m6A sites
|
|
83
|
+
|
|
84
|
+
## Usage
|
|
85
|
+
|
|
86
|
+
`nanomd.py detectm6A -i sample -f genome.cdna.fa -e 0.005 -o m6A`
|
|
87
|
+
|
|
88
|
+
## nanomd new mRNA
|
|
89
|
+
|
|
90
|
+
## Usage
|
|
91
|
+
|
|
92
|
+
`nanomd.py detectnewmRNA -i sample -f genome.cdna.fa -e 0.005 -o newmRNA`
|
|
93
|
+
|
|
94
|
+
# Scripts
|
|
95
|
+
|
|
96
|
+
We provide a set of standalone scripts for 5EU detection and quantification.
|
|
97
|
+
|
|
98
|
+
## detect5EU.py
|
|
99
|
+
|
|
100
|
+
This script detects 5' untranslated regions (5EU) from the ONT direct RNA sequencing data.
|
|
101
|
+
|
|
102
|
+
## Usage
|
|
103
|
+
|
|
104
|
+
`python detect5EU.py -i sample.fastq -o 5EU.bed`
|
|
105
|
+
|
|
106
|
+
# Docker
|
|
107
|
+
|
|
108
|
+
If the user has docker installed, the following command can be used to run the pipeline in a docker container:
|
|
109
|
+
|
|
110
|
+
```
|
|
111
|
+
docker run -v /path/to/data:/data -it nanomd/nanomd:latest /bin/bash
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
# Conda Environment
|
|
115
|
+
|
|
116
|
+
If the user has conda installed, the following command can be used to create a conda environment for nanoMD:
|
|
117
|
+
|
|
118
|
+
1. Install conda
|
|
119
|
+
2. Create a new conda environment: `conda create -n nanomd python=3.6`
|
|
120
|
+
3. Activate the environment: `conda activate nanomd`
|
|
121
|
+
4. Install the required packages: `conda install -c bioconda minimap2 samtools bedtools flair tombo mines`
|
|
122
|
+
5. Install the required python packages: `pip install pandas numpy scipy sklearn matplotlib seaborn pysam`
|
|
123
|
+
6. Clone the nanoMD repository: `git clone https://github.com/epibiotek/nanomd.git`
|
|
124
|
+
7. Run the pipeline: `python nanomd/nanomd.py gene -i sample -f genome.cdna.fa -e 0.005 -o gene`
|
|
125
|
+
|
|
126
|
+
# Cite nanoMD
|
|
127
|
+
|
|
128
|
+
If you use nanoMD in your research, please cite the following paper:
|
|
File without changes
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import typer
|
|
2
|
+
from .modules.gene import gene
|
|
3
|
+
from .modules.isoform import isoform
|
|
4
|
+
from .modules.detectMod import detectMod
|
|
5
|
+
from .modules.isoformAS import isoformAS
|
|
6
|
+
from .modules.nascentRNA import nascentRNA
|
|
7
|
+
|
|
8
|
+
app = typer.Typer(add_completion=False)
|
|
9
|
+
|
|
10
|
+
@app.callback()
|
|
11
|
+
def callback():
|
|
12
|
+
"""
|
|
13
|
+
nanoMD(Nanopore direct RNA sequencing Multi-dimensional analysis) was developed to synchronously analyze the changes in m6A, m5C, psi, AtoI modification sites, genes, isoforms, alternative splicing events, and nascent RNA in direct RNA sequencing data.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
app.command(name="gene")(gene)
|
|
17
|
+
app.command(name="isoform")(isoform)
|
|
18
|
+
app.command(name="isoformAS")(isoformAS)
|
|
19
|
+
app.command(name="detectMod")(detectMod)
|
|
20
|
+
app.command(name="nascentRNA")(nascentRNA)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
if __name__ == "__main__":
|
|
24
|
+
app()
|
|
File without changes
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import time
|
|
2
|
+
import typer
|
|
3
|
+
from typing_extensions import Annotated
|
|
4
|
+
from rich.progress import Progress, SpinnerColumn, TextColumn
|
|
5
|
+
from ..utils.modtools import split_mod
|
|
6
|
+
from ..utils.basetools import check_path_exists
|
|
7
|
+
from ..utils.abs_position import gene_feature_distance_calculator
|
|
8
|
+
from ..utils.modifications import form_reads_get_modifications
|
|
9
|
+
|
|
10
|
+
app = typer.Typer()
|
|
11
|
+
|
|
12
|
+
@app.command()
|
|
13
|
+
def detectMod(
|
|
14
|
+
input: Annotated[str, typer.Option("--input", "-i", help="Input fastq files.")],
|
|
15
|
+
sam: Annotated[str, typer.Option("--sam", "-s", help="mapping sam/bam file.")],
|
|
16
|
+
bed: Annotated[str, typer.Option("--bed", "-b", help="bed file for transcripts sites.")],
|
|
17
|
+
regions: Annotated[str, typer.Option("--regions", "-r", help="regions file for gene feature distance calculation.")],
|
|
18
|
+
output: Annotated[str, typer.Option("--output", "-o", help="Output file path.")]=".",
|
|
19
|
+
prefix: Annotated[str, typer.Option("--prefix", "-p", help="Prefix for output files.")]="prefix",
|
|
20
|
+
pvalue: Annotated[float, typer.Option("--pvalue", help="pvalue cutoff for modification sites.")]=0.98,
|
|
21
|
+
):
|
|
22
|
+
"""
|
|
23
|
+
detect modification sites in input fastq files.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
with Progress(
|
|
27
|
+
SpinnerColumn(),
|
|
28
|
+
TextColumn("[progress.description]{task.description}"),
|
|
29
|
+
transient=True,
|
|
30
|
+
) as progress:
|
|
31
|
+
progress.add_task(description="Detecting modification start...", total=None)
|
|
32
|
+
start=time.time()
|
|
33
|
+
|
|
34
|
+
output_file=f"{output}/{prefix}.bed"
|
|
35
|
+
progress.add_task(description="Getting modification from fq files...", total=None)
|
|
36
|
+
if not check_path_exists(output_file):
|
|
37
|
+
mod = form_reads_get_modifications(input, sam, bed, output_file, pvalue)
|
|
38
|
+
mod.get_mod_position_with_sam()
|
|
39
|
+
progress.add_task(description=f"Getting modification from fq files Done", total=None)
|
|
40
|
+
|
|
41
|
+
progress.add_task(description="Splitting modification sites...", total=None)
|
|
42
|
+
if not check_path_exists(f"{output}/{prefix}_m6A.bed"):
|
|
43
|
+
split_mod(output_file, prefix)
|
|
44
|
+
progress.add_task(description="Splitting modification sites Done", total=None)
|
|
45
|
+
|
|
46
|
+
progress.add_task(description="Calculating absolute distance...", total=None)
|
|
47
|
+
bed_file_list = [f"{output}/{prefix}_m6A.bed", f"{output}/{prefix}_m5C.bed", f"{output}/{prefix}_psi.bed", f"{output}/{prefix}_AtoI.bed"]
|
|
48
|
+
for bed_file in bed_file_list:
|
|
49
|
+
gfc_output = bed_file.replace(".bed", "_abs_dist.txt")
|
|
50
|
+
if not check_path_exists(gfc_output):
|
|
51
|
+
gfc = gene_feature_distance_calculator(bed_file, regions, gfc_output)
|
|
52
|
+
gfc.process_bed_file()
|
|
53
|
+
progress.add_task(description="Calculating absolute distance Done", total=None)
|
|
54
|
+
|
|
55
|
+
end=time.time()
|
|
56
|
+
time_cost=f"{(end - start) // 3600}h{((end - start) % 3600) // 60}m{(end - start) % 60:.2f}s"
|
|
57
|
+
print(f"Detecting modification sites Done, time cost: {time_cost}")
|
|
58
|
+
progress.add_task(description=f"Detecting modification sites Done, time cost: {time_cost}", total=None)
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import time
|
|
2
|
+
import typer
|
|
3
|
+
from typing_extensions import Annotated
|
|
4
|
+
from rich.progress import Progress, SpinnerColumn, TextColumn
|
|
5
|
+
from ..utils.map import minimap2map
|
|
6
|
+
|
|
7
|
+
app = typer.Typer()
|
|
8
|
+
|
|
9
|
+
@app.command()
|
|
10
|
+
def gene(
|
|
11
|
+
input: Annotated[str, typer.Option("--input", "-i", help="Input fastq files.")],
|
|
12
|
+
reference: Annotated[str, typer.Option("--reference", "-r", help="reference genome path.")],
|
|
13
|
+
output: Annotated[str, typer.Option("--output", "-o", help="output for output sam/bam files.")],
|
|
14
|
+
tool: Annotated[str, typer.Option("--tool", help="minimap2.")]="minimap2",
|
|
15
|
+
parms: Annotated[str, typer.Option("--parms", help="minimap2 parameters for mapping.")]="--secondary=no --cs -a",
|
|
16
|
+
threads: Annotated[int, typer.Option("--threads", "-t", help="Number of threads.")]=4,
|
|
17
|
+
):
|
|
18
|
+
"""
|
|
19
|
+
Mapping of nanopore reads to a reference genome.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
with Progress(
|
|
23
|
+
SpinnerColumn(),
|
|
24
|
+
TextColumn("[progress.description]{task.description}"),
|
|
25
|
+
transient=True,
|
|
26
|
+
) as progress:
|
|
27
|
+
try:
|
|
28
|
+
progress.add_task(description="map reference...", total=None)
|
|
29
|
+
start=time.time()
|
|
30
|
+
minimap2map(input, reference, output, tool, parms, threads)
|
|
31
|
+
end=time.time()
|
|
32
|
+
time_cost=f"{(end - start) // 3600}h{((end - start) % 3600) // 60}m{(end - start) % 60:.2f}s"
|
|
33
|
+
print(f"map reference Done, time cost: {time_cost}")
|
|
34
|
+
progress.add_task(description=f"map reference Done, time cost: {time_cost}", total=None)
|
|
35
|
+
except Exception as e:
|
|
36
|
+
print(f"Error: {e}")
|
|
37
|
+
progress.add_task(description="map reference Failed", total=None)
|
|
38
|
+
exit(1)
|
|
39
|
+
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import time
|
|
2
|
+
import typer
|
|
3
|
+
from typing_extensions import Annotated
|
|
4
|
+
from rich.progress import Progress, SpinnerColumn, TextColumn
|
|
5
|
+
from ..utils.map import minimap2map
|
|
6
|
+
|
|
7
|
+
app = typer.Typer()
|
|
8
|
+
|
|
9
|
+
@app.command()
|
|
10
|
+
def isoform(
|
|
11
|
+
input: Annotated[str, typer.Option("--input", "-i", help="Input fastq files.")],
|
|
12
|
+
reference: Annotated[str, typer.Option("--reference", "-r", help="reference transcripts path.")],
|
|
13
|
+
output: Annotated[str, typer.Option("--output", "-o", help="output for output sam/bam files.")],
|
|
14
|
+
tool: Annotated[str, typer.Option("--tool", help="minimap2.")]="minimap2",
|
|
15
|
+
parms: Annotated[str, typer.Option("--parms", help="minimap2 parameters for mapping.")]="--secondary=no --cs -a",
|
|
16
|
+
threads: Annotated[int, typer.Option("--threads", "-t", help="Number of threads.")]=4,
|
|
17
|
+
):
|
|
18
|
+
"""
|
|
19
|
+
Mapping of nanopore reads to a reference transcripts.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
with Progress(
|
|
23
|
+
SpinnerColumn(),
|
|
24
|
+
TextColumn("[progress.description]{task.description}"),
|
|
25
|
+
transient=True,
|
|
26
|
+
) as progress:
|
|
27
|
+
try:
|
|
28
|
+
progress.add_task(description="map reference...", total=None)
|
|
29
|
+
start=time.time()
|
|
30
|
+
minimap2map(input, reference, output, tool, parms, threads)
|
|
31
|
+
end=time.time()
|
|
32
|
+
time_cost=f"{(end - start) // 3600}h{((end - start) % 3600) // 60}m{(end - start) % 60:.2f}s"
|
|
33
|
+
print(f"map reference Done, time cost: {time_cost}")
|
|
34
|
+
progress.add_task(description=f"map reference Done, time cost: {time_cost}", total=None)
|
|
35
|
+
except Exception as e:
|
|
36
|
+
print(f"Error: {e}")
|
|
37
|
+
progress.add_task(description="map reference Failed", total=None)
|
|
38
|
+
exit(1)
|
|
39
|
+
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import typer
|
|
2
|
+
import subprocess
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from rich.progress import track
|
|
5
|
+
from typing_extensions import Annotated
|
|
6
|
+
from ..utils.map import minimap2map
|
|
7
|
+
|
|
8
|
+
app = typer.Typer()
|
|
9
|
+
|
|
10
|
+
@app.command()
|
|
11
|
+
def isoformAS(
|
|
12
|
+
input: Annotated[str, typer.Option("--input", "-i", help="Input fastq files.")],
|
|
13
|
+
reference: Annotated[str, typer.Option("--reference", "-r", help="reference genome path.")],
|
|
14
|
+
prefix: Annotated[str, typer.Option("--prefix", "-p", help="Prefix for output files.")],
|
|
15
|
+
tool: Annotated[str, typer.Option("--tool", help="minimap2.")]="minimap2",
|
|
16
|
+
parms: Annotated[str, typer.Option("--parms", help="minimap2 parameters for mapping.")]="--secondary=no --cs -a",
|
|
17
|
+
threads: Annotated[int, typer.Option(help="Number of threads.")]=4,
|
|
18
|
+
):
|
|
19
|
+
"""
|
|
20
|
+
alternative splicing analysis.
|
|
21
|
+
"""
|
|
22
|
+
minimap2map(input, reference, prefix, tool, parms, threads)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import typer
|
|
2
|
+
import subprocess
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from rich.progress import track
|
|
5
|
+
from typing_extensions import Annotated
|
|
6
|
+
from ..utils.map import minimap2map
|
|
7
|
+
|
|
8
|
+
app = typer.Typer()
|
|
9
|
+
|
|
10
|
+
@app.command()
|
|
11
|
+
def nascentRNA(
|
|
12
|
+
input: Annotated[str, typer.Option("--input", "-i", help="Input fastq files.")],
|
|
13
|
+
reference: Annotated[str, typer.Option("--reference", "-r", help="reference genome path.")],
|
|
14
|
+
prefix: Annotated[str, typer.Option("--prefix", "-p", help="Prefix for output files.")],
|
|
15
|
+
tool: Annotated[str, typer.Option("--tool", help="minimap2.")]="minimap2",
|
|
16
|
+
parms: Annotated[str, typer.Option("--parms", help="minimap2 parameters for mapping.")]="--secondary=no --cs -a",
|
|
17
|
+
threads: Annotated[int, typer.Option(help="Number of threads.")]=4,
|
|
18
|
+
):
|
|
19
|
+
"""
|
|
20
|
+
Detect nascent RNA of nanopore reads.
|
|
21
|
+
"""
|
|
22
|
+
minimap2map(input, reference, prefix, tool, parms, threads)
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
|
|
2
|
+
conda activate mines
|
|
3
|
+
|
|
4
|
+
cat m6A.bed|sort -k1,1 -k2,2n > m6a.sorted.bed
|
|
5
|
+
|
|
6
|
+
perl ~/soft/metaPlotR/annotate_bed_file.pl --bed ./m6a.sorted.bed --bed2 ~/Refernce/human_ensembl_genome/91/hg38_annot.sorted.bed > annot_m6a.sorted.bed
|
|
7
|
+
|
|
8
|
+
perl ~/soft/metaPlotR/rel_and_abs_dist_calc.pl --bed ./annot_m6a.sorted.bed --regions ~/Refernce/human_ensembl_genome/91/region_sizes.txt > m6a.dist.measures.txt
|
|
9
|
+
|
|
10
|
+
cat Treat.mod.bed | awk -F "\t" '$4 > 0.95 {file="Treat/" $7 ".bed"; print $0 > file}'
|
|
11
|
+
|
|
12
|
+
cat Control.mod.bed | awk -F "\t" '$4 > 0.95 {file="Control/" $7 ".bed"; print $0 > file}'
|
|
13
|
+
|
|
14
|
+
cat Treat.mod.bed | awk -F "\t" '$4 >= 0.9 {file="treat_" $7 ".bed"; print $0 > file}'
|
|
15
|
+
|
|
16
|
+
cat Control.mod.bed | awk -F "\t" '$4 >= 0.9 {file="control_" $7 ".bed"; print $0 > file}'
|
|
17
|
+
|
|
18
|
+
awk '!seen[$4]++ {first[$4]=$0} {count[$4]++} END {for (key in count) print first[key], count[key]}' treat_m6A.bed > treat_m6A.uniq.bed
|
|
19
|
+
|
|
20
|
+
nohup python ./split.py -i Treat.mod.bed -p treat -v 0.6 &
|
|
21
|
+
nohup python ./split.py -i WT.mod.bed -p wt -v 0.6 &
|
|
22
|
+
|
|
23
|
+
R CMD INSTALL legendBaseModel_0.0.6.tar.gz
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
#!/opt/conda/bin/Rscript
|
|
2
|
+
options(repos=structure(c(CRAN="https://mirrors.tuna.tsinghua.edu.cn/CRAN/")))
|
|
3
|
+
if (!requireNamespace("optparse", quietly = TRUE))
|
|
4
|
+
install.packages("optparse")
|
|
5
|
+
library(optparse)
|
|
6
|
+
option_list <- list(
|
|
7
|
+
make_option(c("-i", "--input"), type = "character", default = FALSE,
|
|
8
|
+
help = "input file path"),
|
|
9
|
+
make_option(c("-o", "--output"), type = "character", default = FALSE,
|
|
10
|
+
help = "output file path"),
|
|
11
|
+
make_option(c("-p", "--prefix"), type = "character", default = FALSE,
|
|
12
|
+
help = "prefix of output file"),
|
|
13
|
+
make_option(c("-t", "--type"), type = "character", default = FALSE,
|
|
14
|
+
help = "type of mod (m6A, m5C, AtoI, psi, etc.)")
|
|
15
|
+
)
|
|
16
|
+
opt_parser <- OptionParser(option_list = option_list)
|
|
17
|
+
opt <- parse_args(opt_parser)
|
|
18
|
+
|
|
19
|
+
input <- opt$input
|
|
20
|
+
output <- opt$output
|
|
21
|
+
prefix <- opt$prefix
|
|
22
|
+
type <- opt$type
|
|
23
|
+
|
|
24
|
+
# library packages
|
|
25
|
+
library(dplyr)
|
|
26
|
+
library(purrr)
|
|
27
|
+
library(scales)
|
|
28
|
+
library(ggplot2)
|
|
29
|
+
library(magrittr)
|
|
30
|
+
library(legendBaseModel)
|
|
31
|
+
|
|
32
|
+
plot_metagene_Rd <- function(input_data, output_path, prefix, mod_type = "m6A") {
|
|
33
|
+
ifelse(dir.exists(output_path), "Dir exist alreadly!", dir.create(output_path, recursive = TRUE))
|
|
34
|
+
tryCatch({
|
|
35
|
+
# START
|
|
36
|
+
cat(crayon::green(paste0(prefix, " Start ploting Metagene\n")))
|
|
37
|
+
colour_fill <- c("black", "red")
|
|
38
|
+
names(colour_fill) <- input_data$group %>% unique()
|
|
39
|
+
p1 <- ggplot(input_data, aes(x=value))+
|
|
40
|
+
geom_line(aes(colour = group), stat = "density", adjust = 2) +
|
|
41
|
+
scale_colour_manual(values=colour_fill) +
|
|
42
|
+
geom_vline(xintercept = 1:2, col = "red", linetype="dashed") +
|
|
43
|
+
annotate("text", x = 0.5, y = -0.14, label = "5'UTR") +
|
|
44
|
+
annotate("text", x = 1.5, y = -0.14, label = "CDS") +
|
|
45
|
+
annotate("text", x = 2.5, y = -0.14, label = "3'UTR") +
|
|
46
|
+
annotate("rect", xmin = 0, xmax = 1, ymin = -0.08, ymax = -0.04, alpha = .99, colour = "black")+
|
|
47
|
+
annotate("rect", xmin = 2, xmax = 3, ymin = -0.08, ymax = -0.04, alpha = .99, colour = "black")+
|
|
48
|
+
annotate("rect", xmin = 1, xmax = 2, ymin = -0.12, ymax = 0, alpha = .2, colour = "black") +
|
|
49
|
+
xlab(paste0(mod_type, " metagene")) +
|
|
50
|
+
ylab("Frequency") +
|
|
51
|
+
guides(colour = guide_legend(title = NULL)) +
|
|
52
|
+
theme_bw() +
|
|
53
|
+
theme(legend.position = c(1, 1), legend.justification = c(1, 1)) +
|
|
54
|
+
theme(legend.background = element_blank())
|
|
55
|
+
ggsave(paste0(output_path, "/", prefix, "_", mod_type, "_metagene.pdf"), p1, width = 8, height = 6)
|
|
56
|
+
ggsave(paste0(output_path, "/", prefix, "_", mod_type, "_metagene.png"), p1, width = 8, height = 6)
|
|
57
|
+
ggsave(paste0(output_path, "/", prefix, "_", mod_type, "_metagene.tiff"), p1, width = 8, height = 6)
|
|
58
|
+
|
|
59
|
+
cat(crayon::green(paste0(prefix, " Metagene analysis done\n")))
|
|
60
|
+
# END
|
|
61
|
+
return("sucess")},
|
|
62
|
+
error = function(e){print(e$message);message(return("failled"))})
|
|
63
|
+
}
|
|
64
|
+
restructure_coord <- function(input_path, group, type) {
|
|
65
|
+
if (type == "m6A") {
|
|
66
|
+
m6a.dist <- read.delim(input_path, header = T) %>%
|
|
67
|
+
dplyr::filter(utr5_size > utr3_size) %>%
|
|
68
|
+
dplyr::mutate(
|
|
69
|
+
trx_len = utr5_size + cds_size + utr3_size)
|
|
70
|
+
} else if (type == "m5C") {
|
|
71
|
+
m6a.dist <- read.delim(input_path, header = T) %>%
|
|
72
|
+
dplyr::filter(cds_size > utr3_size & utr3_size > utr5_size) %>%
|
|
73
|
+
dplyr::mutate(
|
|
74
|
+
trx_len = utr5_size + cds_size + utr3_size)
|
|
75
|
+
} else if (type == "psi") {
|
|
76
|
+
m6a.dist <- read.delim(input_path, header = T) %>%
|
|
77
|
+
dplyr::filter(cds_size > utr3_size & utr3_size > utr5_size) %>%
|
|
78
|
+
dplyr::mutate(
|
|
79
|
+
trx_len = utr5_size + cds_size + utr3_size)
|
|
80
|
+
} else if (type == "AtoI") {
|
|
81
|
+
m6a.dist <- read.delim(input_path, header = T) %>%
|
|
82
|
+
dplyr::filter(cds_size > utr3_size & utr3_size > utr5_size) %>%
|
|
83
|
+
dplyr::mutate(
|
|
84
|
+
trx_len = utr5_size + cds_size + utr3_size)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
temp.df <- m6a.dist %>%
|
|
88
|
+
dplyr::select(c("gene_name", "refseqID", "trx_len")) %>%
|
|
89
|
+
dplyr::rename(setNames(colnames(.), c("gene_name", "gid", "trx_len"))) %$%
|
|
90
|
+
.[order(.$gene_name, .$gid, -.$trx_len), ] %$%
|
|
91
|
+
.[!duplicated(.$gene_name), ]
|
|
92
|
+
|
|
93
|
+
m6a.dist <- m6a.dist[m6a.dist$refseqID %in% temp.df$gid, ]
|
|
94
|
+
utr5.SF <- median(m6a.dist$utr5_size, na.rm = T)/median(m6a.dist$cds_size, na.rm = T)
|
|
95
|
+
utr3.SF <- median(m6a.dist$utr3_size, na.rm = T)/median(m6a.dist$cds_size, na.rm = T)
|
|
96
|
+
# print(paste0("utr5.SF: ", utr5.SF, " utr3.SF: ", utr3.SF))
|
|
97
|
+
utr5.m6a.dist <- m6a.dist[m6a.dist$rel_location < 1, ]
|
|
98
|
+
cds.m6a.dist <- m6a.dist[m6a.dist$rel_location < 2 & m6a.dist$rel_location >= 1, ]
|
|
99
|
+
utr3.m6a.dist <- m6a.dist[m6a.dist$rel_location >= 2 & m6a.dist$rel_location < 3, ]
|
|
100
|
+
utr5.m6a.dist$rel_location <- scales::rescale(utr5.m6a.dist$rel_location, to = c(1-utr5.SF, 1), from = c(0, 1))
|
|
101
|
+
utr3.m6a.dist$rel_location <- scales::rescale(utr3.m6a.dist$rel_location, to = c(2, 2+utr3.SF), from = c(2, 3))
|
|
102
|
+
m6a.metagene.coord <- c(utr5.m6a.dist$rel_location, cds.m6a.dist$rel_location, utr3.m6a.dist$rel_location)
|
|
103
|
+
|
|
104
|
+
m6a_data <- data.frame("value"= m6a.metagene.coord) %>%
|
|
105
|
+
dplyr::mutate("group"= group)
|
|
106
|
+
return(m6a_data)
|
|
107
|
+
}
|
|
108
|
+
auto_meta_plot <- function(input_path, output_path, prefix, mod_type = "m6A") {
|
|
109
|
+
# test
|
|
110
|
+
# 2. check output path
|
|
111
|
+
options(warn = -1)
|
|
112
|
+
ifelse(dir.exists(output_path), "Dir exist alreadly!", dir.create(output_path, recursive = TRUE))
|
|
113
|
+
tryCatch({
|
|
114
|
+
# START
|
|
115
|
+
sample_all <- legendBaseModel::make_sample_sheet(input_path, paste0("_", mod_type, "_abs_dist.txt")) %>%
|
|
116
|
+
dplyr::mutate(
|
|
117
|
+
group = sample,
|
|
118
|
+
type = mod_type,
|
|
119
|
+
dist_measures = purrr::pmap(list(sample_path, group, type), restructure_coord)
|
|
120
|
+
) %>%
|
|
121
|
+
dplyr::mutate(
|
|
122
|
+
output_plot = output_path,
|
|
123
|
+
prefix_plot = paste0(prefix, group),
|
|
124
|
+
plot_meta <- purrr::pmap(list(dist_measures, output_plot, prefix_plot, type), plot_metagene_Rd)
|
|
125
|
+
)
|
|
126
|
+
# END
|
|
127
|
+
return("sucess")},
|
|
128
|
+
error = function(e){print(e$message);message(return("failled"))})
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
# main run
|
|
133
|
+
auto_meta_plot(input, output, prefix, type)
|