- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 565523 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 174880
- 相册
- 1
- 日志
- 0
- 记录
- 0
- 帖子
- 5313
- 主题
- 5273
- 精华
- 3
- 分享
- 0
- 好友
- 163
TA的每日心情 | 开心 2021-8-11 17:59 |
|---|
签到天数: 17 天 [LV.4]偶尔看看III 网络挑战赛参赛者 网络挑战赛参赛者 - 自我介绍
- 本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。
 群组: 2018美赛大象算法课程 群组: 2018美赛护航培训课程 群组: 2019年 数学中国站长建 群组: 2019年数据分析师课程 群组: 2018年大象老师国赛优 |
基因组测序模拟
. E" n% |8 s9 j# P; l基因组测序模拟! d! _3 J: M0 u6 Y
$ V6 [: v! }: {. D2 o一、摘要2 D% e- w+ J6 J; A" H
2 F" k. B4 M; m6 ^! V; C" e
通过熟悉已有的基因组测序模拟和评估程序,加深全基因组鸟枪法测序原理的理解,并且能够编写程序模拟全基因组鸟枪法测序,理解覆盖度、测序深度、拷贝数等概念,设置测序相关参数,生成单端/双端测序结果文件
" R% p+ H' C6 k' ?
) F$ l r" \# F* s二、材料和方法
x2 [1 ]9 ?. n9 k- {1 H+ N" }9 R! m
1、硬件平台 Q$ ]; D! }8 h3 i
9 ^6 \; s# r9 {& k0 Q处理器:Intel(R) Core(TM)i7-4710MQ CPU @ 2.50GHz 1 T f# V+ U d3 ^
安装内存(RAM):16.0GB! J* y- O/ l! B' X
( |) H5 h2 d3 x. J9 r( W2、系统平台# V7 C$ F- m1 d; w, g9 b l1 d
Windows 8.1,Ubuntu
- ^6 }& J6 r0 K [- j( ]8 R6 k, k: N
3、软件平台( ^" V: F4 i% d) ?8 n
# F' _6 s$ b5 E [
art_454
# _# I# n' U# u8 d" @GenomeABC http://crdd.osdd.net/raghava/genomeabc// }0 A) k _( Q: ?$ h
Python3.59 Z$ H9 _/ K5 |0 t* Q
Biopython: z3 ~- L& a4 v V! L, ~$ c
4、数据库资源& p5 t& F& M2 P! K5 f0 a6 ~
3 u* s0 k; f- C% D- kNCBI数据库:https://www.ncbi.nlm.nih.gov/
- U# \, y" E! D0 Z. R+ w! S7 E8 T6 c! R5 \& |( c: G
5、研究对象; m( }9 f: R9 x& w
( i5 ? J. S8 I3 ~' ?- Y7 \4 f酵母基因组Saccharomyces cerevisiae S288c (assembly R64) 7 d8 I* l0 S% M9 h
ftp://ftp.ncbi.nlm.nih.gov/genomes/all/GCF/000/146/045/GCF_000146045.2_R64/GCF_000146045.2_R64_genomic.fna.gz
t1 U. e' l- ?. H# F9 t1 s
0 h7 q0 S- H2 H+ ?' T( L6、方法1 J5 X8 P1 G, w' [1 N" v
, T& `* e9 R9 A0 xart_454的使用 , t# q, e4 Q; l! B6 s
首先至art系列软件的官网,下载软件,在ubuntu系统安装,然后阅读相关参数设置的帮助文档,运行程序。
+ g- {1 A8 n, y: T( RGenomeABC
9 e/ }) k5 U6 e. K% E) a进入GenomeABC(http://crdd.osdd.net/raghava/genomeabc/),输入参数,获得模拟测序结果。7 k. R8 y- z; p' D; m: i9 _
编程模拟测序
. y9 _3 B8 W1 v' t. R下载安装python,并且安装biopython扩展模块,编写程序,模拟单端/双端测序。
( `$ A. g& F: K& A' {三、结果
1 ?" k: F* M9 {4 n8 U
7 X) h: G! N) b6 i1 `/ {4 W1、art_454的运行结果
* Q7 t) }/ Q# L! s8 x
9 k- q0 P; c$ e无参数art_454运行,阅读帮助文档 & N$ ]# I& U8 L6 E. m1 |2 y6 t
2 l" w5 h$ P) o7 ~5 O* X! u
图表 1无参数art_454运行 7 }: g* d* c" E6 ~& k
对酵母基因组进行基因组单端测序模拟,FOLD_COVERAGE设为20,即覆盖度为20. 3 O% P, a2 y% X: ]: W
下图为模拟单端测序,程序运行过程及结果
' j8 e% K0 Z& \; Y' d3 F. _4 y! L' X R( i
图表 2 art454单端测序 1 W# n8 i7 A. D( G- k5 o
2 O) v2 E& x, ~' S9 C% w3 D图表 3 art454单端模拟结果 9 i) ?- N+ |. P+ l2 ]
双端测序模拟,FOLD_COVERAGE设为20,即覆盖度为20;MEAN_FRAG_LEN设为1500,即平均片段长度为1500;STD_DEV设为20,即长度的标准差为20
1 i. A3 V7 D. v9 k! B% ]0 @/ l下图为模拟双端测序,程序运行过程及结果
* V0 s6 R3 |8 K
! W& t# \/ o$ y3 s5 Y: t图表 4 art454双端测序
( a& `, r% u7 ~# V" W" z7 e& j( f) {6 a- Z" K0 O7 a# G0 \
图表 5 art454双端模拟结果 2 T! c) ]! g2 M u, e. q! U% @
2、GenomeABC , w% M6 X! w$ `
下图为设置参数页面
; D0 S4 Y7 ~; m' U
4 Y5 m r+ q* Y1 ~4 v5 I下图为结果下载页面 ! _4 M( d4 l! j, @' l; s3 Z$ ]
# M7 H, F' d' g6 H" V. p图表 6 结果下载页面 7 w8 F: Q3 z2 c0 w, M. z
3、编程模拟测序结果 , `- ?) q1 h Y! v. |
拷贝数是这里的N值;覆盖度是m,测序深度是宏观的量,在这里与覆盖度意思相同,就是测序仪10X,20X。
1 @" Y+ b( n( x0 Y; G( f单端测序
. |4 v, R% z: ?2 q
* k7 Q- ~7 V+ ?# o% ~* d图表 7 程序模拟单端测序
5 N7 u) ]* @; n: l6 U( `8 N双端测序
/ u! e' V% Z4 N, _9 c P F/ g5 I6 z
图表 8 程序模拟双端测序
! k' n. B9 e ~测序结果 , [6 G2 u( k) t5 P) t
0 i7 s9 L- ]/ r% `
图表 9 结果文件% W0 V8 R1 H& j+ B/ s# [3 a; g
" I7 |- O, i! ] r( g因为期望片段长度是600bp,在片段长度区间200-1000bp内,所以大部分的片段都没有删除。 7 L+ u$ g; I1 Q
测序结果统计表. Q- c) O- Z8 D6 g6 k7 ?
" w# ?8 v+ l) M
测序方式 基因组大小(bp) 片段长度区间 (bp) N值 期望片段长度 克隆保留率 片段数量 Reads长度范围(bp) Reads总数量 Reads总长度 覆盖度(m值) 理论丢失率(e-m) 覆盖率(1-e-m)
4 H. T' D4 A3 q9 p" r6 ^( A# {单端 12157kb 200-1000 10 600 0.95 107378 50-100 101968 7645.541kb 0.62889 0.53318 0.46682
% _$ y, |! Y! `% R5 P8 K单端 12157kb 200-1000 20 600 0.95 213722 50-100 202996 15227.882kb 1.25259 0.28576 0.71424
8 w7 V3 e3 ^" w4 r, v双端 12157kb 200-1000 10 600 0.95 106704 50-100 202770 15212.662kb 1.25134 0.28612 0.71388
2 g* a5 T0 h7 l双端 12157kb 200-1000 20 600 0.95 214212 50-100 407186 30534.265kb 2.51164 0.08114 0.918863 Y0 ?* ?9 _8 x0 o- v- i. ?( N' ]
四、讨论和结论
7 G; g f5 C Q" b! E$ F, w+ p( Q; t5 i+ e0 u" T8 |, l/ a% p5 N1 g
程序运行方法
: z7 Q" h2 g& Y; i% A
4 K8 ^# g0 o( a1 Z5 |8 t在类的构造方法init()中,调整参数。 - R# C" H) X. z! K: J5 O9 o
Averagefragmentlength为片段平均的长度; " _* p" {& x2 P& D
minfragmentlength和maxfragmentlength是保留片段的范围; ; z8 P5 }4 B% q3 C$ n
cloneRetainprobability是克隆的保留率; 2 u/ [. N# G1 d9 u1 C- o* v Y5 f
minreadslength和maxreadslength是测序reads的长度范围
; m- E9 D4 z% ?7 E Q* J6 @3 }8 G; n! c& U1 o5 W
模拟测序的诸多方法都封装成了Sequencing类,只需要创建类,并调用singlereadsequencing()和pairreadsequencing()方法,传入文件名的参数即可。; k+ X3 u& {% O0 B6 G
! T2 Y" _& H8 y6 @8 O
附录* K- y, P5 W4 ]- g; c! R3 J% K
0 J3 {8 c% U! E4 s
from Bio import SeqIO
- a' M9 g0 y, ~9 dfrom math import exp9 I4 ]$ X b R- N: M6 p
import random
: W6 R- i. n7 k7 o( H# P5 J5 s+ y+ n* z X; H& z/ `' T4 w
class Sequencing:& L4 p/ D1 C% ~; n. F, V
# N代表拷贝份数
7 [( W7 i+ T- W8 Z def __init__(self)( C8 Y$ a' _) [9 y" J- ]: R
self.fragmentList = []. r9 d' z, H5 O
self.readsID = 1; }+ J% o) Q; T' ^
self.readsList = []
4 j5 W, J2 E+ b! u" K; X) G5 U self.averagefragmentlength = 650$ v( s0 P A9 f5 S' r! _0 X( Q) m
self.minfragmentlength = 5007 G0 G z( c3 Y! ~
self.maxfragmentlength = 8000 t. q5 z3 F V; R$ @* Q
self.cloneRetainprobability = 1
r" y3 K: }0 @ self.minreadslength = 50) {6 @' d, b; v2 k' U$ C$ k W
self.maxreadslength = 150
# Q6 V- b; I" Q }( o- k self.N = 10
( K7 I$ F2 C$ d) B s# M! v self.genomeLength = 0
2 U5 _7 `4 ?* L8 X( R# x self.allreadslength = 0- x. |+ l9 G) {
+ F- L! H3 I2 {( P7 g8 n) r) a
# 生成断裂点4 ?+ F! B& x; ^: Z7 `% d
def generatebreakpoint(self, seqlen, averageLength):
$ g, m; z* @- N6 | # 假设平均每500bp 产生一个断裂点(averageLength = 500),通过随机函数生成seqlen/500个随机断裂点(1到seqlen之间的随机整数)2 i1 z+ p8 }9 a) M* D
breakpoint = [random.randint(0, seqlen) for _ in range(int(seqlen / averageLength))]+ N" {. i9 c3 L- b# @0 T2 q
breakpoint.append(seqlen)
3 b1 _8 Z" g9 }( o/ A. O2 i- E breakpoint.append(0)! y# j8 b# a! P0 q% ~# U; `3 K
# 把随机断裂点从小到大排序+ C/ @; E0 V2 N' \) q3 w' _% K' E
breakpoint.sort()
' B* R& q+ Q: V a0 i$ T return breakpoint! ?* q+ A B5 j- H2 E* \
' d( w( O2 N6 Y4 N/ p) O # 沿断裂点打断基因组,并删除不符合长度要求的序列片段,定义片段范围:200-1000bp
3 w& C( w5 O2 ~! D def breakgenome(self, seq, breakpoint, minfragmentlength, maxfragmentlength):# I+ e' m) ~% F- H3 t9 r2 `, G
for i in range(len(breakpoint) - 1):
. d! u L0 ~# }7 i! b7 ]4 N fragment = seq[breakpoint:breakpoint[i + 1]] L3 u% p+ D, Y& x0 X+ S; k
if maxfragmentlength > len(fragment) > minfragmentlength:
2 v: b4 N3 j1 Y* |% {% P) M/ W. F5 l self.fragmentList.append(fragment)
: y4 ?8 x: K3 E7 r" q/ A return self.fragmentList/ f6 W2 ~+ D/ L$ S& W* B
8 N: ]6 {3 d- _ # 模拟克隆时的随机丢失情况,random.random()生成0-1的保留概率5 r0 q1 K: R+ c# V# O. Z
def clonefragment(self, fragmentList, cloneRetainprobability):7 r2 l& F1 f# Y4 L" a* Z4 T
clonedfragmentList = []# C) g' L3 \9 C$ R+ ~7 f J7 M4 ]$ U
Lossprobability = [random.random() for _ in range(len(fragmentList))]
' I# @6 w4 n) |6 S for i in range(len(fragmentList)):) N O: A# d; C1 O( t3 h
if Lossprobability <= cloneRetainprobability:
/ t4 z$ X7 {2 B; U clonedfragmentList.append(fragmentList)
3 w c, R: b; p return clonedfragmentList# h1 o; k2 @; M
* ~- o+ y9 y. u# N; V3 |9 U
# 模拟单端测序,并修改reads的ID号6 Z* w! h9 O }8 `6 B2 Y
def singleread(self, clonedfragmentList):4 v2 s6 u; G p8 k; I6 n! G
for fragment in clonedfragmentList:
1 v8 b; Y5 Q: H8 T1 g! B- E fragment.id = ""
+ J4 T. W8 V# H: x fragment.name = ""
9 E n R* B; r9 d+ ^! @! d1 k5 ^ fragment.description = fragment.description[12:].split(",")[0]
1 n' `+ e6 }5 Y" l u fragment.description = str(self.readsID) + "." + fragment.description5 M- J; d6 @+ q& G
self.readsID += 17 I; Q5 P( z( Q, n1 T4 k* C2 U
readslength = random.randint(self.minreadslength, self.maxreadslength)# F- p" v9 q" f# ^: O8 l+ r! X
self.allreadslength += readslength+ ^. f% t" Y. J0 |/ L5 ~9 O
self.readsList.append(fragment[:readslength])
/ }/ N0 L! d% s/ f) K, K E6 c/ S4 n2 d4 ]/ h. n) p
def singlereadsequencing(self, genomedata, sequencingResult):+ ]0 N/ k. A: n: w
for seq_record in SeqIO.parse(genomedata, "fasta"):
9 V# g5 a. t9 f; g. Z' M seqlen = len(seq_record)
1 J0 Q5 c: z7 Y( E* j3 U6 q self.genomeLength += seqlen
$ {( G; D8 x z5 ?, l for i in range(self.N):! o" i3 l8 H& W3 l
# 生成断裂点
$ L; d9 z/ e8 l: S5 c breakpoint = self.generatebreakpoint(seqlen, self.averagefragmentlength)
; |" f- \7 K: l3 Y' i5 @. B # 沿断裂点打断基因组
- i) M5 A3 p9 t2 y, w p/ T: | self.breakgenome(seq_record, breakpoint, self.minfragmentlength, self.maxfragmentlength)2 V$ t4 Q9 d# `0 `2 E* L5 m) `8 A# {
# 模拟克隆时的随机丢失情况: E9 }% ~9 v7 }8 U6 F) m7 _, _9 C
clonedfragmentList = self.clonefragment(self.fragmentList, self.cloneRetainprobability)$ Y" V1 s" k% n. W, K3 T/ T |0 ^
# 模拟单端测序
- f" P X4 ]1 D. a) Q; @ self.singleread(clonedfragmentList)
$ E& F; B! H0 S2 K- L SeqIO.write(self.readsList, sequencingResult, "fasta")0 m1 ]9 f w4 G# l% O
+ y O3 a% a6 y7 T
def pairread(self, clonedfragmentList):8 o- ^2 O# R% a- W' F. B1 \3 \8 x5 {
for fragment in clonedfragmentList:
8 B1 m+ s! ], [, B) o fragment.id = ""# J6 H$ |6 e* f" W! _- ?
fragment.name = ""2 _, o2 s$ S$ E, `
description = fragment.description[12:].split(",")[0]5 m( s1 [; @+ q+ R' d2 o% x7 F
fragment.description = str(self.readsID) + "." + description
9 r; n6 I1 |8 A, H) F readslength = random.randint(self.minreadslength, self.maxreadslength)
1 ?2 v7 f1 h9 _, y2 h self.allreadslength += readslength4 S, ~" c; z- S% @1 B( |1 e
self.readsList.append(fragment[:readslength])' ]2 Q1 \+ y n1 b' w' h' ]
$ t! l+ }8 {; R; v! y% v7 k
readslength = random.randint(self.minreadslength, self.maxreadslength)" H6 M# x* x* ^
self.allreadslength += readslength% Y0 m- S( \- i9 ?0 \. {8 r2 P6 b+ Q
" R7 i: c* x0 e$ C7 u; C+ Q fragmentcomplement = fragment.reverse_complement()1 b0 h9 O/ v$ z9 P
fragmentcomplement.id = ""
i$ U4 Y( w$ R c' Q" g fragmentcomplement.name = ""7 g7 h5 X; o: r1 G4 e! R! ^
fragmentcomplement.description = str(self.readsID) + "." + description
: G) D& }! h* p8 a5 h self.readsList.append(fragmentcomplement[:readslength])
9 O. M4 a1 E$ J2 l- v
7 [; I( A a( q' e3 D! N1 _+ z self.readsID += 1
( G: J) C6 O- v) ]
( R8 P. ^2 s7 O8 i5 u ^/ h def pairreadsequencing(self,genomedata, sequencingResult_1, sequencingResult_2):' H' I9 e& M* ]7 J1 v+ R- d
for seq_record in SeqIO.parse(genomedata, "fasta"):- W9 V) I5 N4 ]' B; k9 `) o$ |
seqlen = len(seq_record)
+ R1 p+ a: D* _' T5 r self.genomeLength += seqlen/ n' Q+ {# y9 w' H8 t
for i in range(self.N):: S. n$ e8 h) P2 e/ Z7 s
# 生成断裂点1 n# ], ?" E) L7 N$ S2 j
breakpoint = self.generatebreakpoint(seqlen, self.averagefragmentlength)& j" V- _5 W* Q" b+ `
# 沿断裂点打断基因组+ ?/ m( S4 M. b- n5 a& ^/ f
self.breakgenome(seq_record, breakpoint, self.minfragmentlength, self.maxfragmentlength)
2 }2 g5 L* z( d( k# i, k" J # 模拟克隆时的随机丢失情况8 m, }' `2 A6 H# ^0 G) R x
clonedfragmentList = self.clonefragment(self.fragmentList, self.cloneRetainprobability)6 R! h- R( ?0 h* {5 ~ e7 T
# 模拟双端测序
" A. c6 H. H% \# f self.pairread(clonedfragmentList)
4 A1 N) @2 L7 Y& p- O/ ]) X readsList_1 = [self.readsList for i in range(len(self.readsList)) if i % 2 == 0]
3 ~8 y/ g0 \0 }# i# K readsList_2 = [self.readsList for i in range(len(self.readsList)) if i % 2 == 1]- j3 [6 s, p+ |! Y0 B2 Q; |
SeqIO.write(readsList_1, sequencingResult_1, "fasta")
. T, i3 S( ?3 W& V SeqIO.write(readsList_2, sequencingResult_2, "fasta")
/ C2 G! Z O: `
8 A1 ]. w7 ~# S9 w5 ?- _: x% b def resultsummary(self):
& V/ ?( n: Z; @- w: E print("基因组长度:" + str(self.genomeLength / 1000) + "kb")3 |) j, s, L9 x5 d, a( V8 w
print("片段长度区间:" + str(self.minfragmentlength) + "-" + str(self.maxfragmentlength))
7 e5 k$ X, q1 L& t5 ^6 i print("N值:" + str(self.N))
, E3 T# c" d1 Y5 `' c( _ print("期望片段长度:" + str(self.averagefragmentlength))
1 S8 j. w( ?, f+ e. f3 Y print("克隆保留率:" + str(self.cloneRetainprobability))
# w+ q3 g5 N* o7 Q; w: Z/ b* l print("片段数量:" + str(len(self.fragmentList)))
" X+ O) y2 I! Q% [& L print("reads长度:" + str(self.minreadslength) + "-" + str(self.maxreadslength))
& i% P, ?$ v1 h6 H print("reads总数量:" + str(len(self.readsList)))
! C* }; j2 H; g print("reads总长度:" + str(self.allreadslength / 1000) + "kb")
8 t6 ]2 x3 D( n1 @0 x2 g) B% t m = self.allreadslength / self.genomeLength
6 t0 J* q( n% U) X print("覆盖度(m值):" + str(round(m, 5)))
( X$ E! `+ |# I3 }% G, L' J print("理论丢失率(e^-m):" + str(round(exp(-m), 5)))
) F. ^$ J0 N, e% G print("覆盖率(1-e^-m):" + str(round(1 - exp(-m), 5)))
- ^$ i) V! h$ f+ C N: I5 ]3 o# -------------------------------------------主程序-------------------------------------------
* a- A7 }, R$ t( @# 模拟单端测序
% _5 i4 y4 L% i' ZsequencingObj = Sequencing()3 _% \% J$ _& M5 X- a8 t
sequencingObj.singlereadsequencing("data/NC_025452.fasta", "result/virusSingleRead.fa")
6 E2 ?0 O: l* A& I3 K3 G9 R: Y2 vsequencingObj.resultsummary(); H; V0 p% M: ^7 P
/ \# R5 O* F9 }0 l8 ]% |% R: Y! r
# 模拟双端测序: r: W( z5 f& G5 I+ n8 y* i% @
sequencingObj = Sequencing()
" w% Y' m9 M/ m% WsequencingObj.pairreadsequencing("data/GCF_000146045.2_R64_genomic.fna", "result/yeastPairRead_1.fa", "result/yeastPairRead_2.fa")
4 i% @ S9 O- QsequencingObj.resultsummary()$ j7 E7 }0 `, U. y
from Bio import SeqIO
T! I1 U3 q3 A* Qfrom math import exp" w7 m4 S! J/ p# x4 b# {
import random4 r1 g T, r1 R4 U$ c1 G0 @6 X j6 t
7 [7 Y4 j# ?/ o
class Sequencing:1 P& `1 u8 Y! ]0 }8 O1 Z) n2 F
# N代表拷贝份数
3 z1 Q4 } g1 X* X def __init__(self):
" ]* c' | h1 y# e' X, ~/ n" c self.fragmentList = []8 d$ w: l& T9 n
self.readsID = 1
: J4 Y' I9 }8 D! `8 a: W self.readsList = []) a$ T6 f( w C$ t M) M7 l# B
self.averagefragmentlength = 6505 z* O3 B- I2 x) |
self.minfragmentlength = 500
7 B% ^ s7 r! O8 ]. s5 U self.maxfragmentlength = 800
8 B: D Q- N; l9 v2 q self.cloneRetainprobability = 10 ?2 _4 O9 V. O, g- F5 G0 e
self.minreadslength = 50
% P/ M! ?0 s+ T* a4 h4 b6 m self.maxreadslength = 150
' a1 S7 N& q8 p& u, F4 p7 N9 x self.N = 10
/ T" n! u9 j+ A) J9 q: c self.genomeLength = 0
9 @: d6 @2 Z9 ^0 J0 U self.allreadslength = 0
% k) h) W+ _2 w& t" t+ [8 Q: W2 y9 s, H8 K$ \9 N/ z. p/ U5 n
# 生成断裂点1 v; d, j$ J( T/ J1 G1 e+ Q
def generatebreakpoint(self, seqlen, averageLength):* w; V6 j& w% g' h! l
# 假设平均每500bp 产生一个断裂点(averageLength = 500),通过随机函数生成seqlen/500个随机断裂点(1到seqlen之间的随机整数). d& _' x' p* m9 A& b7 p- H
breakpoint = [random.randint(0, seqlen) for _ in range(int(seqlen / averageLength))]
+ o$ x9 {7 B5 c7 ] breakpoint.append(seqlen)' ^8 g! v4 a" q: a9 S: d2 [" J
breakpoint.append(0)8 D9 v, a3 N E6 A( m
# 把随机断裂点从小到大排序/ }, X# ]* f0 J) c% P+ Z6 F
breakpoint.sort()
2 S: X3 [0 ~. i! T- o) e+ _ return breakpoint
% m) J/ X, g: |& U4 R
( I0 v' M5 d/ D' }# X" N- S # 沿断裂点打断基因组,并删除不符合长度要求的序列片段,定义片段范围:200-1000bp
0 k* Z1 @" A9 n) }8 ] def breakgenome(self, seq, breakpoint, minfragmentlength, maxfragmentlength):
4 w3 \& {4 x# F/ u# e' n for i in range(len(breakpoint) - 1):* [2 l2 o5 r$ |# i
fragment = seq[breakpoint:breakpoint[i + 1]]8 J; Z; S* e5 w7 Z8 B
if maxfragmentlength > len(fragment) > minfragmentlength:) d# K- W3 v' s
self.fragmentList.append(fragment)% _3 o2 _% X9 B( A) P
return self.fragmentList
+ O# `* l3 r0 z7 @. A, }+ h) }/ d, z( v
# 模拟克隆时的随机丢失情况,random.random()生成0-1的保留概率
+ ^" L8 f& W6 f; P& R/ e def clonefragment(self, fragmentList, cloneRetainprobability):
. p+ d' q( j- s( J4 B) V- S clonedfragmentList = []
1 }9 o: x5 R3 l( a9 ]2 D Lossprobability = [random.random() for _ in range(len(fragmentList))]$ ^, {' m5 j) `& R
for i in range(len(fragmentList)):
0 Z+ ]# R; X4 J1 ? J. `8 l5 t" Z if Lossprobability <= cloneRetainprobability:! W6 i6 Q6 G" Y
clonedfragmentList.append(fragmentList)0 d/ x8 r, ]" j! l, E" q; Z: N8 g
return clonedfragmentList
' w V2 Q t x; g* A( s9 y. n$ \) I7 z- v+ R4 O
# 模拟单端测序,并修改reads的ID号
! ~0 n, M$ `1 a7 Y# ] def singleread(self, clonedfragmentList):8 I' u+ W% D6 {6 t# Z( x
for fragment in clonedfragmentList:+ s3 } y( G A
fragment.id = "", ^) ~* J) s4 ]
fragment.name = ""2 h& ~2 r" b4 L/ i# l) \7 X5 M) X
fragment.description = fragment.description[12:].split(",")[0]
. e4 Q: m l/ g7 w fragment.description = str(self.readsID) + "." + fragment.description8 j% h, w# C- E
self.readsID += 1
+ N1 A: m7 v* [; ~# D/ `6 T readslength = random.randint(self.minreadslength, self.maxreadslength)
% N% \/ D+ C$ v self.allreadslength += readslength
5 n1 a1 O m, V( X self.readsList.append(fragment[:readslength]); P3 d& P( w U0 o1 a# ~4 n& @
0 @1 o" c1 L& k( {' ` def singlereadsequencing(self, genomedata, sequencingResult):: M$ O7 ^) f* O2 E3 W* X
for seq_record in SeqIO.parse(genomedata, "fasta"):2 {; z! h# o# \; T
seqlen = len(seq_record)
$ @% i# D! a: G7 X+ Y self.genomeLength += seqlen% r7 ^$ M8 a9 @8 n1 |) J# o5 m
for i in range(self.N):
: b2 v' _5 k c # 生成断裂点
# S% [9 ~. C7 r2 p breakpoint = self.generatebreakpoint(seqlen, self.averagefragmentlength), Z6 n; Y, L2 w# L+ _. ?( h1 H
# 沿断裂点打断基因组
1 H" g. q' G) I, k' Y! r self.breakgenome(seq_record, breakpoint, self.minfragmentlength, self.maxfragmentlength)
/ t0 c6 } l9 I- [8 m. a # 模拟克隆时的随机丢失情况8 L' H a) K9 X
clonedfragmentList = self.clonefragment(self.fragmentList, self.cloneRetainprobability)8 D) N% n( Q y+ W) w9 Q3 Q( w
# 模拟单端测序0 j4 R5 T7 b7 h% m
self.singleread(clonedfragmentList)9 [1 e6 B* F7 C! m2 V/ i h
SeqIO.write(self.readsList, sequencingResult, "fasta")2 p6 O& L$ M' s
8 _" v- K# `" z& ?7 x def pairread(self, clonedfragmentList):" N; e: w8 ?2 M7 ]8 N
for fragment in clonedfragmentList:# C O; z* ]* l* J0 c" N. q/ {+ L
fragment.id = ""
+ ?1 J$ C0 m3 m2 [ fragment.name = ""
6 N, S* v1 ]2 Y9 e description = fragment.description[12:].split(",")[0]. O. h% B5 A9 \) ?7 r& L: j2 p
fragment.description = str(self.readsID) + "." + description
3 M& {/ D) C5 ]9 w readslength = random.randint(self.minreadslength, self.maxreadslength)1 r# Q: W, a7 k' ^' i
self.allreadslength += readslength
- S! s7 W% }8 j! D self.readsList.append(fragment[:readslength])
* G% ?6 n: {6 k; w1 X& ?* p6 [5 I) i" O' H. v: c5 G
readslength = random.randint(self.minreadslength, self.maxreadslength)
) ?: e" W4 H0 p0 v* l5 ^" ]% V self.allreadslength += readslength1 M2 } Y7 P+ y- K
; I( n2 ]7 K: s4 {8 I7 G3 D- E fragmentcomplement = fragment.reverse_complement()
* w, F8 k( l9 T8 m5 z fragmentcomplement.id = ""
& D% Q* o' U# ~: R& j" j$ [! c fragmentcomplement.name = ""9 I* i' B. v5 x3 [+ D6 a1 [
fragmentcomplement.description = str(self.readsID) + "." + description7 N5 v7 m- @" Q& n1 X2 O
self.readsList.append(fragmentcomplement[:readslength])
7 q) L5 n1 J5 m5 O" n' p# C% } } F- ~( C9 J* U
self.readsID += 1
& J$ l8 u/ K5 F0 @% h
. X8 B* z( v. Q3 ?* W) V0 o def pairreadsequencing(self,genomedata, sequencingResult_1, sequencingResult_2):, r& W6 T0 |1 \3 s) N
for seq_record in SeqIO.parse(genomedata, "fasta"):0 H7 r5 r: ^- I2 U
seqlen = len(seq_record)# h1 E) O9 S2 g2 r2 R
self.genomeLength += seqlen. ^" t/ p1 h9 j2 j! I
for i in range(self.N):4 H# L5 ?) x( Q& N
# 生成断裂点
4 _# R& l3 V, f2 h6 D. ]; A1 O& j breakpoint = self.generatebreakpoint(seqlen, self.averagefragmentlength)( ~. x* R; k* k1 n+ s2 z3 g
# 沿断裂点打断基因组5 N5 i' N8 `( S. f! {
self.breakgenome(seq_record, breakpoint, self.minfragmentlength, self.maxfragmentlength)
% p8 [9 r3 |- Y7 g7 N # 模拟克隆时的随机丢失情况
( A5 K: G6 X( S+ N1 ? v clonedfragmentList = self.clonefragment(self.fragmentList, self.cloneRetainprobability)! b2 `+ L/ T3 `4 ]7 R/ ]: ^
# 模拟双端测序( _3 w- h3 `) R1 }/ |
self.pairread(clonedfragmentList)
( I# t7 y& _3 f; n* D1 R readsList_1 = [self.readsList for i in range(len(self.readsList)) if i % 2 == 0]9 ?& O' |, Z; D; |
readsList_2 = [self.readsList for i in range(len(self.readsList)) if i % 2 == 1]
+ K: ]# |9 e3 ~& u" u SeqIO.write(readsList_1, sequencingResult_1, "fasta")2 C k, \ L3 O6 }, F- S/ G+ N
SeqIO.write(readsList_2, sequencingResult_2, "fasta")
/ ~, q% K" A7 ]) o3 m/ j- A! g6 b+ W x; t
def resultsummary(self):0 B! h& S( t; j9 F+ G
print("基因组长度:" + str(self.genomeLength / 1000) + "kb")
' x' D; y2 Y/ [/ e print("片段长度区间:" + str(self.minfragmentlength) + "-" + str(self.maxfragmentlength))
# W/ {7 Q% f- K' K( O. x! E print("N值:" + str(self.N))1 w* B# R: R) b- V8 \4 n
print("期望片段长度:" + str(self.averagefragmentlength))' N8 E. ?# X- v
print("克隆保留率:" + str(self.cloneRetainprobability))
: Y- [( Y: |& a5 y# d- Q# M3 E; p print("片段数量:" + str(len(self.fragmentList)))
' p- J: ?7 o q4 [5 s print("reads长度:" + str(self.minreadslength) + "-" + str(self.maxreadslength))
+ v" \7 W; X! O/ p4 @0 Z/ Y9 B print("reads总数量:" + str(len(self.readsList)))
: G. i1 E* |/ x: o* j9 y+ H7 ~3 { print("reads总长度:" + str(self.allreadslength / 1000) + "kb")
. h0 ^' g) h1 n$ N( e; b4 f m = self.allreadslength / self.genomeLength2 G& x3 z: g& S( [" @7 r. q; @9 o: E* l* I
print("覆盖度(m值):" + str(round(m, 5)))
7 D! m6 h& _ ^4 j print("理论丢失率(e^-m):" + str(round(exp(-m), 5)))" Q8 l/ s7 e3 f3 ~' o+ M
print("覆盖率(1-e^-m):" + str(round(1 - exp(-m), 5)))
0 e: D6 H9 x7 A+ z& e# -------------------------------------------主程序-------------------------------------------
! |" T1 B! S" Z& |0 L# 模拟单端测序3 z! l- ]: a: j5 u/ {* Y0 u# S4 k
sequencingObj = Sequencing()
0 R# P4 h' K( S! e8 d' FsequencingObj.singlereadsequencing("data/NC_025452.fasta", "result/virusSingleRead.fa")
1 w% a1 d( m& M" `3 k+ _! ?+ A6 zsequencingObj.resultsummary()
' O3 {* E$ i& e6 ?
8 e, y# [. Y0 T/ ]# 模拟双端测序
, L: k. ?8 `- D' Y" J0 w; fsequencingObj = Sequencing()6 w+ q( ~6 \1 u6 u' u0 v6 }' X
sequencingObj.pairreadsequencing("data/GCF_000146045.2_R64_genomic.fna", "result/yeastPairRead_1.fa", "result/yeastPairRead_2.fa")
' p6 n, ]! l0 C; P$ { BsequencingObj.resultsummary()! k& v! `, B. M) e1 m' I
& S) U" a1 x1 E+ l4 D$ k
2 L8 i# N: \0 D4 Z
" ? k5 w- V! j! g9 v( W+ Y* g+ f8 M
, ?7 l/ B- C: {: }8 p
|
zan
|