PyTFBS 1.0.0__tar.gz → 1.0.2__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.
- pytfbs-1.0.2/PKG-INFO +69 -0
- pytfbs-1.0.2/PyTFBS/motif.py +196 -0
- pytfbs-1.0.2/PyTFBS/predict.py +413 -0
- pytfbs-1.0.2/PyTFBS.egg-info/PKG-INFO +69 -0
- pytfbs-1.0.2/PyTFBS.egg-info/SOURCES.txt +12 -0
- {pytfbs-1.0.0/src → pytfbs-1.0.2}/PyTFBS.egg-info/entry_points.txt +1 -0
- pytfbs-1.0.2/PyTFBS.egg-info/requires.txt +16 -0
- pytfbs-1.0.2/README.md +40 -0
- {pytfbs-1.0.0 → pytfbs-1.0.2}/pyproject.toml +14 -16
- pytfbs-1.0.0/PKG-INFO +0 -48
- pytfbs-1.0.0/README.md +0 -18
- pytfbs-1.0.0/src/PyTFBS/tango.py +0 -0
- pytfbs-1.0.0/src/PyTFBS.egg-info/PKG-INFO +0 -48
- pytfbs-1.0.0/src/PyTFBS.egg-info/SOURCES.txt +0 -11
- pytfbs-1.0.0/src/PyTFBS.egg-info/requires.txt +0 -8
- {pytfbs-1.0.0 → pytfbs-1.0.2}/LICENSE +0 -0
- {pytfbs-1.0.0/src → pytfbs-1.0.2}/PyTFBS/__init__.py +0 -0
- {pytfbs-1.0.0/src → pytfbs-1.0.2}/PyTFBS.egg-info/dependency_links.txt +0 -0
- {pytfbs-1.0.0/src → pytfbs-1.0.2}/PyTFBS.egg-info/top_level.txt +0 -0
- {pytfbs-1.0.0 → pytfbs-1.0.2}/setup.cfg +0 -0
pytfbs-1.0.2/PKG-INFO
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: PyTFBS
|
|
3
|
+
Version: 1.0.2
|
|
4
|
+
Summary: PyTFBS: A Python Package for Transcription Factor Binding Site Prediction
|
|
5
|
+
Author-email: Tinghua Huang <thua45@126.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/thua45/pytfbs
|
|
8
|
+
Project-URL: Documentation, https://github.com/thua45/pytfbs#readme
|
|
9
|
+
Project-URL: Repository, https://github.com/thua45/pytfbs
|
|
10
|
+
Project-URL: Issues, https://github.com/thua45/pytfbs/issues
|
|
11
|
+
Keywords: PyTFBS,Transcription Factor,Binding Site
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Requires-Python: >=3.11
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
License-File: LICENSE
|
|
20
|
+
Requires-Dist: torch
|
|
21
|
+
Requires-Dist: numpy==1.26; sys_platform == "darwin"
|
|
22
|
+
Requires-Dist: numpy>=2.0; sys_platform == "win32"
|
|
23
|
+
Requires-Dist: numpy>=2.0; sys_platform == "linux"
|
|
24
|
+
Provides-Extra: dev
|
|
25
|
+
Requires-Dist: matplotlib; extra == "dev"
|
|
26
|
+
Provides-Extra: test
|
|
27
|
+
Requires-Dist: matplotlib; extra == "test"
|
|
28
|
+
Dynamic: license-file
|
|
29
|
+
|
|
30
|
+
# PyTFBS
|
|
31
|
+
|
|
32
|
+
A Python package for dpredicting transcription factor binding sites.
|
|
33
|
+
|
|
34
|
+
## Installation
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pip install torch numpy PyTFBS
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Usage
|
|
41
|
+
|
|
42
|
+
```python
|
|
43
|
+
from PyTFBS import motif, predict
|
|
44
|
+
|
|
45
|
+
# download PyTFBS data, only need to run once!!!
|
|
46
|
+
motif.download_data()
|
|
47
|
+
|
|
48
|
+
# list available models
|
|
49
|
+
motif.list_models(species='Homo sapiens', accuracy=0.9, sensitivity=0.9)
|
|
50
|
+
|
|
51
|
+
# get avaiable motifs
|
|
52
|
+
motifs = motif.get_motifs(species='Homo sapiens', accuracy=0.9, sensitivity=0.9)
|
|
53
|
+
print(motifs)
|
|
54
|
+
|
|
55
|
+
# get models based on motif name
|
|
56
|
+
models = motif.get_models('RFX2_HUMAN.H11MO.0.A')
|
|
57
|
+
print(models)
|
|
58
|
+
|
|
59
|
+
# predict one model
|
|
60
|
+
predict.script('CEBPB_HUMAN.H11MO.0.A', 'CEBPB_HUMAN.H11MO.0.A_1231', 'input_seq_file.fasta', 'out_file.txt')
|
|
61
|
+
|
|
62
|
+
# speed up using mutil-threading (for Windows OS only)
|
|
63
|
+
predict.win_bin('CEBPB_HUMAN.H11MO.0.A', 'CEBPB_HUMAN.H11MO.0.A_1231', 'input_seq_file.fasta', 64, 'out_file.txt')
|
|
64
|
+
|
|
65
|
+
# run prediction with user motif data
|
|
66
|
+
# the my_motif_dir should be organized as [[motif], [trace], [par]]
|
|
67
|
+
predict.script('CEBPB_HUMAN.H11MO.0.A', 'CEBPB_HUMAN.H11MO.0.A_1231', 'input_seq_file.fasta', data_dir='my_motif_dir')
|
|
68
|
+
predict.win_bin('CEBPB_HUMAN.H11MO.0.A', 'CEBPB_HUMAN.H11MO.0.A_1231', 'input_seq_file.fasta', 64, data_dir='my_motif_dir')
|
|
69
|
+
```
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
# from importlib import resources
|
|
2
|
+
import urllib.request
|
|
3
|
+
import zipfile
|
|
4
|
+
import os
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
PyTFBS_data_dir = './PyTFBS_data'
|
|
8
|
+
|
|
9
|
+
def download_with_progress(url, filename=None):
|
|
10
|
+
"""
|
|
11
|
+
带进度显示的下载函数
|
|
12
|
+
"""
|
|
13
|
+
def progress_callback(block_num, block_size, total_size):
|
|
14
|
+
"""
|
|
15
|
+
进度回调函数
|
|
16
|
+
|
|
17
|
+
Args:
|
|
18
|
+
block_num: 当前已下载的块数量
|
|
19
|
+
block_size: 每个块的大小(字节)
|
|
20
|
+
total_size: 文件总大小(字节)
|
|
21
|
+
"""
|
|
22
|
+
downloaded = block_num * block_size
|
|
23
|
+
percent = downloaded / total_size * 100 if total_size > 0 else 0
|
|
24
|
+
|
|
25
|
+
# 限制显示频率,避免刷新太快
|
|
26
|
+
if block_num % 100 == 0 or downloaded >= total_size:
|
|
27
|
+
print(f"\rProgress: {percent:.1f}% ({downloaded}/{total_size} bytes)", end='', flush=True)
|
|
28
|
+
|
|
29
|
+
# 如果没有指定文件名,从URL中提取
|
|
30
|
+
if filename is None:
|
|
31
|
+
filename = os.path.basename(url)
|
|
32
|
+
|
|
33
|
+
print(f"start download: {url}")
|
|
34
|
+
print(f"save as: {filename}")
|
|
35
|
+
|
|
36
|
+
try:
|
|
37
|
+
urllib.request.urlretrieve(url, filename, progress_callback)
|
|
38
|
+
print("donwload sucessful")
|
|
39
|
+
except Exception as e:
|
|
40
|
+
print(f"donwload failed: {e}")
|
|
41
|
+
exit(1)
|
|
42
|
+
|
|
43
|
+
# 使用示例
|
|
44
|
+
# download_with_progress("https://example.com/largefile.zip", "downloaded_file.zip")
|
|
45
|
+
|
|
46
|
+
def extractall_individual_files(zip_path, extract_path):
|
|
47
|
+
"""
|
|
48
|
+
使用 extract() 方法逐个解压文件,确保覆盖
|
|
49
|
+
"""
|
|
50
|
+
os.makedirs(extract_path, exist_ok=True)
|
|
51
|
+
|
|
52
|
+
with zipfile.ZipFile(zip_path, 'r') as zip_ref:
|
|
53
|
+
# 获取所有成员信息
|
|
54
|
+
members = zip_ref.infolist()
|
|
55
|
+
|
|
56
|
+
print(f"extracting {len(members)} file...")
|
|
57
|
+
|
|
58
|
+
for i, member in enumerate(members, 1):
|
|
59
|
+
try:
|
|
60
|
+
# 直接使用 extract() 方法,它会处理覆盖
|
|
61
|
+
zip_ref.extract(member, extract_path)
|
|
62
|
+
|
|
63
|
+
if i % 10 == 0 or i == len(members):
|
|
64
|
+
print(f"progress: {i}/{len(members)}")
|
|
65
|
+
|
|
66
|
+
except Exception as e:
|
|
67
|
+
print(f"extracting failed {member.filename}: {e}")
|
|
68
|
+
exit(1)
|
|
69
|
+
|
|
70
|
+
print("extracting finished")
|
|
71
|
+
|
|
72
|
+
# 使用示例
|
|
73
|
+
# extractall_individual_files("example.zip", "extracted_files")
|
|
74
|
+
|
|
75
|
+
def download_and_extract_zip(url, extract_to):
|
|
76
|
+
"""
|
|
77
|
+
下载ZIP文件并解压到指定目录
|
|
78
|
+
|
|
79
|
+
Args:
|
|
80
|
+
url: ZIP文件的URL
|
|
81
|
+
extract_to: 解压目标目录
|
|
82
|
+
"""
|
|
83
|
+
# 创建目标目录
|
|
84
|
+
Path(extract_to).mkdir(parents=True, exist_ok=True)
|
|
85
|
+
|
|
86
|
+
# 临时ZIP文件路径
|
|
87
|
+
zip_path = os.path.join(extract_to, "temp.zip")
|
|
88
|
+
|
|
89
|
+
try:
|
|
90
|
+
# 下载文件
|
|
91
|
+
# print(f"downloading: {url}")
|
|
92
|
+
# urllib.request.urlretrieve(url, zip_path)
|
|
93
|
+
download_with_progress(url, zip_path)
|
|
94
|
+
# print("donwload finished")
|
|
95
|
+
|
|
96
|
+
# 解压文件
|
|
97
|
+
# print(f"extracting: {extract_to}")
|
|
98
|
+
# with zipfile.ZipFile(zip_path, 'r') as zip_ref:
|
|
99
|
+
# zip_ref.extractall(extract_to, overwrite=True)
|
|
100
|
+
extractall_individual_files(zip_path, extract_to)
|
|
101
|
+
# print("extract finished")
|
|
102
|
+
|
|
103
|
+
except Exception as e:
|
|
104
|
+
print(f"错误: {e}")
|
|
105
|
+
return False
|
|
106
|
+
finally:
|
|
107
|
+
# 清理临时ZIP文件
|
|
108
|
+
if os.path.exists(zip_path):
|
|
109
|
+
os.remove(zip_path)
|
|
110
|
+
print("clearing temp files")
|
|
111
|
+
|
|
112
|
+
return True
|
|
113
|
+
|
|
114
|
+
def download_data(data_dir=None):
|
|
115
|
+
if data_dir == None:
|
|
116
|
+
data_dir = PyTFBS_data_dir
|
|
117
|
+
if not (os.path.exists(data_dir) and os.path.isdir(data_dir)):
|
|
118
|
+
print(data_dir, 'not exist, creating...')
|
|
119
|
+
folder_path = Path(data_dir)
|
|
120
|
+
folder_path.mkdir(exist_ok=True)
|
|
121
|
+
url = "http://www.thua45.cn/PyTFBS/PyTFBS_data.zip"
|
|
122
|
+
extract_dir = data_dir
|
|
123
|
+
# extract_dir = "./downloaded_content"
|
|
124
|
+
success = download_and_extract_zip(url, extract_dir)
|
|
125
|
+
if success:
|
|
126
|
+
print("models installed successful")
|
|
127
|
+
|
|
128
|
+
def list_models(motif_name=None, species=None, accuracy=None, sensitivity=None, data_dir=None):
|
|
129
|
+
if data_dir == None:
|
|
130
|
+
data_dir = PyTFBS_data_dir
|
|
131
|
+
index_file = data_dir + '/motif_index.txt'
|
|
132
|
+
if not os.path.exists(index_file):
|
|
133
|
+
print('motif_index.txt not exist, you may need to run download_data() first')
|
|
134
|
+
exit(1)
|
|
135
|
+
header = ''
|
|
136
|
+
result = []
|
|
137
|
+
for line in open(index_file, 'r'):
|
|
138
|
+
if line[0] == "#":
|
|
139
|
+
header = line.rstrip()
|
|
140
|
+
continue
|
|
141
|
+
lblocks = line.rstrip().split('\t')
|
|
142
|
+
if motif_name != None and lblocks[0] != motif_name:
|
|
143
|
+
continue
|
|
144
|
+
if species != None and lblocks[1] != species:
|
|
145
|
+
continue
|
|
146
|
+
if accuracy != None and float(lblocks[3]) < accuracy:
|
|
147
|
+
continue
|
|
148
|
+
if sensitivity != None and float(lblocks[4]) < sensitivity:
|
|
149
|
+
continue
|
|
150
|
+
result.append(lblocks)
|
|
151
|
+
print(header)
|
|
152
|
+
for rline in result:
|
|
153
|
+
print('\t'.join(rline))
|
|
154
|
+
|
|
155
|
+
def get_motifs(motif_name=None, species=None, accuracy=None, sensitivity=None, data_dir=None):
|
|
156
|
+
if data_dir == None:
|
|
157
|
+
data_dir = PyTFBS_data_dir
|
|
158
|
+
index_file = data_dir + '/motif_index.txt'
|
|
159
|
+
if not os.path.exists(index_file):
|
|
160
|
+
print('motif_index.txt not exist, you may need to run download_data() first')
|
|
161
|
+
exit(1)
|
|
162
|
+
header = ''
|
|
163
|
+
result = []
|
|
164
|
+
for line in open(index_file, 'r'):
|
|
165
|
+
if line[0] == "#":
|
|
166
|
+
header = line.rstrip()
|
|
167
|
+
continue
|
|
168
|
+
lblocks = line.rstrip().split('\t')
|
|
169
|
+
if motif_name != None and lblocks[0] != motif_name:
|
|
170
|
+
continue
|
|
171
|
+
if species != None and lblocks[1] != species:
|
|
172
|
+
continue
|
|
173
|
+
if accuracy != None and float(lblocks[3]) < accuracy:
|
|
174
|
+
continue
|
|
175
|
+
if sensitivity != None and float(lblocks[4]) < sensitivity:
|
|
176
|
+
continue
|
|
177
|
+
result.append(lblocks[0])
|
|
178
|
+
return result
|
|
179
|
+
|
|
180
|
+
def get_models(motif_name, data_dir=None):
|
|
181
|
+
if data_dir == None:
|
|
182
|
+
data_dir = PyTFBS_data_dir
|
|
183
|
+
index_file = data_dir + '/motif_index.txt'
|
|
184
|
+
if not os.path.exists(index_file):
|
|
185
|
+
print('motif_index.txt not exist, you may need to run download_data() first')
|
|
186
|
+
exit(1)
|
|
187
|
+
models = []
|
|
188
|
+
for line in open(index_file, 'r'):
|
|
189
|
+
if line[0] == "#":
|
|
190
|
+
header = line.rstrip()
|
|
191
|
+
continue
|
|
192
|
+
lblocks = line.rstrip().split('\t')
|
|
193
|
+
if lblocks[0] != motif_name:
|
|
194
|
+
continue
|
|
195
|
+
models.append(lblocks[2])
|
|
196
|
+
return {'motif_name': motif_name, 'models': models}
|
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
import os
|
|
3
|
+
from importlib import resources
|
|
4
|
+
from collections import defaultdict
|
|
5
|
+
from importlib import resources
|
|
6
|
+
import math
|
|
7
|
+
import torch
|
|
8
|
+
import torch.nn as nn
|
|
9
|
+
from torch.nn import functional as F
|
|
10
|
+
|
|
11
|
+
PyTFBS_data_dir = './PyTFBS_data'
|
|
12
|
+
|
|
13
|
+
def has_non_acgtn_upper(sequence):
|
|
14
|
+
"""只检查大写ACGT字符"""
|
|
15
|
+
valid_chars = {'A', 'C', 'G', 'T', 'N'}
|
|
16
|
+
return any(char.upper() not in valid_chars for char in sequence)
|
|
17
|
+
|
|
18
|
+
def sequence_to_numbers(sequence, mapping=None):
|
|
19
|
+
# 将ACGT序列转换为数字列表
|
|
20
|
+
if mapping is None:
|
|
21
|
+
mapping = {'A': 0, 'C': 1, 'G': 2, 'T': 3, 'N': 4}
|
|
22
|
+
return [mapping.get(base.upper(), -1) for base in sequence]
|
|
23
|
+
|
|
24
|
+
def to_base(line_str):
|
|
25
|
+
seq_base = 'ACGT'
|
|
26
|
+
line_blocks = line_str.split('\t')
|
|
27
|
+
line_data = [float(bi) for bi in line_blocks]
|
|
28
|
+
max_index = line_data.index(max(line_data))
|
|
29
|
+
# print(max_index)
|
|
30
|
+
base = seq_base[max_index]
|
|
31
|
+
return base
|
|
32
|
+
|
|
33
|
+
def read_motif(fasta_file):
|
|
34
|
+
motifs_all = {}
|
|
35
|
+
#fasta = {}
|
|
36
|
+
#motifs = []
|
|
37
|
+
#motif_names = []
|
|
38
|
+
fp = open(fasta_file, 'r')
|
|
39
|
+
header = ''
|
|
40
|
+
seq = ''
|
|
41
|
+
motif = []
|
|
42
|
+
for line in fp:
|
|
43
|
+
line_str = line.rstrip()
|
|
44
|
+
if line_str[0] == '>':
|
|
45
|
+
if header != '':
|
|
46
|
+
#fasta[header] = seq
|
|
47
|
+
#motifs.append(motif)
|
|
48
|
+
#motif_names.append(header)
|
|
49
|
+
motifs_all[header] = (motif, seq)
|
|
50
|
+
header = line_str[1:len(line_str)]
|
|
51
|
+
seq = ''
|
|
52
|
+
motif = []
|
|
53
|
+
else:
|
|
54
|
+
seq += to_base(line_str)
|
|
55
|
+
motif.append(to_mdata_n_frq(line_str))
|
|
56
|
+
else:
|
|
57
|
+
if header != '':
|
|
58
|
+
# fasta[header] = seq
|
|
59
|
+
# motifs.append(motif)
|
|
60
|
+
# motif_names.append(header)
|
|
61
|
+
motifs_all[header] = (motif, seq)
|
|
62
|
+
fp.close()
|
|
63
|
+
return motifs_all
|
|
64
|
+
|
|
65
|
+
def cal_base_freq(fasta_seqs):
|
|
66
|
+
base_sum = [0.25, 0.25, 0.25, 0.25, 0.25]
|
|
67
|
+
for seq_name in fasta_seqs.keys():
|
|
68
|
+
for base in fasta_seqs[seq_name]:
|
|
69
|
+
if base == 'A' or base == 'a':
|
|
70
|
+
base_sum[0] += 1
|
|
71
|
+
elif base == 'C' or base == 'c':
|
|
72
|
+
base_sum[1] += 1
|
|
73
|
+
elif base == 'G' or base == 'g':
|
|
74
|
+
base_sum[2] += 1
|
|
75
|
+
elif base == 'T' or base == 't':
|
|
76
|
+
base_sum[3] += 1
|
|
77
|
+
elif base == 'N' or base == 'n':
|
|
78
|
+
base_sum[4] += 1
|
|
79
|
+
bsum = sum(base_sum)
|
|
80
|
+
base_freq1 = [bs / bsum for bs in base_sum]
|
|
81
|
+
return base_freq1
|
|
82
|
+
|
|
83
|
+
def read_motif_single(fasta_file):
|
|
84
|
+
motif_name = ''
|
|
85
|
+
motif = []
|
|
86
|
+
for line in open(fasta_file, 'r'):
|
|
87
|
+
line_str = line.rstrip()
|
|
88
|
+
if line_str == '':
|
|
89
|
+
continue
|
|
90
|
+
if line_str[0] == '>':
|
|
91
|
+
motif_name = line_str[1:len(line_str)]
|
|
92
|
+
else:
|
|
93
|
+
motif.append(to_mdata_n_frq(line_str))
|
|
94
|
+
return motif_name, motif
|
|
95
|
+
|
|
96
|
+
def cal_base_freq(fasta_seqs):
|
|
97
|
+
base_sum = [0.25, 0.25, 0.25, 0.25, 0.25]
|
|
98
|
+
for seq_name in fasta_seqs.keys():
|
|
99
|
+
for base in fasta_seqs[seq_name]:
|
|
100
|
+
if base == 'A' or base == 'a':
|
|
101
|
+
base_sum[0] += 1
|
|
102
|
+
elif base == 'C' or base == 'c':
|
|
103
|
+
base_sum[1] += 1
|
|
104
|
+
elif base == 'G' or base == 'g':
|
|
105
|
+
base_sum[2] += 1
|
|
106
|
+
elif base == 'T' or base == 't':
|
|
107
|
+
base_sum[3] += 1
|
|
108
|
+
elif base == 'N' or base == 'n':
|
|
109
|
+
base_sum[4] += 1
|
|
110
|
+
bsum = sum(base_sum)
|
|
111
|
+
base_freq1 = [bs / bsum for bs in base_sum]
|
|
112
|
+
return base_freq1
|
|
113
|
+
|
|
114
|
+
def read_fasta(file):
|
|
115
|
+
fasta = {}
|
|
116
|
+
header = ''
|
|
117
|
+
seq = ''
|
|
118
|
+
seq_id = 0
|
|
119
|
+
for line in open(file, 'r'):
|
|
120
|
+
line_str = line.rstrip()
|
|
121
|
+
if line_str[0] == '>':
|
|
122
|
+
if header != '':
|
|
123
|
+
seq_id += 1
|
|
124
|
+
fasta[header] = seq
|
|
125
|
+
header = line_str[1:len(line_str)]
|
|
126
|
+
seq = ''
|
|
127
|
+
else:
|
|
128
|
+
seq += line_str
|
|
129
|
+
else:
|
|
130
|
+
if header != '':
|
|
131
|
+
seq_id += 1
|
|
132
|
+
fasta[header] = seq
|
|
133
|
+
seq_freq = cal_base_freq(fasta)
|
|
134
|
+
return fasta, seq_freq
|
|
135
|
+
|
|
136
|
+
def to_mdata_n(line_str):
|
|
137
|
+
seq_base = 'ACGT'
|
|
138
|
+
line_blocks = line_str.split('\t')
|
|
139
|
+
line_data = [float(bi) + 0.25 for bi in line_blocks]
|
|
140
|
+
line_data.append(0.25)
|
|
141
|
+
return line_data
|
|
142
|
+
|
|
143
|
+
def to_mdata_n_frq(line_str):
|
|
144
|
+
seq_base = 'ACGT'
|
|
145
|
+
line_blocks = line_str.split('\t')
|
|
146
|
+
line_data = [float(bi) + 0.25 for bi in line_blocks]
|
|
147
|
+
line_data.append(0.25)
|
|
148
|
+
sum_base = sum(line_data)
|
|
149
|
+
line_data_frq = [da / sum_base for da in line_data]
|
|
150
|
+
return line_data_frq
|
|
151
|
+
|
|
152
|
+
'''
|
|
153
|
+
def forward(x, params):
|
|
154
|
+
# global parameters
|
|
155
|
+
w1, b1, w2, b2, w3, b3 = params
|
|
156
|
+
x = x @ w1.t() + b1
|
|
157
|
+
x = torch.tanh(x)
|
|
158
|
+
x = x @ w2.t() + b2
|
|
159
|
+
x = torch.tanh(x)
|
|
160
|
+
x = x @ w3.t() + b3
|
|
161
|
+
x = torch.tanh(x)
|
|
162
|
+
return x
|
|
163
|
+
'''
|
|
164
|
+
|
|
165
|
+
def forward(x, params):
|
|
166
|
+
# global parameters
|
|
167
|
+
w1, b1, w2, b2, w3, b3 = params
|
|
168
|
+
x = x @ w1.t() + b1
|
|
169
|
+
x = F.relu(x)
|
|
170
|
+
x = x @ w2.t() + b2
|
|
171
|
+
x = F.relu(x)
|
|
172
|
+
x = x @ w3.t() + b3
|
|
173
|
+
x = F.relu(x)
|
|
174
|
+
return x
|
|
175
|
+
|
|
176
|
+
def predict_llrs(seq, motif, header, motif_name):
|
|
177
|
+
global parameters
|
|
178
|
+
base_freq, j_mean = parameters['jpar']
|
|
179
|
+
# print('base_freq, j_mean: ', base_freq, j_mean)
|
|
180
|
+
model_pars = parameters['model']
|
|
181
|
+
dseq = sequence_to_numbers(seq)
|
|
182
|
+
seq_len = len(seq)
|
|
183
|
+
motif_len = len(motif)
|
|
184
|
+
j_best = -10.0
|
|
185
|
+
best_pos = 0
|
|
186
|
+
best_llrs = []
|
|
187
|
+
llr_matrix = []
|
|
188
|
+
j_tmps = []
|
|
189
|
+
for si in range(seq_len - motif_len + 1):
|
|
190
|
+
llr_sum = 0.0
|
|
191
|
+
llrs = []
|
|
192
|
+
for mi in range(motif_len):
|
|
193
|
+
base = dseq[si + mi]
|
|
194
|
+
if base == 4:
|
|
195
|
+
llr = 0.0
|
|
196
|
+
else:
|
|
197
|
+
llr = math.log(motif[mi][base] / base_freq[base]);
|
|
198
|
+
llr_sum += llr
|
|
199
|
+
# print(motif[mi][base], base_freq[base])
|
|
200
|
+
llrs.append(llr)
|
|
201
|
+
# llrs_norm = [llr - j_mean for llr in llrs]
|
|
202
|
+
llrs_norm = llrs
|
|
203
|
+
# print('llrs_norm: ', llrs_norm)
|
|
204
|
+
j_tmp = llr_sum / motif_len
|
|
205
|
+
if j_tmp > 0.0:
|
|
206
|
+
llr_matrix.append(llrs_norm)
|
|
207
|
+
j_tmps.append(j_tmp)
|
|
208
|
+
data = torch.tensor(llr_matrix)
|
|
209
|
+
data = data.view(-1, motif_len)
|
|
210
|
+
logits = forward(data, model_pars)
|
|
211
|
+
predict = torch.sigmoid(logits * 4.0)
|
|
212
|
+
# print('predict.shape:', predict.shape)
|
|
213
|
+
col_index = 1
|
|
214
|
+
#indices = torch.nonzero(predict[:, col_index] >= 0.5, as_tuple=False)
|
|
215
|
+
indices = torch.nonzero((predict[:, 1] > 0.75) & (predict[:, 0] < 0.25), as_tuple=False)
|
|
216
|
+
for value in indices:
|
|
217
|
+
match_seq = seq[value.item(): value.item() + motif_len]
|
|
218
|
+
print(header, motif_name, value.item(), match_seq, j_tmps[value.item()], predict[value, 0].item(), predict[value, 1].item())
|
|
219
|
+
|
|
220
|
+
def predict_seq():
|
|
221
|
+
motifs_all = read_motif('motif_data.txt')
|
|
222
|
+
# fasta, seq_freq = read_fasta('GCF_000001405.40_GRCh38.p14_promoter_1.1k.txt')
|
|
223
|
+
fasta, seq_freq = read_fasta('GCF_000001405.40_GRCh38.p14_promoter_1.1k_rdm1000.txt')
|
|
224
|
+
# print(len(fasta))
|
|
225
|
+
for seq_name in fasta.keys():
|
|
226
|
+
seq = fasta[seq_name].upper()
|
|
227
|
+
if has_non_acgtn_upper(seq):
|
|
228
|
+
continue
|
|
229
|
+
for motif_name in motifs_all.keys():
|
|
230
|
+
if motif_name != 'ANDR_HUMAN.H11MO.0.A':
|
|
231
|
+
continue
|
|
232
|
+
motif = motifs_all[motif_name][0]
|
|
233
|
+
predict_llrs(seq, motif, seq_name, motif_name)
|
|
234
|
+
|
|
235
|
+
def seq2onehot(seq_in, motif_len, motif, base_freq):
|
|
236
|
+
datas = []
|
|
237
|
+
poss = []
|
|
238
|
+
j_tmps = []
|
|
239
|
+
seq_len = len(seq_in)
|
|
240
|
+
for si in range(seq_len - motif_len + 1):
|
|
241
|
+
seq = seq_in[si: si + motif_len]
|
|
242
|
+
j_tmp = jindex(seq, motif, base_freq)
|
|
243
|
+
# print(j_tmp)
|
|
244
|
+
if j_tmp <= 0.0:
|
|
245
|
+
continue
|
|
246
|
+
poss.append(si)
|
|
247
|
+
j_tmps.append(j_tmp)
|
|
248
|
+
seq_onehot = []
|
|
249
|
+
dseq = sequence_to_numbers(seq.upper())
|
|
250
|
+
for si in dseq:
|
|
251
|
+
sonehot = [0.0, 0.0, 0.0, 0.0, 0.0]
|
|
252
|
+
sonehot[si] = 1.0
|
|
253
|
+
seq_onehot += sonehot
|
|
254
|
+
datas.append(seq_onehot)
|
|
255
|
+
return datas, poss, j_tmps
|
|
256
|
+
|
|
257
|
+
def jindex(seq, motif, base_freq):
|
|
258
|
+
dseq = sequence_to_numbers(seq)
|
|
259
|
+
motif_len = len(motif)
|
|
260
|
+
llr_sum = 0.0
|
|
261
|
+
for mi in range(motif_len):
|
|
262
|
+
base = dseq[mi]
|
|
263
|
+
if base == 4:
|
|
264
|
+
llr = 0.0
|
|
265
|
+
else:
|
|
266
|
+
llr = math.log(motif[mi][base] / base_freq[base]);
|
|
267
|
+
llr_sum += llr
|
|
268
|
+
j_tmp = llr_sum / motif_len
|
|
269
|
+
return j_tmp
|
|
270
|
+
|
|
271
|
+
def predict_tfbs(file, motif_name, motif, data_dim, model, base_freq, out_file):
|
|
272
|
+
fasta, seq_freq = read_fasta(file)
|
|
273
|
+
# print(len(fasta))
|
|
274
|
+
motif_len = int(data_dim[0] / 5)
|
|
275
|
+
fp = open(out_file, 'w')
|
|
276
|
+
for seq_name in fasta.keys():
|
|
277
|
+
seq = fasta[seq_name].upper()
|
|
278
|
+
if has_non_acgtn_upper(seq):
|
|
279
|
+
continue
|
|
280
|
+
data_onehot, poss, j_tmps = seq2onehot(seq, motif_len, motif, base_freq)
|
|
281
|
+
data = torch.tensor(data_onehot)
|
|
282
|
+
data = data.view(-1, data_dim[0])
|
|
283
|
+
logits = model(data).flatten().tolist()
|
|
284
|
+
#indices = torch.nonzero(logits > 0.5, as_tuple=False).squeeze().tolist()
|
|
285
|
+
#indices = torch.nonzero(logits[:, 1] > logits[:, 0], as_tuple=False)
|
|
286
|
+
#indices = [i for i, value in enumerate(logits) if value > 0.5]
|
|
287
|
+
for vi in range(len(logits)):
|
|
288
|
+
if logits[vi] > 0.5:
|
|
289
|
+
value = vi
|
|
290
|
+
match_seq = seq[poss[value]: poss[value] + motif_len]
|
|
291
|
+
fp.write('\t'.join([seq_name, str(poss[value]), match_seq, str(j_tmps[value]), str(logits[value])]) + '\n')
|
|
292
|
+
fp.close()
|
|
293
|
+
|
|
294
|
+
def load_module(file):
|
|
295
|
+
saved_data = torch.load(file)
|
|
296
|
+
base_freq = saved_data['base_freq']
|
|
297
|
+
data_dim = saved_data['data_dim']
|
|
298
|
+
w1 = saved_data['w1']
|
|
299
|
+
b1 = saved_data['b1']
|
|
300
|
+
w2 = saved_data['w2']
|
|
301
|
+
b2 = saved_data['b2']
|
|
302
|
+
w3 = saved_data['w3']
|
|
303
|
+
b3 = saved_data['b3']
|
|
304
|
+
parameters = {'jpar': [base_freq, data_dim], 'model': [w1, b1, w2, b2, w3, b3]}
|
|
305
|
+
return parameters
|
|
306
|
+
|
|
307
|
+
def read_motif_cmp(file):
|
|
308
|
+
motif_cmp = {}
|
|
309
|
+
for line in open(file, 'r'):
|
|
310
|
+
if line[0: 3] != 'Cmp':
|
|
311
|
+
continue
|
|
312
|
+
lblocks = line.rstrip().split(' ')
|
|
313
|
+
motif_cmp[lblocks[1]] = lblocks[2]
|
|
314
|
+
return motif_cmp
|
|
315
|
+
|
|
316
|
+
def loade_model_pars(model_file, data_dim):
|
|
317
|
+
# 加载模型参数
|
|
318
|
+
# 首先需要创建相同结构的模型
|
|
319
|
+
global x_dimention
|
|
320
|
+
global optimizer
|
|
321
|
+
model_pars = torch.load(model_file)
|
|
322
|
+
#seq_freq = model_pars['base_freq']
|
|
323
|
+
#data_dim = model_pars['data_dim']
|
|
324
|
+
#del model_pars['base_freq']
|
|
325
|
+
#del model_pars['data_dim']
|
|
326
|
+
x_dimention = data_dim[0]
|
|
327
|
+
y_dimention = data_dim[1]
|
|
328
|
+
# 1. 定义模型
|
|
329
|
+
model = nn.Sequential(
|
|
330
|
+
nn.Linear(x_dimention, 64),
|
|
331
|
+
nn.ReLU(),
|
|
332
|
+
nn.Linear(64, 32),
|
|
333
|
+
nn.ReLU(),
|
|
334
|
+
nn.Linear(32, 1),
|
|
335
|
+
nn.Sigmoid()
|
|
336
|
+
)
|
|
337
|
+
model.load_state_dict(model_pars)
|
|
338
|
+
#new_model.eval()
|
|
339
|
+
return model
|
|
340
|
+
|
|
341
|
+
def script(motif_id, model_id, seq_file, out_file, data_dir=None):
|
|
342
|
+
if data_dir == None:
|
|
343
|
+
data_dir = PyTFBS_data_dir
|
|
344
|
+
if not (os.path.exists(data_dir) and os.path.isdir(data_dir)):
|
|
345
|
+
print("PyTFBS_data folder can not found!")
|
|
346
|
+
exit(1)
|
|
347
|
+
motif_file = data_dir + '/motif/' + motif_id + '.pwm'
|
|
348
|
+
model_file = data_dir + '/par/' + model_id + '_par.pth'
|
|
349
|
+
if not os.path.exists(motif_file):
|
|
350
|
+
print(motif_file, 'not exist!')
|
|
351
|
+
exit(1)
|
|
352
|
+
if not os.path.exists(model_file):
|
|
353
|
+
print(model_file, 'not exist!')
|
|
354
|
+
exit(1)
|
|
355
|
+
if not os.path.exists(seq_file):
|
|
356
|
+
print(seq_file, 'not exist!')
|
|
357
|
+
exit(1)
|
|
358
|
+
motif_name, motif = read_motif_single(motif_file)
|
|
359
|
+
data_dim = [len(motif) * 5, 1]
|
|
360
|
+
model = loade_model_pars(model_file, data_dim)
|
|
361
|
+
# run predict
|
|
362
|
+
fasta, seq_freq = read_fasta(seq_file)
|
|
363
|
+
# seq_freq = [0.22698189046475983, 0.2685381453335145, 0.2744548727333858, 0.22957776564437835, 0.00044732582396156444]
|
|
364
|
+
motif_len = len(motif)
|
|
365
|
+
fp = open(out_file, 'w')
|
|
366
|
+
seq_n = len(fasta)
|
|
367
|
+
finished_n = 0
|
|
368
|
+
for seq_name in fasta.keys():
|
|
369
|
+
seq = fasta[seq_name].upper()
|
|
370
|
+
if has_non_acgtn_upper(seq):
|
|
371
|
+
continue
|
|
372
|
+
data_onehot, poss, j_tmps = seq2onehot(seq, motif_len, motif, seq_freq)
|
|
373
|
+
data = torch.tensor(data_onehot)
|
|
374
|
+
data = data.view(-1, data_dim[0])
|
|
375
|
+
logits = model(data).flatten().tolist()
|
|
376
|
+
#indices = torch.nonzero(logits > 0.5, as_tuple=False).squeeze().tolist()
|
|
377
|
+
#indices = torch.nonzero(logits[:, 1] > logits[:, 0], as_tuple=False)
|
|
378
|
+
#indices = [i for i, value in enumerate(logits) if value > 0.5]
|
|
379
|
+
for vi in range(len(logits)):
|
|
380
|
+
if logits[vi] > 0.5:
|
|
381
|
+
value = vi
|
|
382
|
+
match_seq = seq[poss[value]: poss[value] + motif_len]
|
|
383
|
+
fp.write('\t'.join([seq_name, str(poss[value]), match_seq, str(j_tmps[value]), str(logits[value])]) + '\n')
|
|
384
|
+
finished_n += 1
|
|
385
|
+
if finished_n % 100 == 0 or finished_n == seq_n:
|
|
386
|
+
print(str(finished_n) + '/' + str(seq_n))
|
|
387
|
+
fp.close()
|
|
388
|
+
|
|
389
|
+
def win_bin(motif_id, model_id, seq_file, thread_n, out_file, data_dir=None):
|
|
390
|
+
if data_dir == None:
|
|
391
|
+
data_dir = PyTFBS_data_dir
|
|
392
|
+
if not (os.path.exists(data_dir) and os.path.isdir(data_dir)):
|
|
393
|
+
print("PyTFBS_data folder can not found!")
|
|
394
|
+
exit(1)
|
|
395
|
+
motif_file = data_dir + '/motif/' + motif_id + '.pwm'
|
|
396
|
+
model_file = data_dir + '/trace/' + model_id + '_trace.pth'
|
|
397
|
+
PyTFBS_exe = data_dir + '/PyTFBS_bin/PyTFBS.exe'
|
|
398
|
+
if not os.path.exists(motif_file):
|
|
399
|
+
print(motif_file, 'not exist!')
|
|
400
|
+
exit(1)
|
|
401
|
+
if not os.path.exists(model_file):
|
|
402
|
+
print(model_file, 'not exist!')
|
|
403
|
+
exit(1)
|
|
404
|
+
if not os.path.exists(seq_file):
|
|
405
|
+
print(seq_file, 'not exist!')
|
|
406
|
+
exit(1)
|
|
407
|
+
cmd = '\"' + PyTFBS_exe + '\" -m ' + motif_file + ' -z ' + model_file + ' -i ' + seq_file + ' -t ' + str(thread_n) + ' -o ' + out_file + ''
|
|
408
|
+
cmd = cmd.replace('/', '\\')
|
|
409
|
+
print(cmd)
|
|
410
|
+
os.system(cmd)
|
|
411
|
+
|
|
412
|
+
if __name__ == '__main__':
|
|
413
|
+
script('CEBPB_HUMAN.H11MO.0.A', 'CEBPB_HUMAN.H11MO.0.A_1231', 'GCF_000001405.40_GRCh38.p14_promoter_1.1k.txt', 'out_file.txt')
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: PyTFBS
|
|
3
|
+
Version: 1.0.2
|
|
4
|
+
Summary: PyTFBS: A Python Package for Transcription Factor Binding Site Prediction
|
|
5
|
+
Author-email: Tinghua Huang <thua45@126.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/thua45/pytfbs
|
|
8
|
+
Project-URL: Documentation, https://github.com/thua45/pytfbs#readme
|
|
9
|
+
Project-URL: Repository, https://github.com/thua45/pytfbs
|
|
10
|
+
Project-URL: Issues, https://github.com/thua45/pytfbs/issues
|
|
11
|
+
Keywords: PyTFBS,Transcription Factor,Binding Site
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Requires-Python: >=3.11
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
License-File: LICENSE
|
|
20
|
+
Requires-Dist: torch
|
|
21
|
+
Requires-Dist: numpy==1.26; sys_platform == "darwin"
|
|
22
|
+
Requires-Dist: numpy>=2.0; sys_platform == "win32"
|
|
23
|
+
Requires-Dist: numpy>=2.0; sys_platform == "linux"
|
|
24
|
+
Provides-Extra: dev
|
|
25
|
+
Requires-Dist: matplotlib; extra == "dev"
|
|
26
|
+
Provides-Extra: test
|
|
27
|
+
Requires-Dist: matplotlib; extra == "test"
|
|
28
|
+
Dynamic: license-file
|
|
29
|
+
|
|
30
|
+
# PyTFBS
|
|
31
|
+
|
|
32
|
+
A Python package for dpredicting transcription factor binding sites.
|
|
33
|
+
|
|
34
|
+
## Installation
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pip install torch numpy PyTFBS
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Usage
|
|
41
|
+
|
|
42
|
+
```python
|
|
43
|
+
from PyTFBS import motif, predict
|
|
44
|
+
|
|
45
|
+
# download PyTFBS data, only need to run once!!!
|
|
46
|
+
motif.download_data()
|
|
47
|
+
|
|
48
|
+
# list available models
|
|
49
|
+
motif.list_models(species='Homo sapiens', accuracy=0.9, sensitivity=0.9)
|
|
50
|
+
|
|
51
|
+
# get avaiable motifs
|
|
52
|
+
motifs = motif.get_motifs(species='Homo sapiens', accuracy=0.9, sensitivity=0.9)
|
|
53
|
+
print(motifs)
|
|
54
|
+
|
|
55
|
+
# get models based on motif name
|
|
56
|
+
models = motif.get_models('RFX2_HUMAN.H11MO.0.A')
|
|
57
|
+
print(models)
|
|
58
|
+
|
|
59
|
+
# predict one model
|
|
60
|
+
predict.script('CEBPB_HUMAN.H11MO.0.A', 'CEBPB_HUMAN.H11MO.0.A_1231', 'input_seq_file.fasta', 'out_file.txt')
|
|
61
|
+
|
|
62
|
+
# speed up using mutil-threading (for Windows OS only)
|
|
63
|
+
predict.win_bin('CEBPB_HUMAN.H11MO.0.A', 'CEBPB_HUMAN.H11MO.0.A_1231', 'input_seq_file.fasta', 64, 'out_file.txt')
|
|
64
|
+
|
|
65
|
+
# run prediction with user motif data
|
|
66
|
+
# the my_motif_dir should be organized as [[motif], [trace], [par]]
|
|
67
|
+
predict.script('CEBPB_HUMAN.H11MO.0.A', 'CEBPB_HUMAN.H11MO.0.A_1231', 'input_seq_file.fasta', data_dir='my_motif_dir')
|
|
68
|
+
predict.win_bin('CEBPB_HUMAN.H11MO.0.A', 'CEBPB_HUMAN.H11MO.0.A_1231', 'input_seq_file.fasta', 64, data_dir='my_motif_dir')
|
|
69
|
+
```
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
PyTFBS/__init__.py
|
|
5
|
+
PyTFBS/motif.py
|
|
6
|
+
PyTFBS/predict.py
|
|
7
|
+
PyTFBS.egg-info/PKG-INFO
|
|
8
|
+
PyTFBS.egg-info/SOURCES.txt
|
|
9
|
+
PyTFBS.egg-info/dependency_links.txt
|
|
10
|
+
PyTFBS.egg-info/entry_points.txt
|
|
11
|
+
PyTFBS.egg-info/requires.txt
|
|
12
|
+
PyTFBS.egg-info/top_level.txt
|
pytfbs-1.0.2/README.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# PyTFBS
|
|
2
|
+
|
|
3
|
+
A Python package for dpredicting transcription factor binding sites.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install torch numpy PyTFBS
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
from PyTFBS import motif, predict
|
|
15
|
+
|
|
16
|
+
# download PyTFBS data, only need to run once!!!
|
|
17
|
+
motif.download_data()
|
|
18
|
+
|
|
19
|
+
# list available models
|
|
20
|
+
motif.list_models(species='Homo sapiens', accuracy=0.9, sensitivity=0.9)
|
|
21
|
+
|
|
22
|
+
# get avaiable motifs
|
|
23
|
+
motifs = motif.get_motifs(species='Homo sapiens', accuracy=0.9, sensitivity=0.9)
|
|
24
|
+
print(motifs)
|
|
25
|
+
|
|
26
|
+
# get models based on motif name
|
|
27
|
+
models = motif.get_models('RFX2_HUMAN.H11MO.0.A')
|
|
28
|
+
print(models)
|
|
29
|
+
|
|
30
|
+
# predict one model
|
|
31
|
+
predict.script('CEBPB_HUMAN.H11MO.0.A', 'CEBPB_HUMAN.H11MO.0.A_1231', 'input_seq_file.fasta', 'out_file.txt')
|
|
32
|
+
|
|
33
|
+
# speed up using mutil-threading (for Windows OS only)
|
|
34
|
+
predict.win_bin('CEBPB_HUMAN.H11MO.0.A', 'CEBPB_HUMAN.H11MO.0.A_1231', 'input_seq_file.fasta', 64, 'out_file.txt')
|
|
35
|
+
|
|
36
|
+
# run prediction with user motif data
|
|
37
|
+
# the my_motif_dir should be organized as [[motif], [trace], [par]]
|
|
38
|
+
predict.script('CEBPB_HUMAN.H11MO.0.A', 'CEBPB_HUMAN.H11MO.0.A_1231', 'input_seq_file.fasta', data_dir='my_motif_dir')
|
|
39
|
+
predict.win_bin('CEBPB_HUMAN.H11MO.0.A', 'CEBPB_HUMAN.H11MO.0.A_1231', 'input_seq_file.fasta', 64, data_dir='my_motif_dir')
|
|
40
|
+
```
|
|
@@ -4,28 +4,27 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "PyTFBS"
|
|
7
|
-
version = "1.0.
|
|
7
|
+
version = "1.0.2"
|
|
8
|
+
license = "MIT" # SPDX expression
|
|
8
9
|
description = "PyTFBS: A Python Package for Transcription Factor Binding Site Prediction"
|
|
9
10
|
readme = "README.md"
|
|
10
|
-
requires-python = ">=3.
|
|
11
|
+
requires-python = ">=3.11"
|
|
11
12
|
authors = [
|
|
12
13
|
{name = "Tinghua Huang", email = "thua45@126.com"}
|
|
13
14
|
]
|
|
14
|
-
license = {text = "Acdemic"}
|
|
15
15
|
keywords = ["PyTFBS", "Transcription Factor", "Binding Site"]
|
|
16
16
|
classifiers = [
|
|
17
17
|
"Development Status :: 4 - Beta",
|
|
18
18
|
"Intended Audience :: Developers",
|
|
19
|
-
"License :: OSI Approved :: MIT License",
|
|
20
|
-
"Programming Language :: Python :: 3",
|
|
21
|
-
"Programming Language :: Python :: 3.8",
|
|
22
|
-
"Programming Language :: Python :: 3.9",
|
|
23
|
-
"Programming Language :: Python :: 3.10",
|
|
24
19
|
"Programming Language :: Python :: 3.11",
|
|
20
|
+
"Programming Language :: Python :: 3.12",
|
|
21
|
+
"Programming Language :: Python :: 3.13",
|
|
25
22
|
]
|
|
26
23
|
dependencies = [
|
|
27
|
-
"
|
|
28
|
-
"numpy
|
|
24
|
+
"torch",
|
|
25
|
+
"numpy==1.26; sys_platform == 'darwin'",
|
|
26
|
+
"numpy>=2.0; sys_platform == 'win32'",
|
|
27
|
+
"numpy>=2.0; sys_platform == 'linux'",
|
|
29
28
|
]
|
|
30
29
|
|
|
31
30
|
[project.urls]
|
|
@@ -36,18 +35,17 @@ Issues = "https://github.com/thua45/pytfbs/issues"
|
|
|
36
35
|
|
|
37
36
|
[project.optional-dependencies]
|
|
38
37
|
dev = [
|
|
39
|
-
"
|
|
38
|
+
"matplotlib",
|
|
40
39
|
]
|
|
41
40
|
test = [
|
|
42
|
-
"
|
|
41
|
+
"matplotlib",
|
|
43
42
|
]
|
|
44
43
|
|
|
45
44
|
[project.scripts]
|
|
46
45
|
PyTFBS = "PyTFBS.cli:main"
|
|
46
|
+
PyTFBS-cleanup = "PyTFBS.uninstall:cleanup"
|
|
47
47
|
|
|
48
48
|
[tool.setuptools]
|
|
49
|
-
packages =
|
|
50
|
-
package-
|
|
49
|
+
packages = ["PyTFBS"]
|
|
50
|
+
package-data = {"*" = ["*.txt", "*.md", "*.rst", "data/*"]}
|
|
51
51
|
|
|
52
|
-
[tool.setuptools.package-data]
|
|
53
|
-
mypackage = ["*.txt", "*.json", "data/*", "templates/*"]
|
pytfbs-1.0.0/PKG-INFO
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: PyTFBS
|
|
3
|
-
Version: 1.0.0
|
|
4
|
-
Summary: PyTFBS: A Python Package for Transcription Factor Binding Site Prediction
|
|
5
|
-
Author-email: Tinghua Huang <thua45@126.com>
|
|
6
|
-
License: Acdemic
|
|
7
|
-
Project-URL: Homepage, https://github.com/thua45/pytfbs
|
|
8
|
-
Project-URL: Documentation, https://github.com/thua45/pytfbs#readme
|
|
9
|
-
Project-URL: Repository, https://github.com/thua45/pytfbs
|
|
10
|
-
Project-URL: Issues, https://github.com/thua45/pytfbs/issues
|
|
11
|
-
Keywords: PyTFBS,Transcription Factor,Binding Site
|
|
12
|
-
Classifier: Development Status :: 4 - Beta
|
|
13
|
-
Classifier: Intended Audience :: Developers
|
|
14
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
-
Classifier: Programming Language :: Python :: 3
|
|
16
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
18
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
-
Requires-Python: >=3.8
|
|
21
|
-
Description-Content-Type: text/markdown
|
|
22
|
-
License-File: LICENSE
|
|
23
|
-
Requires-Dist: requests>=2.25.0
|
|
24
|
-
Requires-Dist: numpy>=1.21.0
|
|
25
|
-
Provides-Extra: dev
|
|
26
|
-
Requires-Dist: pytest>=6.0; extra == "dev"
|
|
27
|
-
Provides-Extra: test
|
|
28
|
-
Requires-Dist: pytest>=6.0; extra == "test"
|
|
29
|
-
Dynamic: license-file
|
|
30
|
-
|
|
31
|
-
# My Package
|
|
32
|
-
|
|
33
|
-
A Python package for dpredicting transcription factor binding sites.
|
|
34
|
-
|
|
35
|
-
## Installation
|
|
36
|
-
|
|
37
|
-
```bash
|
|
38
|
-
pip install PyTFBS
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
## Usage
|
|
42
|
-
|
|
43
|
-
```python
|
|
44
|
-
import PyTFBS
|
|
45
|
-
|
|
46
|
-
result = PyTFBS.predict()
|
|
47
|
-
print(result)
|
|
48
|
-
```
|
pytfbs-1.0.0/README.md
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
# My Package
|
|
2
|
-
|
|
3
|
-
A Python package for dpredicting transcription factor binding sites.
|
|
4
|
-
|
|
5
|
-
## Installation
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
pip install PyTFBS
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
## Usage
|
|
12
|
-
|
|
13
|
-
```python
|
|
14
|
-
import PyTFBS
|
|
15
|
-
|
|
16
|
-
result = PyTFBS.predict()
|
|
17
|
-
print(result)
|
|
18
|
-
```
|
pytfbs-1.0.0/src/PyTFBS/tango.py
DELETED
|
File without changes
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: PyTFBS
|
|
3
|
-
Version: 1.0.0
|
|
4
|
-
Summary: PyTFBS: A Python Package for Transcription Factor Binding Site Prediction
|
|
5
|
-
Author-email: Tinghua Huang <thua45@126.com>
|
|
6
|
-
License: Acdemic
|
|
7
|
-
Project-URL: Homepage, https://github.com/thua45/pytfbs
|
|
8
|
-
Project-URL: Documentation, https://github.com/thua45/pytfbs#readme
|
|
9
|
-
Project-URL: Repository, https://github.com/thua45/pytfbs
|
|
10
|
-
Project-URL: Issues, https://github.com/thua45/pytfbs/issues
|
|
11
|
-
Keywords: PyTFBS,Transcription Factor,Binding Site
|
|
12
|
-
Classifier: Development Status :: 4 - Beta
|
|
13
|
-
Classifier: Intended Audience :: Developers
|
|
14
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
-
Classifier: Programming Language :: Python :: 3
|
|
16
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
18
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
-
Requires-Python: >=3.8
|
|
21
|
-
Description-Content-Type: text/markdown
|
|
22
|
-
License-File: LICENSE
|
|
23
|
-
Requires-Dist: requests>=2.25.0
|
|
24
|
-
Requires-Dist: numpy>=1.21.0
|
|
25
|
-
Provides-Extra: dev
|
|
26
|
-
Requires-Dist: pytest>=6.0; extra == "dev"
|
|
27
|
-
Provides-Extra: test
|
|
28
|
-
Requires-Dist: pytest>=6.0; extra == "test"
|
|
29
|
-
Dynamic: license-file
|
|
30
|
-
|
|
31
|
-
# My Package
|
|
32
|
-
|
|
33
|
-
A Python package for dpredicting transcription factor binding sites.
|
|
34
|
-
|
|
35
|
-
## Installation
|
|
36
|
-
|
|
37
|
-
```bash
|
|
38
|
-
pip install PyTFBS
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
## Usage
|
|
42
|
-
|
|
43
|
-
```python
|
|
44
|
-
import PyTFBS
|
|
45
|
-
|
|
46
|
-
result = PyTFBS.predict()
|
|
47
|
-
print(result)
|
|
48
|
-
```
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
LICENSE
|
|
2
|
-
README.md
|
|
3
|
-
pyproject.toml
|
|
4
|
-
src/PyTFBS/__init__.py
|
|
5
|
-
src/PyTFBS/tango.py
|
|
6
|
-
src/PyTFBS.egg-info/PKG-INFO
|
|
7
|
-
src/PyTFBS.egg-info/SOURCES.txt
|
|
8
|
-
src/PyTFBS.egg-info/dependency_links.txt
|
|
9
|
-
src/PyTFBS.egg-info/entry_points.txt
|
|
10
|
-
src/PyTFBS.egg-info/requires.txt
|
|
11
|
-
src/PyTFBS.egg-info/top_level.txt
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|