- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 565522 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 174879
- 相册
- 1
- 日志
- 0
- 记录
- 0
- 帖子
- 5313
- 主题
- 5273
- 精华
- 3
- 分享
- 0
- 好友
- 163
TA的每日心情 | 开心 2021-8-11 17:59 |
|---|
签到天数: 17 天 [LV.4]偶尔看看III 网络挑战赛参赛者 网络挑战赛参赛者 - 自我介绍
- 本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。
 群组: 2018美赛大象算法课程 群组: 2018美赛护航培训课程 群组: 2019年 数学中国站长建 群组: 2019年数据分析师课程 群组: 2018年大象老师国赛优 |
基因组测序模拟
9 K8 J. L: f$ b! \: j. v基因组测序模拟
4 B1 ~. {# @9 D
* W9 M; W7 Z( w) {一、摘要
+ |) z5 ~* n% T
6 W" X" G" l$ Q- f9 t3 r3 B( K通过熟悉已有的基因组测序模拟和评估程序,加深全基因组鸟枪法测序原理的理解,并且能够编写程序模拟全基因组鸟枪法测序,理解覆盖度、测序深度、拷贝数等概念,设置测序相关参数,生成单端/双端测序结果文件
9 t3 l, V5 p: G l* v" B0 X$ T& l# @: i% k9 W: e( }* f
二、材料和方法6 r. J: |& l. M- ^) ]/ {
y6 H* X& \$ E4 v+ U3 c$ P
1、硬件平台
/ Z! R5 C j q* Q8 [# y$ g. ~/ i @8 c# r2 H' P2 I! t
处理器:Intel(R) Core(TM)i7-4710MQ CPU @ 2.50GHz ' I: F6 {7 Z3 `6 b G. ]
安装内存(RAM):16.0GB9 h; e9 q) q$ w2 a
1 ?/ E0 {5 ~6 _ d& h9 G
2、系统平台( l: V" k% Z0 \* r& V# _
Windows 8.1,Ubuntu' z5 `7 o) L' q" U; p
2 q5 w. Z; U# R
3、软件平台
1 y- ]- s3 I2 g% G
7 q& p3 I( n$ E2 i# q/ q& Sart_454. q9 W* o/ Z1 u, j
GenomeABC http://crdd.osdd.net/raghava/genomeabc/
' W" a) I9 Q! V# f# I7 o9 VPython3.5
- G) t- B* C! S* j: |9 k9 U# b- b' tBiopython3 U) ^) Y/ m) Q
4、数据库资源) z' h- I8 W3 s8 z9 ]6 G; {
) P5 o9 M: S( P9 q6 v! ?NCBI数据库:https://www.ncbi.nlm.nih.gov/+ m5 A( G' m* q t/ A4 E
$ ]- ?$ R+ c& j3 B4 r+ ]8 T9 i5、研究对象0 @$ n+ @7 K% y0 C7 |" b
. K7 H8 o; Q! Z( }酵母基因组Saccharomyces cerevisiae S288c (assembly R64) 3 @ W0 L+ R0 ?, l- r5 j
ftp://ftp.ncbi.nlm.nih.gov/genomes/all/GCF/000/146/045/GCF_000146045.2_R64/GCF_000146045.2_R64_genomic.fna.gz
7 s" |- W- B4 l- h6 L2 |3 K2 d: k# a, q0 f+ S& b
6、方法
/ D6 z) G& o# \9 b" a3 P
6 u) }+ u$ D3 g/ v' M; Y6 fart_454的使用
N9 _- A. S" k+ @, r; I/ e# j/ ^/ u首先至art系列软件的官网,下载软件,在ubuntu系统安装,然后阅读相关参数设置的帮助文档,运行程序。
, y4 j8 w* Q' ~: XGenomeABC
+ E# U) ~1 G( B5 ^. @2 w) C进入GenomeABC(http://crdd.osdd.net/raghava/genomeabc/),输入参数,获得模拟测序结果。* _1 B/ C6 A$ U$ P) h7 A1 \
编程模拟测序 , z: U/ B1 D' d/ }/ d" h
下载安装python,并且安装biopython扩展模块,编写程序,模拟单端/双端测序。
( L3 e+ W8 d' Q5 B4 @三、结果
- Q! k* Y8 H2 S3 J3 R o9 f+ E4 n' M1 ^- B
1、art_454的运行结果
( K8 ]% s3 k# {* Q& V* V9 H9 l6 j; X/ n n( @& P
无参数art_454运行,阅读帮助文档
3 h5 S6 j5 ?% c& Z$ ?( S4 ^+ |7 c7 ~( n9 y- ^. C0 W
图表 1无参数art_454运行
% N: Y* ]4 k2 Y$ R2 t* e对酵母基因组进行基因组单端测序模拟,FOLD_COVERAGE设为20,即覆盖度为20.
k5 X0 O4 \, `2 X4 X! e# p下图为模拟单端测序,程序运行过程及结果
+ R! z0 N0 c: ^1 `1 o$ a$ O
]; B/ c8 J! f2 z( @& T图表 2 art454单端测序 " T3 Z: _* v. n1 \
F/ q2 y9 l8 ]2 w) N# T, S
图表 3 art454单端模拟结果
& U: H( u/ f3 j/ l双端测序模拟,FOLD_COVERAGE设为20,即覆盖度为20;MEAN_FRAG_LEN设为1500,即平均片段长度为1500;STD_DEV设为20,即长度的标准差为20
7 G% p& x+ }: X" y& I下图为模拟双端测序,程序运行过程及结果 9 y+ H3 v, Q" c; h, n( q
* l8 Q- L P" ~. o; a. y图表 4 art454双端测序 % L3 X) Y) I4 e
+ ^1 j7 ^; I* u4 x( y- }8 y
图表 5 art454双端模拟结果
" a q' ]( v; z3 n7 t) ?! {2、GenomeABC 1 j) J9 S7 A# G! f
下图为设置参数页面
2 M! J/ p7 }: h$ m! ?, L5 e3 F2 @: g6 u2 w+ n: ~8 F
下图为结果下载页面
: X( |' X. m5 S; r; J- l9 G+ S" ]' C( k5 e; m$ c. U# b
图表 6 结果下载页面 ) m% X$ J: T8 Q# i
3、编程模拟测序结果
6 y: b5 P; a5 H! N拷贝数是这里的N值;覆盖度是m,测序深度是宏观的量,在这里与覆盖度意思相同,就是测序仪10X,20X。
: I4 X% h- U3 R9 ? m9 e* P. h单端测序
0 _5 c6 A z! u3 H7 ?. ~+ E" e2 j) _/ E7 O
图表 7 程序模拟单端测序 . m. `* l1 b1 [9 G# Q
双端测序
; X. V1 P$ Z a" d( q2 t/ E
$ Z" I3 x$ T% n8 {8 P' x& X! M! q图表 8 程序模拟双端测序 / L% T4 ]1 n* w7 F: V
测序结果
$ ]+ k9 n; D) C+ [$ \& Y3 t3 x3 }; j7 w! j: X" O; H
图表 9 结果文件
- a( ~( c: u9 _! ~
; D5 _% [7 Z) K4 W! R因为期望片段长度是600bp,在片段长度区间200-1000bp内,所以大部分的片段都没有删除。
% q( m Q1 E' W% B测序结果统计表0 J" ~$ `0 N9 G" O
: j; k8 ]* @; k
测序方式 基因组大小(bp) 片段长度区间 (bp) N值 期望片段长度 克隆保留率 片段数量 Reads长度范围(bp) Reads总数量 Reads总长度 覆盖度(m值) 理论丢失率(e-m) 覆盖率(1-e-m)' s3 ^' h" b2 F& a/ R( ^
单端 12157kb 200-1000 10 600 0.95 107378 50-100 101968 7645.541kb 0.62889 0.53318 0.46682* n; J8 y6 o/ G' M
单端 12157kb 200-1000 20 600 0.95 213722 50-100 202996 15227.882kb 1.25259 0.28576 0.71424$ \; S1 t) c7 o2 s
双端 12157kb 200-1000 10 600 0.95 106704 50-100 202770 15212.662kb 1.25134 0.28612 0.71388
7 }1 l- F) K1 f+ ?8 ]+ p双端 12157kb 200-1000 20 600 0.95 214212 50-100 407186 30534.265kb 2.51164 0.08114 0.91886
: A, h$ L v, Y& V# f6 Q四、讨论和结论
C& Q' @5 b; f& t$ f9 A( P" L, u
% O' J8 |# I' n6 m* p8 I程序运行方法
* u6 _: t4 ^0 T7 T( Z
3 e" o- I" }9 f+ p" s在类的构造方法init()中,调整参数。
# c, Z) v" r1 a7 ^Averagefragmentlength为片段平均的长度; ! j; k, R! X3 h. B
minfragmentlength和maxfragmentlength是保留片段的范围;
& c4 R2 o3 ?) y' A3 g' FcloneRetainprobability是克隆的保留率;
# x8 z( d2 t' A- @" W# kminreadslength和maxreadslength是测序reads的长度范围8 I2 z3 L: ?, h, k; G0 H
/ I) `2 w0 Q, [% g4 m8 |模拟测序的诸多方法都封装成了Sequencing类,只需要创建类,并调用singlereadsequencing()和pairreadsequencing()方法,传入文件名的参数即可。8 B2 `9 ~% O; r/ f
3 K3 ?; K9 J9 ^' b+ O; H
附录
2 t7 q' u3 K) m+ C4 X0 Q$ P9 H+ P5 G: k, U$ _
from Bio import SeqIO) N; p6 m7 z! A7 [: }- q
from math import exp8 I$ V9 B9 g8 b: M' A
import random
+ r# q7 L# N' n3 ?- c0 w9 Z1 k6 ^0 Q8 b3 `" y4 u2 }
class Sequencing:
$ \2 \: K! e$ x1 ^4 g0 o/ v2 S6 Y # N代表拷贝份数& f; V. O. E A! P% Z
def __init__(self)
4 m: Q! i7 h$ y% @ w% O/ _" M2 T self.fragmentList = []. G% h1 m8 u# X/ E
self.readsID = 1- \( L* @/ i2 ^ M# g9 f
self.readsList = []* z$ Q& r( R( \+ v( E8 ~
self.averagefragmentlength = 650$ j, W+ h; y! i) T, n# f" \& q) W
self.minfragmentlength = 500
' g+ N! E* n1 x( d self.maxfragmentlength = 8001 x- o* M' o; j
self.cloneRetainprobability = 1
6 w1 _" r3 d" J self.minreadslength = 50
, a+ ?4 U" E: M$ Y" l self.maxreadslength = 150# M$ k6 s8 l$ a9 v+ p
self.N = 10
K0 l! f+ z4 j& y self.genomeLength = 01 J6 P N Q! r7 p9 X) x
self.allreadslength = 0. l) o) a" h. R% A# t
- `3 w' G' ^, z0 m # 生成断裂点
& x+ p, U. h9 @. ?" ?9 ~) h def generatebreakpoint(self, seqlen, averageLength):" W# ]1 m6 D7 n0 V7 o
# 假设平均每500bp 产生一个断裂点(averageLength = 500),通过随机函数生成seqlen/500个随机断裂点(1到seqlen之间的随机整数)3 k6 r1 K' i, T/ N5 s8 P" {0 a2 b/ r
breakpoint = [random.randint(0, seqlen) for _ in range(int(seqlen / averageLength))]
- u$ S. m3 y+ D4 U2 P breakpoint.append(seqlen)
+ H# B, m# T/ ~+ `7 }9 p breakpoint.append(0)
b+ \4 ~1 @$ x" C Z2 n+ x # 把随机断裂点从小到大排序
. ~$ m9 L8 u! Z& u/ l breakpoint.sort(). H) R0 I/ y0 \- c! z
return breakpoint
& L7 k$ L- s K. \; D& U Z; x' D1 ]1 G( x+ G$ D
# 沿断裂点打断基因组,并删除不符合长度要求的序列片段,定义片段范围:200-1000bp1 l( W4 t# ]# A. l8 }! Q6 X2 M
def breakgenome(self, seq, breakpoint, minfragmentlength, maxfragmentlength):
/ }; i" c5 Q' K7 L# } for i in range(len(breakpoint) - 1):1 F6 S$ t% S& S4 ]- w2 s$ b: b
fragment = seq[breakpoint:breakpoint[i + 1]]
6 B8 V n. j5 g if maxfragmentlength > len(fragment) > minfragmentlength:/ G) V5 Y% P, w7 P c, m e% r
self.fragmentList.append(fragment)
8 R$ c% j8 p6 Q! `5 r, j3 F return self.fragmentList
/ O' e; L$ B {* A k, V: X( Z7 N6 }4 f
# 模拟克隆时的随机丢失情况,random.random()生成0-1的保留概率
o* p/ B! {$ e3 ^ def clonefragment(self, fragmentList, cloneRetainprobability):) @' y( [+ Y" @& D* g) K1 Y& k
clonedfragmentList = []
C' q5 `% L1 ^! n" V1 z Lossprobability = [random.random() for _ in range(len(fragmentList))]
p: P8 x1 e; q8 |" s for i in range(len(fragmentList)):
* }) G/ N+ A( m9 b: S if Lossprobability <= cloneRetainprobability:3 S; ~ p" Q5 i$ m
clonedfragmentList.append(fragmentList)) ~ {: } m: t: X& W
return clonedfragmentList
# m& S: v' b8 T7 T/ C% ?" @! o% X
. O+ m, _- H6 ` N # 模拟单端测序,并修改reads的ID号0 k t. _) i% W+ z
def singleread(self, clonedfragmentList):4 _7 s& p/ g( o5 @
for fragment in clonedfragmentList:
. m( N5 S7 l! D' G: u5 F, D fragment.id = ""
/ F2 A ~' \ a0 ^ fragment.name = "". B, B1 o6 C( _: g
fragment.description = fragment.description[12:].split(",")[0]
1 q; v( S! R. s6 z4 }2 i fragment.description = str(self.readsID) + "." + fragment.description) G# @4 s( ^; q
self.readsID += 1
0 d: ^. \8 p3 V; T, Z: L& r8 q9 A readslength = random.randint(self.minreadslength, self.maxreadslength)$ p! q, o; ~: C" R3 D4 b0 ]' s
self.allreadslength += readslength5 b; N6 ^; A2 R: t
self.readsList.append(fragment[:readslength]) Y- h; a4 M K& {8 N( a1 T5 y' C! R
9 o$ D+ \+ ~* ~- q- I& K, q def singlereadsequencing(self, genomedata, sequencingResult):1 ^% I a% C& K: z$ J3 H# O
for seq_record in SeqIO.parse(genomedata, "fasta"):
# X8 j$ E0 h3 Z( W! b! K5 |) B seqlen = len(seq_record)
/ u6 @" ?; @5 z' G& _0 k9 x4 j- v2 Y self.genomeLength += seqlen& L1 L5 {6 ~; D7 u% m. N% t9 Y5 r
for i in range(self.N):
: R6 ^- J% \1 F5 P. [) T, p7 p2 W # 生成断裂点
) v7 k {# U" a breakpoint = self.generatebreakpoint(seqlen, self.averagefragmentlength)
+ {( `* L; w9 Y, f% T1 l) { # 沿断裂点打断基因组
! [! B3 H. E; q9 F9 @- H self.breakgenome(seq_record, breakpoint, self.minfragmentlength, self.maxfragmentlength)
4 w* l) d! U! Q5 L' R4 Y/ [7 n # 模拟克隆时的随机丢失情况: l2 ~9 u" S! ?8 h
clonedfragmentList = self.clonefragment(self.fragmentList, self.cloneRetainprobability)
7 V1 J$ p3 ?& n W, |% u. m& i # 模拟单端测序- y+ g8 \& k, @" I6 {5 |
self.singleread(clonedfragmentList)/ F) H' |" @0 l% v1 X/ ~7 o
SeqIO.write(self.readsList, sequencingResult, "fasta")0 @& d% Y5 ^" g
/ R% y2 j7 `) R# | def pairread(self, clonedfragmentList):
. X' G- |# T9 B" W% K for fragment in clonedfragmentList:0 s6 o; w0 m8 e. O; c( C* u
fragment.id = ""0 D& p* n, b$ f. K( A
fragment.name = ""
" t, ]: ~ I2 Y* I0 C$ h description = fragment.description[12:].split(",")[0]1 r2 ?/ T. A" x, _$ H
fragment.description = str(self.readsID) + "." + description% J/ h9 u0 t4 u5 L# x; p
readslength = random.randint(self.minreadslength, self.maxreadslength)
2 V# n: G0 E" D9 B7 B2 Z* X2 v self.allreadslength += readslength
6 Z$ _# H; x3 z5 B$ d self.readsList.append(fragment[:readslength])
1 ^; D' Q2 b C5 b$ K' |' }) k2 d' o( e: Z' C, h6 z
readslength = random.randint(self.minreadslength, self.maxreadslength)6 I c4 a9 x1 c3 s3 h1 `6 s; S
self.allreadslength += readslength
+ s# R: j$ I0 ]3 l- I' {4 B. ~5 D- Z& I, ]8 G- U
fragmentcomplement = fragment.reverse_complement()- J G1 V2 B, x$ H
fragmentcomplement.id = ""% j. q( a7 [# V" @& S P
fragmentcomplement.name = ""
; E9 M1 K; W. V fragmentcomplement.description = str(self.readsID) + "." + description
_* k$ I3 G: P; ^& D1 p# _ self.readsList.append(fragmentcomplement[:readslength])
$ H) B: L. N5 P7 S3 ]/ J9 v6 c- |' a9 E% n& M; z- s
self.readsID += 16 q# X6 {" C/ v* d% H
2 [: e( u/ G1 g0 x4 x: q) J
def pairreadsequencing(self,genomedata, sequencingResult_1, sequencingResult_2):
8 c" ?% l; Q% D$ |9 Y for seq_record in SeqIO.parse(genomedata, "fasta"):$ O+ f' P& c' B5 u' F0 ]: O' D
seqlen = len(seq_record)
- f1 Z5 m- E( S self.genomeLength += seqlen
( O0 H" [: d' C2 m9 Q1 D" b for i in range(self.N):
1 O0 V8 D1 ?; n0 D: L2 Q4 k1 N6 u2 m # 生成断裂点' _4 [% U" }9 T4 H: g& m! H
breakpoint = self.generatebreakpoint(seqlen, self.averagefragmentlength)6 f" a9 u+ l' {% B" a
# 沿断裂点打断基因组
; W2 q( }: E; a1 X4 |, u* m self.breakgenome(seq_record, breakpoint, self.minfragmentlength, self.maxfragmentlength)
" f' w$ ~/ j$ s5 h, p # 模拟克隆时的随机丢失情况
7 T/ h& z! _. s6 J; e clonedfragmentList = self.clonefragment(self.fragmentList, self.cloneRetainprobability)4 w. q) s% f7 s. O, C3 X( b2 L' h
# 模拟双端测序# q+ @2 \0 y, T' c" z1 L
self.pairread(clonedfragmentList)
" V9 N% d/ S) M. H- d4 _0 |. _ readsList_1 = [self.readsList for i in range(len(self.readsList)) if i % 2 == 0]( S9 C* f' |" }, l$ ]1 @% j+ c
readsList_2 = [self.readsList for i in range(len(self.readsList)) if i % 2 == 1]) O$ D$ n- Q4 X+ E) x2 I
SeqIO.write(readsList_1, sequencingResult_1, "fasta")
( o0 G v6 t) t- b: N X SeqIO.write(readsList_2, sequencingResult_2, "fasta")4 c# W/ G3 g/ j
0 M9 d0 Z; T' N4 k: H `
def resultsummary(self):
! B4 y0 t: |* W; I9 A0 s print("基因组长度:" + str(self.genomeLength / 1000) + "kb") R3 g7 f5 X7 d& u: o) D
print("片段长度区间:" + str(self.minfragmentlength) + "-" + str(self.maxfragmentlength))' }3 d- \$ j- _* V$ }6 B: p% L
print("N值:" + str(self.N))& a, f2 ?+ k% L9 G; l1 ]
print("期望片段长度:" + str(self.averagefragmentlength))% x4 s% D# }0 z3 i- w% |8 j
print("克隆保留率:" + str(self.cloneRetainprobability)): I/ F- g% h/ u0 |5 \7 A B
print("片段数量:" + str(len(self.fragmentList)))/ k5 x5 s& z J
print("reads长度:" + str(self.minreadslength) + "-" + str(self.maxreadslength)), F: v4 n1 q; V |' t5 q5 ~2 t+ F
print("reads总数量:" + str(len(self.readsList)))
5 x8 b6 E5 E- s4 \ print("reads总长度:" + str(self.allreadslength / 1000) + "kb")
3 }8 t1 v( d) L m = self.allreadslength / self.genomeLength/ X. C: y( J! o: A# }
print("覆盖度(m值):" + str(round(m, 5))): t& L$ d& P% [) S
print("理论丢失率(e^-m):" + str(round(exp(-m), 5)))
3 h8 S0 d, `' c print("覆盖率(1-e^-m):" + str(round(1 - exp(-m), 5)))* N- w& R% m! |* E& s5 _
# -------------------------------------------主程序-------------------------------------------% e5 O; R0 i: Q5 \% R4 j% n
# 模拟单端测序
+ s! l. R; ?. N: ^ E+ T1 ?& P4 nsequencingObj = Sequencing(): |% U) X$ M; g( B- f+ g5 V
sequencingObj.singlereadsequencing("data/NC_025452.fasta", "result/virusSingleRead.fa")
. ^& m1 R1 L1 v1 r2 w. \8 b% j8 vsequencingObj.resultsummary()
# Y! d1 c \, l# _& ]" K0 d+ M: e" r7 T4 Z! n0 f
# 模拟双端测序
, u: x$ v, a2 p+ |# x- |sequencingObj = Sequencing()
. S9 E( K9 E5 RsequencingObj.pairreadsequencing("data/GCF_000146045.2_R64_genomic.fna", "result/yeastPairRead_1.fa", "result/yeastPairRead_2.fa")
1 s/ K0 m# i& Y; CsequencingObj.resultsummary()
3 c' } [0 m% `5 W6 ^from Bio import SeqIO6 m" ?0 G* Z9 B- E" ~' a8 X$ e' S
from math import exp+ l* K, `0 `- u4 c2 O! H
import random
/ i: c+ T: s6 u; Z( f* L1 l8 C+ G/ f4 P, S8 c( \ w1 c d7 O$ P" @' d/ S
class Sequencing:
: N; C* T9 r$ J2 M n # N代表拷贝份数
1 @' h q4 H6 S2 K& m3 l% k def __init__(self):
, W' \ o! c% o$ [- P self.fragmentList = []
0 {+ ?, [% w- f9 t9 g. d self.readsID = 1" G$ S9 k. p" @9 @& l
self.readsList = []
s2 O" O& x/ R- r* l self.averagefragmentlength = 650, p- B$ U; ]' ]6 e" f% Y0 C
self.minfragmentlength = 500
3 i- }5 t! [" W) G- H7 ?3 n G5 K% ~# | self.maxfragmentlength = 800
5 U# Z E2 `& D self.cloneRetainprobability = 1
+ F+ T& Z# F+ }+ d1 ` self.minreadslength = 50( J; n5 n4 Y8 Y, W
self.maxreadslength = 150
* ^! m" H) }, d self.N = 10* P8 F% T: ~* J6 {8 ?, s- g' F9 w
self.genomeLength = 0" l9 y6 h' Z& k) s6 x1 Q9 K: x
self.allreadslength = 0' J2 S( X& e/ O! y) M- m
6 k) P, a s5 }5 V* w! ^6 B # 生成断裂点
& V2 N. J' Z* g$ ]- ^ def generatebreakpoint(self, seqlen, averageLength):* _/ a7 b0 ]$ f" O% c; s8 C8 Q
# 假设平均每500bp 产生一个断裂点(averageLength = 500),通过随机函数生成seqlen/500个随机断裂点(1到seqlen之间的随机整数)
3 G9 H( t- r; ^% Y$ Q! ~( ? breakpoint = [random.randint(0, seqlen) for _ in range(int(seqlen / averageLength))]# {9 s4 e' }- Y9 V3 k; K
breakpoint.append(seqlen) y$ ]2 R+ K4 J9 {
breakpoint.append(0)
" F9 g7 f8 E F+ w" U7 _: e # 把随机断裂点从小到大排序
1 z. C6 Q, e1 D7 H* j breakpoint.sort()
5 ?/ S: d( y, N5 p/ P8 K2 y return breakpoint
2 i: G0 X: ^$ o# D$ Q
( t0 X) @ A# b. [4 a # 沿断裂点打断基因组,并删除不符合长度要求的序列片段,定义片段范围:200-1000bp: a- z8 z9 C, E9 z5 u2 n
def breakgenome(self, seq, breakpoint, minfragmentlength, maxfragmentlength):
; L- ?: Y/ c" L/ X for i in range(len(breakpoint) - 1):
6 U, [. A* b4 V! e J1 L3 N fragment = seq[breakpoint:breakpoint[i + 1]]
; F; ~0 g9 G- U7 t if maxfragmentlength > len(fragment) > minfragmentlength:
, ?1 `% f, S: ^7 e+ e self.fragmentList.append(fragment)7 C! _6 i* A' t) t( F
return self.fragmentList
: n/ C6 W1 ^$ m7 E
( A9 a. n# E3 P7 b7 [. q" ^ n # 模拟克隆时的随机丢失情况,random.random()生成0-1的保留概率# ~) e- k; n6 f1 z4 a# }9 A9 t: x
def clonefragment(self, fragmentList, cloneRetainprobability):# f$ b& h( }; {5 `
clonedfragmentList = []
* d t" H, {# B* A( r Lossprobability = [random.random() for _ in range(len(fragmentList))]; R4 F; }' i; A y# ^
for i in range(len(fragmentList)):" ?. V6 E) D( o) F4 j. W
if Lossprobability <= cloneRetainprobability:
+ p4 { J5 `( w( c9 n clonedfragmentList.append(fragmentList)
6 v# k' |" O# E" r0 S$ L return clonedfragmentList4 o! Z2 s2 S) I+ B' K2 [
- v7 M& N- c$ ]) W9 Z9 i6 S5 e # 模拟单端测序,并修改reads的ID号% J5 @8 i: U4 B- W0 M' K' ~
def singleread(self, clonedfragmentList):: J1 {; l7 h! ]9 M
for fragment in clonedfragmentList:- W* ^# }) \7 R: K5 i3 G' Y
fragment.id = ""
9 ] X& E+ _$ |2 W8 e1 T8 \ fragment.name = ""
3 I6 J$ D1 O! e Z( f# s$ X* Q fragment.description = fragment.description[12:].split(",")[0]- ?# p: J: G- J8 L( f, W+ a
fragment.description = str(self.readsID) + "." + fragment.description( S8 v& W9 x7 Q6 X1 e' a
self.readsID += 1" b v/ J5 t5 u7 ` Z% ]7 m
readslength = random.randint(self.minreadslength, self.maxreadslength)
0 d8 c @0 F+ Y# R3 R" { c self.allreadslength += readslength
9 P: w2 Z' d; e& L: z$ s self.readsList.append(fragment[:readslength])* Y1 A% \5 m; R
% C& e- l$ m- U def singlereadsequencing(self, genomedata, sequencingResult):
. f7 P' B; c- d! T$ S0 Z for seq_record in SeqIO.parse(genomedata, "fasta"):
; a+ s5 R: Y1 f! U2 j seqlen = len(seq_record)6 b& G- p9 C% f) R
self.genomeLength += seqlen
0 l4 S/ d) R, a, Z for i in range(self.N):
" {3 l+ C* k2 @, ?# c1 x% g # 生成断裂点$ @! F8 v+ v- r- |/ L) q. o
breakpoint = self.generatebreakpoint(seqlen, self.averagefragmentlength)
( K& v y, ^/ T$ H # 沿断裂点打断基因组
`& S, I. t! `: G4 v9 A' \, S$ v8 b9 B self.breakgenome(seq_record, breakpoint, self.minfragmentlength, self.maxfragmentlength)
, k# q$ W7 b5 x. U h # 模拟克隆时的随机丢失情况3 w. H) h% Q/ _9 C! @5 v/ k4 p
clonedfragmentList = self.clonefragment(self.fragmentList, self.cloneRetainprobability)" \) }0 X, `1 t+ y
# 模拟单端测序
; i5 x7 p& @1 J2 o5 f3 s1 k self.singleread(clonedfragmentList)) U! {7 H8 T# @& F1 j
SeqIO.write(self.readsList, sequencingResult, "fasta")) f, p7 P7 Q! S3 k
: t5 K* J1 P9 m M+ W0 f
def pairread(self, clonedfragmentList):
6 X# m- j# e- h- R for fragment in clonedfragmentList:
3 z2 D, }/ y! P fragment.id = ""1 L y9 b! t/ O# I$ N
fragment.name = ""- g! J; Z! h6 \: }. m: G
description = fragment.description[12:].split(",")[0]
& Z4 m2 {/ G3 k4 J9 v fragment.description = str(self.readsID) + "." + description
- g: s; m4 j) K5 X2 B1 o, q& A readslength = random.randint(self.minreadslength, self.maxreadslength)7 M3 x% d' b" z- z4 m" t+ v
self.allreadslength += readslength
@* j+ v; |: [7 `2 t self.readsList.append(fragment[:readslength])
7 `" P6 _8 J( [
- k/ ~0 W' L0 d3 _# l9 o readslength = random.randint(self.minreadslength, self.maxreadslength)
$ ^0 m; B2 n; @4 d- _& Q( \5 n( s8 j0 O self.allreadslength += readslength: f4 g7 e7 {- c$ N7 a
" |) v" h: P# C4 n$ [! M
fragmentcomplement = fragment.reverse_complement()& t4 k+ h( I* n" V, C, S8 ]& b2 y5 }
fragmentcomplement.id = ""
% K) c1 }2 U S3 J( h- P! ] fragmentcomplement.name = ""
" u) |0 U! e' _' y8 m P) G fragmentcomplement.description = str(self.readsID) + "." + description
* q$ ^: K! I. l2 s self.readsList.append(fragmentcomplement[:readslength])
8 \% n% l6 r6 x4 @2 K" C' e& @8 t+ W9 I% H
self.readsID += 1
" H/ \) v% x; Z
- u( Q7 q% R( D6 [# q! c3 k def pairreadsequencing(self,genomedata, sequencingResult_1, sequencingResult_2):
. p/ @# X/ L; r0 \2 F/ X/ D7 i5 Z for seq_record in SeqIO.parse(genomedata, "fasta"):# o8 R0 W- ]# E( e4 f
seqlen = len(seq_record)7 _* V& x" b9 m; r
self.genomeLength += seqlen# s/ E' C3 r6 _* P
for i in range(self.N):
0 ]) r+ \ s+ c- ? # 生成断裂点( k( x( z P( g. d# k0 M3 f
breakpoint = self.generatebreakpoint(seqlen, self.averagefragmentlength)# \6 ~ l+ H6 t, u- k* c
# 沿断裂点打断基因组2 B% p3 P/ L% }9 N) ]" F
self.breakgenome(seq_record, breakpoint, self.minfragmentlength, self.maxfragmentlength)+ j5 `. K0 N, Z& }$ R4 n( j, I
# 模拟克隆时的随机丢失情况5 _0 O( q% E1 k8 E* |0 A) F
clonedfragmentList = self.clonefragment(self.fragmentList, self.cloneRetainprobability); S# S+ y) R$ H; u9 @- ]2 |- V* H
# 模拟双端测序
# U9 o, W1 z$ [8 l$ X6 j' E5 v self.pairread(clonedfragmentList): W0 @( w) p$ A K
readsList_1 = [self.readsList for i in range(len(self.readsList)) if i % 2 == 0]
$ H/ x) a! G t9 @) g0 |" B readsList_2 = [self.readsList for i in range(len(self.readsList)) if i % 2 == 1]
6 t a' N: U: I, c' Z SeqIO.write(readsList_1, sequencingResult_1, "fasta")8 Z) q, {. @" ~& [8 Z! \
SeqIO.write(readsList_2, sequencingResult_2, "fasta")
6 a% k- x9 V" |7 v; ?
. z5 y H+ Q4 G+ u; M! h def resultsummary(self):0 @) ?3 b2 F2 P0 o! m) I
print("基因组长度:" + str(self.genomeLength / 1000) + "kb")
1 \" x+ N9 o3 U# ~7 ]- `0 l* L! L print("片段长度区间:" + str(self.minfragmentlength) + "-" + str(self.maxfragmentlength)): K1 Y' e* Y5 G6 u8 j2 J1 v
print("N值:" + str(self.N))
; ]7 B5 V9 W8 _6 Z print("期望片段长度:" + str(self.averagefragmentlength))/ b% ~: A* F; a& c
print("克隆保留率:" + str(self.cloneRetainprobability))
. w! Y1 F/ _& S) f print("片段数量:" + str(len(self.fragmentList)))
* G7 I- R/ |8 O! y& D! @2 l6 _2 [, M print("reads长度:" + str(self.minreadslength) + "-" + str(self.maxreadslength)): I9 D; c( u8 K* D y
print("reads总数量:" + str(len(self.readsList)))
8 l2 R" @* z! a' W3 \0 B print("reads总长度:" + str(self.allreadslength / 1000) + "kb")2 |+ O! N* \1 i3 g$ I' u/ q
m = self.allreadslength / self.genomeLength
; _1 H: r* o+ g _" a! q4 e: E print("覆盖度(m值):" + str(round(m, 5)))! x+ d' `& A0 n% B3 D2 j% `, ~% J
print("理论丢失率(e^-m):" + str(round(exp(-m), 5)))
* r6 X7 W) a x3 R5 a' X0 \# B print("覆盖率(1-e^-m):" + str(round(1 - exp(-m), 5)))
: \* {" P0 b% a) \) E! _/ K1 P# -------------------------------------------主程序-------------------------------------------
0 H* A4 z5 i+ \; w* o# 模拟单端测序7 _' v, c. z1 c) K$ @2 I) _
sequencingObj = Sequencing()7 f/ L+ N/ x8 V! y. ]* z6 a
sequencingObj.singlereadsequencing("data/NC_025452.fasta", "result/virusSingleRead.fa")
5 `/ j9 X- n7 c3 ]sequencingObj.resultsummary()
! H3 [! y. v% Z9 N- `+ C1 \2 f' Z+ P% @( |3 W$ r
# 模拟双端测序! i2 y- N! Z: C/ I0 D9 i
sequencingObj = Sequencing()
@+ n/ V1 I/ ~sequencingObj.pairreadsequencing("data/GCF_000146045.2_R64_genomic.fna", "result/yeastPairRead_1.fa", "result/yeastPairRead_2.fa")# l r. Q9 o! @; S; m
sequencingObj.resultsummary()
' B& m% ~, j$ D( }( r9 x, m4 q- M9 v* f& S/ K' J m
, E" S% ~. k4 o: z
! E# U- W" b2 ~
. ~" @' ]! ^, ~# T) W2 f* K! i |
zan
|