- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 570814 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 176467
- 相册
- 1
- 日志
- 0
- 记录
- 0
- 帖子
- 5313
- 主题
- 5273
- 精华
- 3
- 分享
- 0
- 好友
- 163
TA的每日心情 | 开心 2021-8-11 17:59 |
|---|
签到天数: 17 天 [LV.4]偶尔看看III 网络挑战赛参赛者 网络挑战赛参赛者 - 自我介绍
- 本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。
 群组: 2018美赛大象算法课程 群组: 2018美赛护航培训课程 群组: 2019年 数学中国站长建 群组: 2019年数据分析师课程 群组: 2018年大象老师国赛优 |
基因组测序模拟
, @( m) Z6 R, B9 y基因组测序模拟7 E- i5 N m( ?
1 }/ {; j5 T8 D3 `7 X
一、摘要0 P0 m' L6 l$ U7 x9 @7 v
; r1 X, h4 F9 Q5 R: Q% g4 j
通过熟悉已有的基因组测序模拟和评估程序,加深全基因组鸟枪法测序原理的理解,并且能够编写程序模拟全基因组鸟枪法测序,理解覆盖度、测序深度、拷贝数等概念,设置测序相关参数,生成单端/双端测序结果文件
+ ~3 m, O7 B% E/ V( m6 }# ^: ?4 ^1 e& P2 {: ?/ ^$ ]$ p
二、材料和方法
# a4 U+ r7 S: Y5 r6 J b' B2 Y5 ^7 |9 u$ e
1、硬件平台% y W/ ], \! E2 j5 C! C
: o( \* t& c8 {+ ? D$ G
处理器:Intel(R) Core(TM)i7-4710MQ CPU @ 2.50GHz
$ s* i7 V( I+ M% t7 N4 X安装内存(RAM):16.0GB
! @) q+ i, q* q8 B9 F& p2 a j3 w3 r' _* I$ a, T8 W$ F& O
2、系统平台
5 m2 n# c& D1 }5 Z* m& \$ x, }Windows 8.1,Ubuntu" i1 S* a) V) z# [# S2 c# J
+ C7 o- E3 d7 Z2 Z/ x
3、软件平台) P$ T! d2 R2 T7 \/ Y3 ?( G2 \
7 J8 {6 l% s: ?) r w
art_454
3 o% V" v2 U$ PGenomeABC http://crdd.osdd.net/raghava/genomeabc/2 o9 F9 S9 S0 a
Python3.5- l. I# T2 ]9 U* d; X
Biopython5 D1 b" c1 p: ^5 k
4、数据库资源0 A: x& \5 T. F9 M1 M5 b
h& K0 p1 [* [3 U5 YNCBI数据库:https://www.ncbi.nlm.nih.gov/0 h8 K& m+ u' {5 h: E: k- h$ }
' `* W# M7 w1 w/ N d, Z& |* N5、研究对象
2 L) I" X- w- X% @
$ V& J9 d9 u( @8 n; Z- k0 [酵母基因组Saccharomyces cerevisiae S288c (assembly R64)
( q( D; z7 L3 L& v vftp://ftp.ncbi.nlm.nih.gov/genomes/all/GCF/000/146/045/GCF_000146045.2_R64/GCF_000146045.2_R64_genomic.fna.gz
3 G& g& d$ k0 M8 w
$ }, T; q6 h9 D% ]6、方法0 U% A+ V( n& n$ l2 `5 W
8 ]3 _, |" [) W% h, Hart_454的使用
/ l, _7 O1 L- v' y0 G首先至art系列软件的官网,下载软件,在ubuntu系统安装,然后阅读相关参数设置的帮助文档,运行程序。
) X! _' i1 S; m8 fGenomeABC : ?& C" @" h' i3 ^3 i+ v
进入GenomeABC(http://crdd.osdd.net/raghava/genomeabc/),输入参数,获得模拟测序结果。
4 q; z( B+ W( w7 t6 X3 H编程模拟测序 ! _; z# D9 L- P7 a0 \( f4 R: i
下载安装python,并且安装biopython扩展模块,编写程序,模拟单端/双端测序。
# ^" L, m1 i4 w' o v; g三、结果
: T6 A7 d3 P5 C+ I) M9 ^+ v* N a4 P# L) K0 l& L
1、art_454的运行结果
, {& z; m+ {. Y$ q, n% C
1 B9 w+ f0 `! l无参数art_454运行,阅读帮助文档 ; |) M2 i( w+ {1 m' q: T/ u1 m
, a% ^$ @( e7 }4 b; [图表 1无参数art_454运行
% K* ~1 V+ p' S8 _对酵母基因组进行基因组单端测序模拟,FOLD_COVERAGE设为20,即覆盖度为20. . f8 C1 g, t4 D* A, t. S3 L0 w, a
下图为模拟单端测序,程序运行过程及结果
+ j$ r# M& F. O; G5 f: Z
! q+ ]) b" C ~5 |! d5 {& E图表 2 art454单端测序
: ?& I* W" ~1 N% K* T, u ~6 z, Q
$ h& U5 |" u; ?# m5 |% @图表 3 art454单端模拟结果 % H# u6 d) K+ ?) O+ w: Z7 G
双端测序模拟,FOLD_COVERAGE设为20,即覆盖度为20;MEAN_FRAG_LEN设为1500,即平均片段长度为1500;STD_DEV设为20,即长度的标准差为20
4 d5 ]# Y9 T8 t) G1 S下图为模拟双端测序,程序运行过程及结果
, T$ H3 @/ U0 t4 q/ ~4 a5 D
G. d* W* N: p: \ P; @8 s图表 4 art454双端测序
. q% ~! P" c. \3 T: i" \
" v8 Q3 q$ [# C8 C8 o$ I, W图表 5 art454双端模拟结果 7 W% _ v# p0 P+ H9 V
2、GenomeABC
! ?# a( Z2 c/ ^5 W下图为设置参数页面 & n* F* R4 P, q( W: n0 ~* B. r: l5 s; r
5 A' N- y5 B; X; n9 B) b2 M下图为结果下载页面 8 w, d9 P0 b! {7 |4 Y
8 Z3 g& m! d: k$ Q' w2 d! b) Q图表 6 结果下载页面 / P% J9 \: c0 e% C$ } f
3、编程模拟测序结果
8 ?7 B! @' f( X4 O' L* M拷贝数是这里的N值;覆盖度是m,测序深度是宏观的量,在这里与覆盖度意思相同,就是测序仪10X,20X。
) ]- Y9 r4 d0 x9 h- G' {7 j单端测序 / }- c9 K4 ?* c" v, c2 U& j
+ ~5 Q* a r, U/ v, p, m: t
图表 7 程序模拟单端测序
. X B7 l; J: G& D1 Y# j5 ]双端测序 5 v3 W3 T. B! u8 @, ~# a6 A
% K2 S) c) h s7 A4 ?" V, u
图表 8 程序模拟双端测序
) t: K7 T" f! w8 T测序结果 ' [' p3 {9 a; J m% d, Y
5 O; m2 k( E0 ^. o, X- \/ z& N图表 9 结果文件, ]. \) g$ S7 W6 J7 {" S2 W
9 H- S+ ]0 f0 q7 W5 b' m8 ~3 W! s
因为期望片段长度是600bp,在片段长度区间200-1000bp内,所以大部分的片段都没有删除。 $ n( T |5 i1 ^7 X+ N
测序结果统计表
* J6 y6 B2 u6 f2 { `
1 K' N1 K7 |1 s8 P9 ~) B( h测序方式 基因组大小(bp) 片段长度区间 (bp) N值 期望片段长度 克隆保留率 片段数量 Reads长度范围(bp) Reads总数量 Reads总长度 覆盖度(m值) 理论丢失率(e-m) 覆盖率(1-e-m)8 F" c; ]: b5 |: Z- Q8 d
单端 12157kb 200-1000 10 600 0.95 107378 50-100 101968 7645.541kb 0.62889 0.53318 0.466827 D7 }; h; o! J- p
单端 12157kb 200-1000 20 600 0.95 213722 50-100 202996 15227.882kb 1.25259 0.28576 0.71424
|( m, M& P% D双端 12157kb 200-1000 10 600 0.95 106704 50-100 202770 15212.662kb 1.25134 0.28612 0.71388' a% f1 _# t: F/ W3 M/ L
双端 12157kb 200-1000 20 600 0.95 214212 50-100 407186 30534.265kb 2.51164 0.08114 0.91886
3 C7 q2 q6 w4 `/ X v四、讨论和结论4 q" k# w# Z) z8 V7 R5 B$ j+ N. d
& r7 j6 i# O+ O3 e+ o; j; a$ U8 d
程序运行方法: f6 ]- `& E0 C0 B c* z* S+ |% C
; r9 A9 e8 R4 `& \8 d- I在类的构造方法init()中,调整参数。 * V) p2 Y) s7 ]+ m+ ?# K& l
Averagefragmentlength为片段平均的长度;
' L# O! e8 O4 y5 h/ c1 N, Pminfragmentlength和maxfragmentlength是保留片段的范围; + q7 X4 |) P# S7 m+ M3 P/ ~5 V2 e
cloneRetainprobability是克隆的保留率;
y& ^3 {/ T8 ?; X4 U- X, V- B' w1 z, dminreadslength和maxreadslength是测序reads的长度范围0 H; @1 {& T; U0 s8 b8 Z; a- l0 N
9 s/ G. l" A# R: V: v8 ^. ]
模拟测序的诸多方法都封装成了Sequencing类,只需要创建类,并调用singlereadsequencing()和pairreadsequencing()方法,传入文件名的参数即可。
0 O& t5 R% S6 t/ s( T7 I% E( Y# A6 V- Z# X( X
附录3 h# h1 S& D. ]! m% K3 w1 Z I
; F# a+ i% T6 \) D0 }
from Bio import SeqIO# _8 {& c* I( [9 t& h- V
from math import exp
9 x' |$ r" ^) N7 }7 yimport random) }4 }8 K3 O0 T
% H' \* P1 K3 A3 h3 ? v- P2 r2 iclass Sequencing:6 O6 v! J! M o8 T: S; `
# N代表拷贝份数
+ b9 T3 S. a, @7 s def __init__(self)/ o& ?; G! j0 O$ r$ b* N
self.fragmentList = []8 g0 C1 N% C9 L7 w+ A; b& X+ ?
self.readsID = 1) T# p9 o5 Y) H* ?6 ^% V
self.readsList = [], q# v. V! p5 u( e5 T8 [" K
self.averagefragmentlength = 650! f4 c* |5 g+ i# r: M9 ?* J
self.minfragmentlength = 500
6 E* H* T* F* g- M( C self.maxfragmentlength = 800" a: m, c8 g) E% {5 {
self.cloneRetainprobability = 1" I- k( n+ U* W' V7 m
self.minreadslength = 50
/ ^2 m6 m7 k l self.maxreadslength = 150' z) K8 A! O. r$ K( x
self.N = 10
Z8 n3 `0 {6 X/ | self.genomeLength = 08 o. P; Z c+ T# @ B
self.allreadslength = 0
! T" k: p; N! u# G4 o' G1 P
* r9 ?+ n/ V7 R8 s' F& } # 生成断裂点
% i$ e' v; `1 W8 p# J2 z, ?6 {$ q1 x def generatebreakpoint(self, seqlen, averageLength):
* Q3 J1 X' `! G% J% K6 r9 J- n% I2 p* T # 假设平均每500bp 产生一个断裂点(averageLength = 500),通过随机函数生成seqlen/500个随机断裂点(1到seqlen之间的随机整数)5 `# D4 \* E. Z
breakpoint = [random.randint(0, seqlen) for _ in range(int(seqlen / averageLength))]6 Z7 M. B8 M& ^; K8 D/ ~4 k
breakpoint.append(seqlen)
* r) I" y! C4 T" `6 { breakpoint.append(0)
* t; |5 u5 B7 A0 t, `( P' _5 Y( T # 把随机断裂点从小到大排序
T5 G" q7 G) D3 p y# K0 R+ l breakpoint.sort()
, k7 V/ ^+ e/ \1 q0 D( n% @ return breakpoint
0 X7 ^8 E4 Z: } ~4 \0 @
; N! O. q: ~1 [) p8 a- p3 d # 沿断裂点打断基因组,并删除不符合长度要求的序列片段,定义片段范围:200-1000bp
* Z. w& j2 `! v9 n/ Y6 T) e def breakgenome(self, seq, breakpoint, minfragmentlength, maxfragmentlength):
' v- u; j! [. @ M: P1 ~, m, n# Y for i in range(len(breakpoint) - 1):
. ?1 E' U' i( j" Z& a5 B fragment = seq[breakpoint:breakpoint[i + 1]]
2 n* A) j$ X! d0 L, J0 X/ r if maxfragmentlength > len(fragment) > minfragmentlength:9 N, Z" Z) C- s$ Q: w$ g
self.fragmentList.append(fragment). y$ y/ l, r; k; F0 `
return self.fragmentList6 l* I+ A' S: Q' p; Q8 ^
1 E Q! v( ^* @4 V
# 模拟克隆时的随机丢失情况,random.random()生成0-1的保留概率
+ h* U. G& x7 s9 O, ~5 s& _0 S def clonefragment(self, fragmentList, cloneRetainprobability):5 z" j2 @* ^5 p. L8 H+ m: P
clonedfragmentList = []
( U% r- K a; S; M% [# m9 J Lossprobability = [random.random() for _ in range(len(fragmentList))]
& `; a# m! ]7 ?" M) w for i in range(len(fragmentList)):
( Y9 P5 I" @+ L6 Q# `* B# s if Lossprobability <= cloneRetainprobability:
+ H# q' o: f6 G7 ^- D clonedfragmentList.append(fragmentList)2 `( F5 P. a( i& M) d5 W
return clonedfragmentList9 b6 I) [% y( o0 }- d
" g- W/ _+ J) `7 z( q3 B/ Q% q
# 模拟单端测序,并修改reads的ID号
+ F, b/ k3 u+ _ def singleread(self, clonedfragmentList):
2 K0 e7 p* `& J for fragment in clonedfragmentList:
4 A' u0 B$ q; E) F2 R' `' V fragment.id = ""
_' L9 W# ^4 X9 M fragment.name = ""+ g. A* k. R0 w+ L0 R( u. L2 c
fragment.description = fragment.description[12:].split(",")[0]
2 i$ E( a! j8 c, h$ }0 M fragment.description = str(self.readsID) + "." + fragment.description
0 \4 d- p9 }/ ~4 e: G) ? self.readsID += 1
2 O; N$ H$ }$ I% U, D6 C readslength = random.randint(self.minreadslength, self.maxreadslength)( E7 u/ h5 {: Z4 A- v
self.allreadslength += readslength1 U% t8 @2 f' Z! s8 [
self.readsList.append(fragment[:readslength])& T: D3 [; e* ]: R' ^1 S
; K8 p! K: U9 a4 F" ] i
def singlereadsequencing(self, genomedata, sequencingResult):
. W/ C1 T% @+ O' u# f7 d. v for seq_record in SeqIO.parse(genomedata, "fasta"):1 u# @3 K; V5 p Z5 q! s" a" d
seqlen = len(seq_record)
1 c: |4 O( ?4 z% A( Z8 l1 T self.genomeLength += seqlen
% m. D1 I6 ]; |. K for i in range(self.N):
2 e: `( W- x" c0 O+ L # 生成断裂点% o4 K. r& @+ r# a1 t1 Y0 _2 k
breakpoint = self.generatebreakpoint(seqlen, self.averagefragmentlength)
' x6 l7 c5 }2 H4 A1 c. W) b # 沿断裂点打断基因组
9 N6 w& l$ ^) m self.breakgenome(seq_record, breakpoint, self.minfragmentlength, self.maxfragmentlength)
+ w: a) q [ N+ ^ # 模拟克隆时的随机丢失情况
" Q, S5 I/ @/ Y- [0 `8 N! J, G- f clonedfragmentList = self.clonefragment(self.fragmentList, self.cloneRetainprobability)
% T4 j, g0 j h/ v" p # 模拟单端测序
' Z% x( @/ m6 v' x i self.singleread(clonedfragmentList)6 w& I- k. g' _1 R6 T
SeqIO.write(self.readsList, sequencingResult, "fasta")' Y. R& _" c4 E
( W1 ?! n {! {4 i, D
def pairread(self, clonedfragmentList):% c7 d; e8 }! @4 z! b1 c
for fragment in clonedfragmentList:2 G7 A, b7 Q4 D3 c9 x a* t
fragment.id = ""% Q& q- J ^) X0 A8 `
fragment.name = ""
* @$ {4 D& _2 @2 S description = fragment.description[12:].split(",")[0]9 x `1 B) c% a- x/ @! R: p2 [/ e
fragment.description = str(self.readsID) + "." + description) |/ V7 G. h+ P( Q
readslength = random.randint(self.minreadslength, self.maxreadslength)
, E# _; `7 m' D5 ]' o9 X2 e self.allreadslength += readslength* c- E9 E2 n3 x! U7 C* K6 i$ p
self.readsList.append(fragment[:readslength])
; g- A( T3 t. J/ J: D
/ C; v6 c# M$ Q% c2 t! O readslength = random.randint(self.minreadslength, self.maxreadslength)* ] q9 z. z7 Q0 v1 E% \2 N8 e
self.allreadslength += readslength2 v4 q* Q1 [( O1 U5 @
- K+ V. | x8 ?) n- Q% n; @) Z; k+ d fragmentcomplement = fragment.reverse_complement()
* R8 K; e) f! N9 F2 m8 P fragmentcomplement.id = ""
% A8 ~7 x* z! _" f) y fragmentcomplement.name = ""
6 t- ?/ M( \5 M/ g5 s9 | fragmentcomplement.description = str(self.readsID) + "." + description8 \0 L/ I2 n9 ^& A. T
self.readsList.append(fragmentcomplement[:readslength])
. p6 o% G3 {+ x: s# K! P
) \; `9 o. l8 `% x! g. e' { self.readsID += 1* r6 J) _5 s! D0 D5 Q/ b. z7 b6 T, o
; i2 d. \; ?6 |5 P
def pairreadsequencing(self,genomedata, sequencingResult_1, sequencingResult_2):9 y r# B8 _; w1 u' j; G$ L" A3 {0 e
for seq_record in SeqIO.parse(genomedata, "fasta"):
: e% {8 Y2 P1 L e7 E+ g seqlen = len(seq_record)% B$ s) W7 V, E& S% o% R
self.genomeLength += seqlen% n, q9 @4 {( m
for i in range(self.N): F/ S( b$ J% e
# 生成断裂点- ~) j# S+ A" m, I; @9 P" g$ M
breakpoint = self.generatebreakpoint(seqlen, self.averagefragmentlength)8 R7 a" l( K; i# s: b
# 沿断裂点打断基因组1 [: k! ~* w4 y
self.breakgenome(seq_record, breakpoint, self.minfragmentlength, self.maxfragmentlength)
5 Z' t2 a) e2 _. ^' o! |2 e # 模拟克隆时的随机丢失情况
2 S, f9 h7 X' E$ y+ L clonedfragmentList = self.clonefragment(self.fragmentList, self.cloneRetainprobability)
7 a3 [+ @$ \2 y # 模拟双端测序
" H( `' B7 d. o; [! k self.pairread(clonedfragmentList)
% q6 g/ @1 z! v' R$ d readsList_1 = [self.readsList for i in range(len(self.readsList)) if i % 2 == 0]: G# o5 t, c+ X$ a) Z6 S, ~
readsList_2 = [self.readsList for i in range(len(self.readsList)) if i % 2 == 1]" k) J8 _1 X" E
SeqIO.write(readsList_1, sequencingResult_1, "fasta")2 c- u* D4 d9 z# Q P+ `
SeqIO.write(readsList_2, sequencingResult_2, "fasta")
& s3 \* N2 a" |) R
* B6 K0 R C$ f" g$ m% R def resultsummary(self):
& j: n M2 I1 b- l print("基因组长度:" + str(self.genomeLength / 1000) + "kb")( } ~( Y1 t$ Y+ f
print("片段长度区间:" + str(self.minfragmentlength) + "-" + str(self.maxfragmentlength))# \4 e4 o! ~1 \
print("N值:" + str(self.N)): G9 |1 t6 }/ Y- I
print("期望片段长度:" + str(self.averagefragmentlength))" v/ l) U, f6 F0 N0 S8 j
print("克隆保留率:" + str(self.cloneRetainprobability))
" o: P/ a) r9 f9 T9 o3 d print("片段数量:" + str(len(self.fragmentList)))6 n; s; Q7 R: Q$ Q
print("reads长度:" + str(self.minreadslength) + "-" + str(self.maxreadslength))
0 f4 P! O# A5 O print("reads总数量:" + str(len(self.readsList))): S% r) C8 C: \1 O! D9 H
print("reads总长度:" + str(self.allreadslength / 1000) + "kb") s/ ^8 u* a: F; r* e
m = self.allreadslength / self.genomeLength2 W; H* w1 w& Y+ o1 f, u/ L! y
print("覆盖度(m值):" + str(round(m, 5))). }5 P8 s. X$ F9 A, B4 c, R
print("理论丢失率(e^-m):" + str(round(exp(-m), 5)))+ N- m w* T0 _: x% Q
print("覆盖率(1-e^-m):" + str(round(1 - exp(-m), 5)))
- }- J( U, A& k' O- l# -------------------------------------------主程序-------------------------------------------
+ r) ~- a( J1 S/ }( r: e7 M2 J# 模拟单端测序
! {' f( V g- xsequencingObj = Sequencing(); e& k6 h! Y& R0 n, ?" X
sequencingObj.singlereadsequencing("data/NC_025452.fasta", "result/virusSingleRead.fa"); F3 B$ z( q% L. `8 |# Q1 k. j
sequencingObj.resultsummary()
! S* Q" T& l1 s# F! U* g' |
( q) N, V0 N& S# 模拟双端测序7 I; {, e: ?7 W9 I5 g
sequencingObj = Sequencing()
8 c1 f- h* S1 @# W- |sequencingObj.pairreadsequencing("data/GCF_000146045.2_R64_genomic.fna", "result/yeastPairRead_1.fa", "result/yeastPairRead_2.fa")
' w9 i2 u- e% o) H; rsequencingObj.resultsummary()2 f: f% M/ U, y# R& u
from Bio import SeqIO1 X; A& @3 h3 i' E( u6 m
from math import exp
* r3 T9 a2 X: C1 p9 Jimport random. q, K- M1 J6 ^ ]( {8 p d
# a6 r* F% \' K3 K$ jclass Sequencing:. x" Q4 o: p8 C7 ~" f
# N代表拷贝份数
% a7 B# X# M# y5 C def __init__(self):
" `2 }, t3 ?+ t) S4 r self.fragmentList = []
f! I7 O' r8 I) d2 h# H self.readsID = 1* Z1 R7 y% F: B" J# y
self.readsList = []
9 H5 o$ Y5 _; L: ] ^2 c5 j self.averagefragmentlength = 6509 R) l* o& \1 y# M
self.minfragmentlength = 5008 B' G# r0 y3 M8 z0 x9 m
self.maxfragmentlength = 8003 m/ a- K0 S. _" }! Z: N" C5 ~
self.cloneRetainprobability = 1/ a/ |4 E7 p. z5 x, X$ B! M
self.minreadslength = 50' w- u' k- `- e# e* E: H
self.maxreadslength = 150+ f. J" r/ ]8 ?% O
self.N = 10/ L* b- X) V1 T2 H
self.genomeLength = 09 k" @, E! @. R1 t/ E
self.allreadslength = 03 [/ M5 T9 w& D5 H' O8 g! l
. P+ y& u9 N8 {* {7 H! X; T # 生成断裂点 I3 d5 M! ]0 G. z# j: T, {0 ~/ L
def generatebreakpoint(self, seqlen, averageLength):
9 `8 q- B' Z/ t% `* U # 假设平均每500bp 产生一个断裂点(averageLength = 500),通过随机函数生成seqlen/500个随机断裂点(1到seqlen之间的随机整数)! w, E" j. ?4 s. s7 T# z
breakpoint = [random.randint(0, seqlen) for _ in range(int(seqlen / averageLength))]
8 ^1 [: r) h- w1 ^3 N8 v4 | breakpoint.append(seqlen)
( v2 ]) B$ B& L3 I- w9 v breakpoint.append(0). n) j6 I) Z/ |% Y
# 把随机断裂点从小到大排序, O. p4 a7 B* i; [
breakpoint.sort()6 X6 R0 G( V$ g/ X, w6 s; X
return breakpoint
! A. t- T# z5 d& b6 z7 b0 o
# N! [! e4 ~9 w1 y" y # 沿断裂点打断基因组,并删除不符合长度要求的序列片段,定义片段范围:200-1000bp5 k0 u% N& r0 A7 s5 O
def breakgenome(self, seq, breakpoint, minfragmentlength, maxfragmentlength):
$ z. c0 H% e# I1 T- J8 T" _ for i in range(len(breakpoint) - 1):
1 ?8 y* D+ s: X' G3 l/ p. |7 a8 w fragment = seq[breakpoint:breakpoint[i + 1]]) H+ ?# L' C7 b0 n
if maxfragmentlength > len(fragment) > minfragmentlength:5 C5 `4 A1 i# ]
self.fragmentList.append(fragment)* A7 _7 q! _, q$ C" i1 s8 F8 w6 R" R
return self.fragmentList$ [! S1 J+ Y- q; a$ L; [7 Q1 M
0 R, _7 c% T. ^4 E/ s2 H/ a
# 模拟克隆时的随机丢失情况,random.random()生成0-1的保留概率0 V m J3 V s, c' q4 Q, D/ S. y
def clonefragment(self, fragmentList, cloneRetainprobability):9 r0 |; b, }' B' T
clonedfragmentList = []+ I. R! M9 ~( o) m* F
Lossprobability = [random.random() for _ in range(len(fragmentList))]6 N3 H' ~, w" W( O8 r! M
for i in range(len(fragmentList)):
) q( Z% g- \5 N: x: } if Lossprobability <= cloneRetainprobability:
+ B$ _" v: @ H# p$ x clonedfragmentList.append(fragmentList)+ i2 E2 W% g n' K2 o
return clonedfragmentList
( {/ z; V5 t5 D
+ p. I+ X" c. O( q6 A' Z # 模拟单端测序,并修改reads的ID号
$ E# W2 i0 n8 S9 ~ def singleread(self, clonedfragmentList):( N9 m' V x5 v8 i& R" i8 A
for fragment in clonedfragmentList:5 Y8 }. i( Z1 a' z U* w
fragment.id = ""$ R# g, |: \: X( l: h/ y2 G$ r
fragment.name = ""7 ^% W0 c Y- p! b, Y4 Z `% i* |7 O
fragment.description = fragment.description[12:].split(",")[0]- T6 B8 S) Y1 E9 j- O3 @5 @- D
fragment.description = str(self.readsID) + "." + fragment.description
5 `: \2 E$ K: R! W self.readsID += 1! `" @( e4 d: W4 J$ t" R- X
readslength = random.randint(self.minreadslength, self.maxreadslength)
- P0 L4 q! h* L8 o2 @ self.allreadslength += readslength2 a9 z, }" v1 ]" l0 @
self.readsList.append(fragment[:readslength])7 Q5 }0 e7 R! q- [' g' E$ L. k
, b* Q5 p n0 j; |4 j/ ~
def singlereadsequencing(self, genomedata, sequencingResult):
1 s* U* z7 C8 C# @6 C9 w- X for seq_record in SeqIO.parse(genomedata, "fasta"):, ?7 w: V8 I: j) i
seqlen = len(seq_record)* x" I$ O6 G5 [2 q+ e' X. A* u
self.genomeLength += seqlen. e* I% J9 [# g6 w. R& j
for i in range(self.N):- d$ r* g& X7 r' L3 @1 y. ]9 {
# 生成断裂点6 Y" i$ ]3 \% r" n$ R6 I# x
breakpoint = self.generatebreakpoint(seqlen, self.averagefragmentlength)
' E. w& V0 t+ ? # 沿断裂点打断基因组+ r+ R% t7 v+ |; u/ D
self.breakgenome(seq_record, breakpoint, self.minfragmentlength, self.maxfragmentlength)" H! v$ p) B9 ]$ f% U0 Y, a9 @
# 模拟克隆时的随机丢失情况
! Q4 K7 a( Z) [5 W clonedfragmentList = self.clonefragment(self.fragmentList, self.cloneRetainprobability)
% ?3 `# X$ X0 u$ C% s0 {' p # 模拟单端测序' X1 s0 _1 x9 v$ A* B" x
self.singleread(clonedfragmentList)
9 s) `" ?+ v0 K' i5 } x4 G, q' S3 M SeqIO.write(self.readsList, sequencingResult, "fasta")
2 ^; b! v4 \* ?0 _9 t, A& q C# i
/ \- s5 e0 h0 U g) s- Y def pairread(self, clonedfragmentList):! [& ^/ v& g# y& {, ]) g% k& y
for fragment in clonedfragmentList:
2 q9 C, ^; v, N. ~( ? fragment.id = ""0 I1 d0 J! Q5 j" V1 a- h7 M
fragment.name = ""% N6 K' r$ T( \2 p( S! Q
description = fragment.description[12:].split(",")[0]9 T4 l: q0 r$ y$ e6 k9 H4 G
fragment.description = str(self.readsID) + "." + description! x5 J, h$ |8 G" Y! `8 @+ d
readslength = random.randint(self.minreadslength, self.maxreadslength)7 |+ ?; t; j* }6 J6 t
self.allreadslength += readslength; h1 }: `6 t& b
self.readsList.append(fragment[:readslength])
; R9 c3 u: a% T6 N+ Y, P5 b! n8 o% ?4 u( p; n' Q7 l, _) I
readslength = random.randint(self.minreadslength, self.maxreadslength)2 R) b4 f d1 ~* O
self.allreadslength += readslength
0 W8 z' x& h, m$ R, Q5 i, l: X3 B) U9 s" |. x
fragmentcomplement = fragment.reverse_complement()9 _) V* o8 O! L+ B X" A
fragmentcomplement.id = ""- o- e5 g* v$ X" h/ p
fragmentcomplement.name = ""
- D3 G7 t% E" B fragmentcomplement.description = str(self.readsID) + "." + description! ^+ P( h3 a$ P( J( ~& S
self.readsList.append(fragmentcomplement[:readslength])9 A2 @9 u6 m' j# D
7 b4 h. ]% e6 d$ h8 f: j% i self.readsID += 1
, c' a4 m; E7 P4 q/ R& r! ^* u4 d4 {) U
def pairreadsequencing(self,genomedata, sequencingResult_1, sequencingResult_2):" j8 E& R9 ~4 S+ t+ K
for seq_record in SeqIO.parse(genomedata, "fasta"):
3 n) T% f( c& _ seqlen = len(seq_record)
& m! ~1 ~1 ?( m self.genomeLength += seqlen: \/ ^. ?: T7 ^" |; D! m1 _
for i in range(self.N):
8 {# h9 i/ w( ? # 生成断裂点( z" ?' G# Z8 n# I! n+ [
breakpoint = self.generatebreakpoint(seqlen, self.averagefragmentlength)& L, ?. z, f1 m" s& Y' ?
# 沿断裂点打断基因组* i% }6 Q0 y" f; S }1 K& I/ N7 u9 C3 {9 T
self.breakgenome(seq_record, breakpoint, self.minfragmentlength, self.maxfragmentlength)
- u: U v5 p+ N/ i1 w% J # 模拟克隆时的随机丢失情况0 u, m, n: G) V: a, D
clonedfragmentList = self.clonefragment(self.fragmentList, self.cloneRetainprobability); S" @6 t; H5 B5 U1 d' t
# 模拟双端测序
; Y+ ~) c0 A! M+ c1 q& Z& @ self.pairread(clonedfragmentList)
4 j8 Q/ G6 D/ E" ^ readsList_1 = [self.readsList for i in range(len(self.readsList)) if i % 2 == 0]: W9 u: Q4 H. l7 E+ K* p
readsList_2 = [self.readsList for i in range(len(self.readsList)) if i % 2 == 1]
8 _) S* h( ]- R' _ SeqIO.write(readsList_1, sequencingResult_1, "fasta")
l) Y& n% {7 s9 I SeqIO.write(readsList_2, sequencingResult_2, "fasta")
1 j4 [$ H/ ^" \0 S8 { n9 Z' ?2 Z) Z+ F, W/ [3 {# p
def resultsummary(self):( f# D' g X0 c) ?& V; b$ o% [
print("基因组长度:" + str(self.genomeLength / 1000) + "kb")
9 S6 R7 H$ O2 p print("片段长度区间:" + str(self.minfragmentlength) + "-" + str(self.maxfragmentlength))
& N4 }2 x; l) |& C; Z) f print("N值:" + str(self.N))
- G, W' ]9 q7 ~0 ~& m+ ?: M print("期望片段长度:" + str(self.averagefragmentlength))7 ^/ \! Y' l0 r( J4 f
print("克隆保留率:" + str(self.cloneRetainprobability))
~& k+ v" k q' d print("片段数量:" + str(len(self.fragmentList)))
7 c( _8 f1 |* R0 f9 ~3 K% b print("reads长度:" + str(self.minreadslength) + "-" + str(self.maxreadslength))
" j0 R4 K9 {: i" I6 Z( Y print("reads总数量:" + str(len(self.readsList)))
7 S1 E% Y6 v( y print("reads总长度:" + str(self.allreadslength / 1000) + "kb")" h1 }+ n {& B3 F5 Z
m = self.allreadslength / self.genomeLength- d& e. X8 o. C8 _
print("覆盖度(m值):" + str(round(m, 5)))3 v {+ T% {3 C/ k
print("理论丢失率(e^-m):" + str(round(exp(-m), 5)))
3 b& j+ a- a& `, i8 z, ~" R$ V( C print("覆盖率(1-e^-m):" + str(round(1 - exp(-m), 5)))
8 S; H9 n! }) v! O" F! \# -------------------------------------------主程序-------------------------------------------% k# j: c R9 f& p/ W$ b
# 模拟单端测序4 z* ~4 m9 d: _- j! k
sequencingObj = Sequencing()" E2 o+ ?0 Z* F2 e6 Q& y9 g
sequencingObj.singlereadsequencing("data/NC_025452.fasta", "result/virusSingleRead.fa")" ?" e: p; U+ }+ \: j" P4 m, m
sequencingObj.resultsummary()* n( i9 v; |) D l/ h
' M! S3 e( W; A9 N- ?$ q1 h: |0 F# 模拟双端测序
. ?" G" U1 _4 ^# P7 E, t$ MsequencingObj = Sequencing()" F! E" n$ J' O' B. S' v
sequencingObj.pairreadsequencing("data/GCF_000146045.2_R64_genomic.fna", "result/yeastPairRead_1.fa", "result/yeastPairRead_2.fa"), ~+ B2 u/ ~+ s$ P, J8 @
sequencingObj.resultsummary()5 e* y+ b2 c% e( M- z7 n/ f
- b/ p9 |/ a1 E" x0 a R* _0 S' ^: D7 c- @5 T: p
* _, }. r6 k" O8 j, b/ [# h4 I O
: R& H. z% E; E, ]0 d: a. ]) J |
zan
|