- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 566771 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 175254
- 相册
- 1
- 日志
- 0
- 记录
- 0
- 帖子
- 5313
- 主题
- 5273
- 精华
- 3
- 分享
- 0
- 好友
- 163
TA的每日心情 | 开心 2021-8-11 17:59 |
|---|
签到天数: 17 天 [LV.4]偶尔看看III 网络挑战赛参赛者 网络挑战赛参赛者 - 自我介绍
- 本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。
 群组: 2018美赛大象算法课程 群组: 2018美赛护航培训课程 群组: 2019年 数学中国站长建 群组: 2019年数据分析师课程 群组: 2018年大象老师国赛优 |
基因组测序模拟
7 ^6 q. a4 M8 s! Q1 I基因组测序模拟7 f6 K( p( M2 j7 U% Q9 i
9 @, k- q7 c. P5 Y1 R) D) P一、摘要" N2 @6 i* `4 m8 Q5 J, D$ A
% z; q; n ?1 m/ |
通过熟悉已有的基因组测序模拟和评估程序,加深全基因组鸟枪法测序原理的理解,并且能够编写程序模拟全基因组鸟枪法测序,理解覆盖度、测序深度、拷贝数等概念,设置测序相关参数,生成单端/双端测序结果文件- q8 O. Q$ x1 h* ^3 C
( s" ?: _, X5 Y- ?1 }3 E
二、材料和方法/ `5 J* z" B, X/ O) i/ o( i
& l F0 c7 B. X0 a- p( P8 `$ E% H& b
1、硬件平台: H$ t5 {* G* h
3 z" E/ X/ I: H) b# j5 Z0 N: ^) ~
处理器:Intel(R) Core(TM)i7-4710MQ CPU @ 2.50GHz @. @& p5 j1 {
安装内存(RAM):16.0GB
* ~ @* ~8 l& Z- D+ }2 f% j/ J& O- n& W
2、系统平台
0 _; p% w) l. ^# O# MWindows 8.1,Ubuntu
# S( } J$ \% Y# m5 H
7 O% B' n# s% v3、软件平台; ?& F8 e% b7 ]
3 v7 ~% x+ ~: V+ w
art_4548 C6 p8 l, K, m7 k: e
GenomeABC http://crdd.osdd.net/raghava/genomeabc/; @3 ]& @7 i" n* T$ ]
Python3.5
( c' d. J. [0 A# x' S5 DBiopython
8 S) \ y! t, w4、数据库资源7 ^1 P, x& s* j
/ A$ B; w4 f: j
NCBI数据库:https://www.ncbi.nlm.nih.gov/
, q/ c" L1 t( s8 S/ a" W# U1 R3 E: n9 F6 V; _) \. \0 W! c" [
5、研究对象
* C0 n* I' E& Z6 N: V- ?1 S7 C4 v7 k6 P2 |- v" b* E
酵母基因组Saccharomyces cerevisiae S288c (assembly R64) 9 O) y, w& w/ V$ S F2 N
ftp://ftp.ncbi.nlm.nih.gov/genomes/all/GCF/000/146/045/GCF_000146045.2_R64/GCF_000146045.2_R64_genomic.fna.gz
, x+ s4 o6 ~, P9 ?7 U6 K {# |$ b5 G0 z1 K' P
6、方法; x7 ~6 z. b8 n
8 v/ L, t. a% t. N) |" s' B
art_454的使用
- m N2 |, @% Q: R w% x首先至art系列软件的官网,下载软件,在ubuntu系统安装,然后阅读相关参数设置的帮助文档,运行程序。
x- ?5 s* f% B, ~' }GenomeABC % \2 D* F( f; b- [2 @3 k
进入GenomeABC(http://crdd.osdd.net/raghava/genomeabc/),输入参数,获得模拟测序结果。
6 q( J7 Y( m8 m; @! P- g( V编程模拟测序
6 {9 F% ?8 F3 v. p# F下载安装python,并且安装biopython扩展模块,编写程序,模拟单端/双端测序。; X7 f4 T. t) c" [/ O& L
三、结果6 }; i" y2 l f' k* f
! c. A0 V8 x' U- I! D/ _% c! V
1、art_454的运行结果. S7 o; I; B9 A8 o2 f2 `( f1 }
) [; U$ K+ u6 d- h
无参数art_454运行,阅读帮助文档
5 `3 M, Q' ?2 c) Z6 ] `" B! S/ X$ u$ {4 f( N. ]) b
图表 1无参数art_454运行
0 [2 l6 m) {+ H7 \对酵母基因组进行基因组单端测序模拟,FOLD_COVERAGE设为20,即覆盖度为20. * ~; U7 ^* P# q% ]
下图为模拟单端测序,程序运行过程及结果 g$ \" c* e9 t/ i- n0 k) ~1 T
! E7 o% j" L4 o8 h' r; ]图表 2 art454单端测序 / w9 l+ M' |+ I
5 J, `$ Q& t5 d# `$ B' @
图表 3 art454单端模拟结果
: w' i2 y% i# l; j- J0 x双端测序模拟,FOLD_COVERAGE设为20,即覆盖度为20;MEAN_FRAG_LEN设为1500,即平均片段长度为1500;STD_DEV设为20,即长度的标准差为20
: H0 E; ^( p3 ?下图为模拟双端测序,程序运行过程及结果 ) V: T. ^) \, z, H& N$ Z9 I6 x* o# |: _
; c& t! Z6 h6 J# h2 f
图表 4 art454双端测序
. f1 ?1 }# I3 b/ B
0 S, z+ ~* t2 t V3 F图表 5 art454双端模拟结果 8 W: }% }5 D& k. Q' q' ]
2、GenomeABC " K; h- d& r5 p O6 @
下图为设置参数页面 ( c0 [$ i i; \, ?8 c ^) p2 t; d
& X4 ?# l# D" c' ?4 p1 a
下图为结果下载页面
- l2 \! P+ U2 ?" B5 P
1 F8 H+ x2 U$ k1 \* k% R图表 6 结果下载页面 . l t& p+ s) g! ~3 B/ |* i
3、编程模拟测序结果 $ X- V% M+ ~7 Z- N
拷贝数是这里的N值;覆盖度是m,测序深度是宏观的量,在这里与覆盖度意思相同,就是测序仪10X,20X。 " M4 v. a" i: w4 Q8 M& \* ^
单端测序
1 v# x# _: c4 r. N1 |3 y3 B* b- Q9 Y
图表 7 程序模拟单端测序 & A6 q3 a0 `0 p2 S+ u8 d; h8 T
双端测序
6 [- a' k; Q5 V5 T) a8 j, R% m& Z
) p5 }- K# x9 y# o7 l图表 8 程序模拟双端测序 ; s. ?) }( ?/ Q) ?
测序结果
% j2 D- F, Y4 o8 J1 _0 d( E! @3 o( x# ]- `7 w
图表 9 结果文件
3 W3 m' j5 [$ Q$ y: P' D9 Y0 k& y4 i3 ^
因为期望片段长度是600bp,在片段长度区间200-1000bp内,所以大部分的片段都没有删除。
. I3 g C( @/ l! f! d8 U测序结果统计表3 b+ p5 h% J- f. I
; J. m5 _0 M3 `# M
测序方式 基因组大小(bp) 片段长度区间 (bp) N值 期望片段长度 克隆保留率 片段数量 Reads长度范围(bp) Reads总数量 Reads总长度 覆盖度(m值) 理论丢失率(e-m) 覆盖率(1-e-m)
( p# S7 y' P1 w单端 12157kb 200-1000 10 600 0.95 107378 50-100 101968 7645.541kb 0.62889 0.53318 0.46682, _; y9 o$ b& C2 T& g
单端 12157kb 200-1000 20 600 0.95 213722 50-100 202996 15227.882kb 1.25259 0.28576 0.71424" y0 n/ ]( z: j0 o
双端 12157kb 200-1000 10 600 0.95 106704 50-100 202770 15212.662kb 1.25134 0.28612 0.71388, g$ T& c+ q% R. f( l
双端 12157kb 200-1000 20 600 0.95 214212 50-100 407186 30534.265kb 2.51164 0.08114 0.91886, ?) j6 h$ }1 s' ]7 s! ]$ U5 K: X
四、讨论和结论1 L5 N$ { o8 p0 q( c* ]3 K
6 i g1 j& b1 r0 ]1 J* G! J程序运行方法
; p" G! [, ?, j) d. n5 ?3 Y9 _% x' m# p: V3 d
在类的构造方法init()中,调整参数。 - Q( q8 O1 n+ H; y7 c# i
Averagefragmentlength为片段平均的长度; 1 E b' U+ ~$ H6 S! f& W4 E
minfragmentlength和maxfragmentlength是保留片段的范围;
. ?- N4 z* k% ^2 L5 f2 P% |5 x$ f) VcloneRetainprobability是克隆的保留率;
, [0 A, s7 W. `' C. D! K5 p) o& ^minreadslength和maxreadslength是测序reads的长度范围
; V+ |+ N6 Q" S" T3 {. O) Q" ? O$ q! l# D9 a$ f* N
模拟测序的诸多方法都封装成了Sequencing类,只需要创建类,并调用singlereadsequencing()和pairreadsequencing()方法,传入文件名的参数即可。8 R$ i' `# `1 H5 n6 V
' L$ D& p9 i! @% q4 U附录
4 R3 R' F! t# n2 W N+ x. ~2 i- R+ y% w! J7 @7 O
from Bio import SeqIO
/ v# b4 V( f2 s2 Gfrom math import exp
3 ?# w1 S# q M( l/ nimport random( d& U5 Q; l/ I, V
# _ r7 A8 g; F( s. lclass Sequencing:) [, g# l3 E9 Z/ o9 [
# N代表拷贝份数
( N- T; N+ q, ]3 ` def __init__(self)# L" J) P1 M! E7 D8 Y8 p* u
self.fragmentList = []3 v& G u3 F/ @& m2 V& v6 ~9 x2 \
self.readsID = 1
1 w+ S: [7 K% D( V6 P/ O; p0 y self.readsList = []
# E1 ^( a2 p( ^) v% \8 j/ v+ t1 {, b* f0 { self.averagefragmentlength = 650
! L& \, Y2 r3 A. ~2 l2 z self.minfragmentlength = 500+ t5 x- c. z5 d; G; p" h' T
self.maxfragmentlength = 800
6 T4 Z8 _" x- L! s self.cloneRetainprobability = 1
3 c$ v2 K$ U: ? R) c) S+ f8 H self.minreadslength = 50 y3 u0 N" \7 T3 D& O2 k
self.maxreadslength = 150
0 e9 }6 x# D0 T$ V! H self.N = 10
; K/ w: u$ L3 W: a/ s; h self.genomeLength = 0" R0 G! f) X5 M
self.allreadslength = 0 E8 V& F5 a# I+ f" r$ {
& a! i1 F5 f" A9 I# a+ p
# 生成断裂点
- U j' E! a$ ?$ ~: D! p5 f4 `6 x def generatebreakpoint(self, seqlen, averageLength):
3 Y2 v, `6 w5 B+ { # 假设平均每500bp 产生一个断裂点(averageLength = 500),通过随机函数生成seqlen/500个随机断裂点(1到seqlen之间的随机整数)# c! c$ v6 r5 Q& B9 t
breakpoint = [random.randint(0, seqlen) for _ in range(int(seqlen / averageLength))] r1 q0 ?8 A$ K9 A2 R- C
breakpoint.append(seqlen)# w' k" d& g$ Y) u- Q6 I4 v
breakpoint.append(0)' S/ \" p) S' V: Z
# 把随机断裂点从小到大排序
. [" R3 c( l6 z7 L: A breakpoint.sort()
2 Q9 ?" Y/ A* \' R% l/ m% O return breakpoint
8 ~" W! d2 R1 ^8 W1 s3 @! |3 ]2 @+ Z c# b; B1 [6 X
# 沿断裂点打断基因组,并删除不符合长度要求的序列片段,定义片段范围:200-1000bp+ U' f* ^9 y8 y7 m4 s& O7 o
def breakgenome(self, seq, breakpoint, minfragmentlength, maxfragmentlength):
6 k$ J7 z& M( `/ }0 h6 a1 \ for i in range(len(breakpoint) - 1):
% Y1 Q. ^' ]& A E, K fragment = seq[breakpoint:breakpoint[i + 1]]9 {! K. b2 E0 R' Y& @
if maxfragmentlength > len(fragment) > minfragmentlength:4 D, P2 d7 U5 y$ B; v
self.fragmentList.append(fragment)
! I6 H# a" n( ? return self.fragmentList" h0 N9 e3 @$ W5 Y
% ]. ]' E8 p" A) C& a7 d$ ?
# 模拟克隆时的随机丢失情况,random.random()生成0-1的保留概率) ?& q) y2 m$ Z4 e: F y
def clonefragment(self, fragmentList, cloneRetainprobability):; s7 o5 h8 [% q. _* n/ b$ U# l
clonedfragmentList = []/ o: E* E" O2 F$ j3 A/ R
Lossprobability = [random.random() for _ in range(len(fragmentList))]
0 W4 ^' D: `% g/ r& O" {3 K for i in range(len(fragmentList)):+ O+ J! H" P' p1 [. q4 L k: \. ^
if Lossprobability <= cloneRetainprobability:
9 N# }) t1 a& j clonedfragmentList.append(fragmentList)" J, o2 I4 G: s$ H# ~
return clonedfragmentList
) g6 i& m9 q9 u; A$ |3 \. l0 O- R# e% o6 ^. q& T
# 模拟单端测序,并修改reads的ID号& m5 c: |* _. U8 o
def singleread(self, clonedfragmentList):. `. o) }" `. B4 Q2 i
for fragment in clonedfragmentList:
6 B9 R x- W: r) y' m) @' [ fragment.id = ""
8 _$ |8 E" l- p3 a& o" u) T fragment.name = ""* _9 ~- v1 ]) ]
fragment.description = fragment.description[12:].split(",")[0]
: P# X: }* a9 N. t) T5 T, i fragment.description = str(self.readsID) + "." + fragment.description/ r9 @. P% J( {# O# ^
self.readsID += 1
2 K$ \* q5 D& [# {1 G5 | B readslength = random.randint(self.minreadslength, self.maxreadslength)
d7 W+ T8 O8 F9 i+ q2 n0 C: ], C self.allreadslength += readslength
; Y( a# S O, @+ j+ z2 {# `: X' u$ S self.readsList.append(fragment[:readslength])# ?8 ]$ n4 e+ c
5 d/ w7 s0 I% y, `5 ? def singlereadsequencing(self, genomedata, sequencingResult):
$ T3 Y! b1 [. }( x5 b for seq_record in SeqIO.parse(genomedata, "fasta"):
* G. j' Q! |, [& J5 M* M* ^( Z seqlen = len(seq_record), f1 l, u6 _2 l9 d( V
self.genomeLength += seqlen
+ a0 m7 K% h- ~1 v K1 E I% [0 e for i in range(self.N):2 [5 Y# Y- c! S/ d
# 生成断裂点3 ?" ~7 P( i2 O$ Y( R
breakpoint = self.generatebreakpoint(seqlen, self.averagefragmentlength)
" s- o( W& p0 Q ^, e # 沿断裂点打断基因组
( \9 W: L/ v @' Z0 z: ^ self.breakgenome(seq_record, breakpoint, self.minfragmentlength, self.maxfragmentlength)
2 k) k0 R7 ]" Y2 V" z* i" s( ]+ d # 模拟克隆时的随机丢失情况; h" I& ^2 D! h1 R
clonedfragmentList = self.clonefragment(self.fragmentList, self.cloneRetainprobability)& G2 I9 Y7 ]. D0 ], _8 y5 P
# 模拟单端测序0 m7 H M, r" O$ Q' R
self.singleread(clonedfragmentList)( p, d. x3 R0 E/ u/ M, K
SeqIO.write(self.readsList, sequencingResult, "fasta")8 p0 o# M; T6 |) `
! w, V f- Y: h$ B6 {) s, r def pairread(self, clonedfragmentList):
% D6 T$ j9 P' X6 P) S" u; T' }2 Y for fragment in clonedfragmentList:
4 q1 K9 L& P7 ~* K% {1 K! w6 C fragment.id = ""
" h( B% a- } z; G0 D fragment.name = ""5 R% T8 z" Z5 S4 D! l* o) Z. G) d3 j
description = fragment.description[12:].split(",")[0]
9 R( O2 B9 O& T& I9 ? fragment.description = str(self.readsID) + "." + description
A* X A* C. R2 w readslength = random.randint(self.minreadslength, self.maxreadslength)
1 x, o3 ~( H! x- S self.allreadslength += readslength7 G+ d8 V6 X4 Q$ V8 ] l
self.readsList.append(fragment[:readslength])" T' {, p% A. J9 O x8 g* h. t, u
3 k7 ]$ _6 {: J2 Z& [4 P readslength = random.randint(self.minreadslength, self.maxreadslength)
+ C7 x/ i: V% n( j self.allreadslength += readslength
3 l5 Y. d+ [+ J+ y- O/ j
+ ~: _: V( s$ C1 m+ c fragmentcomplement = fragment.reverse_complement()) n0 H, A) [* X$ E6 N' Y
fragmentcomplement.id = ""
9 W$ _0 y* I( `& t: W- o# F fragmentcomplement.name = ""$ n( w+ }7 O2 X: L
fragmentcomplement.description = str(self.readsID) + "." + description
% A) s# M4 ^5 _8 ?; d5 V$ ~ self.readsList.append(fragmentcomplement[:readslength]): F/ o- ]# z) i4 B6 |3 o, p5 S
, o, I# G4 Y ~4 `: L& U! Z" o self.readsID += 1
' j1 \) o# R1 R( U. l& l f) g
! O( p# ], d2 b1 ~: D8 l def pairreadsequencing(self,genomedata, sequencingResult_1, sequencingResult_2):, {: G& m0 b( n- ]/ \
for seq_record in SeqIO.parse(genomedata, "fasta"):
, M, \( k& z1 Y. a3 ~2 t5 ]2 ~9 k/ X seqlen = len(seq_record)5 l x9 ?, S) ~# r; j
self.genomeLength += seqlen
( R* Y! O' C$ y4 O. x" \! M for i in range(self.N):
; ^, ^5 M2 b' e( ~2 Y # 生成断裂点3 h ^9 ~0 t3 }* [0 n! C% a3 \
breakpoint = self.generatebreakpoint(seqlen, self.averagefragmentlength)) B, T7 n3 ]" z+ d0 j5 K
# 沿断裂点打断基因组& q+ w3 k$ ^# A( N" U) q- e5 F
self.breakgenome(seq_record, breakpoint, self.minfragmentlength, self.maxfragmentlength)0 i) a) v4 E" ]4 u
# 模拟克隆时的随机丢失情况9 Q: n3 e6 A2 C" }" o+ |2 k5 ]* Z
clonedfragmentList = self.clonefragment(self.fragmentList, self.cloneRetainprobability)& X& }% m) ^; Q7 t
# 模拟双端测序9 N, J3 O3 g5 `& c$ R4 {0 S
self.pairread(clonedfragmentList)7 B2 y: I* m$ f8 K: l9 g
readsList_1 = [self.readsList for i in range(len(self.readsList)) if i % 2 == 0]4 V; E- a6 `* c
readsList_2 = [self.readsList for i in range(len(self.readsList)) if i % 2 == 1]; @. l4 L7 O6 M# i7 R
SeqIO.write(readsList_1, sequencingResult_1, "fasta")
t8 O+ L% A( F; G4 P( u SeqIO.write(readsList_2, sequencingResult_2, "fasta")* F# M* ~ ~3 T! R
: G- C% F: g3 r# G+ q6 H def resultsummary(self):
/ X' A- [' n5 m- Q print("基因组长度:" + str(self.genomeLength / 1000) + "kb")
7 A: |9 L( u) B" _! f: n print("片段长度区间:" + str(self.minfragmentlength) + "-" + str(self.maxfragmentlength))
# _# K2 e$ X. o$ S print("N值:" + str(self.N))
! M) K" K8 r9 m4 ?5 T8 h* | print("期望片段长度:" + str(self.averagefragmentlength))/ c7 R4 L6 A* a
print("克隆保留率:" + str(self.cloneRetainprobability))5 [- ?% p: v$ S( F! b; G$ Q4 Z
print("片段数量:" + str(len(self.fragmentList)))
z& Y& E4 _! p7 J3 T; Y print("reads长度:" + str(self.minreadslength) + "-" + str(self.maxreadslength))6 L5 ~# B3 u( T- m3 g7 p3 B7 t
print("reads总数量:" + str(len(self.readsList))) ~6 w0 W: G# k1 \4 N M( j i
print("reads总长度:" + str(self.allreadslength / 1000) + "kb")
7 o* t' h3 |$ M0 ^6 s m = self.allreadslength / self.genomeLength! @. d% H$ f4 r4 D( u1 d: @" U
print("覆盖度(m值):" + str(round(m, 5)))
, d" m+ p; @) X" I6 H" \1 ` print("理论丢失率(e^-m):" + str(round(exp(-m), 5))) w! }) i/ p% d% D4 o6 r( {' a
print("覆盖率(1-e^-m):" + str(round(1 - exp(-m), 5)))
3 ]9 Y% \1 J; _5 N1 ~# -------------------------------------------主程序-------------------------------------------
8 i# a7 X7 o" S2 ~) h% g# 模拟单端测序' w* H3 W/ z* j5 O" \& d
sequencingObj = Sequencing()
2 o: |- l' m* y! i A! e& ]sequencingObj.singlereadsequencing("data/NC_025452.fasta", "result/virusSingleRead.fa")
# v/ O; K' d% ~3 Q+ DsequencingObj.resultsummary()' u2 Z; F( p6 M: X
; d5 W5 Q; n0 {# 模拟双端测序! b9 @5 Y- O' \9 z1 ]# o
sequencingObj = Sequencing(); w- b; i' c) x8 X" O
sequencingObj.pairreadsequencing("data/GCF_000146045.2_R64_genomic.fna", "result/yeastPairRead_1.fa", "result/yeastPairRead_2.fa")+ A. M9 T4 n& T- h: _9 h; m
sequencingObj.resultsummary()( S6 B# z9 i5 R% l4 O( `
from Bio import SeqIO
; X6 l5 _/ Q* n9 n9 U" afrom math import exp8 h5 k! q: H6 B1 Z- F9 }. x6 q4 M
import random
: x4 o# k$ ^" e/ \: E& K- r a" ~1 t" _7 E# \ p
class Sequencing:
. u6 _. Z: D! g1 l" r9 H # N代表拷贝份数
" K# x' ]6 K) [* C! W def __init__(self):
6 F. W" q+ o; C/ |$ d self.fragmentList = []
6 J+ U% Q# C! s; l$ A: p self.readsID = 1
) z6 F$ u2 l& z4 O, Y2 u self.readsList = []5 [+ a5 c6 h6 G w; \" x* m- P
self.averagefragmentlength = 6500 J7 W2 j; f9 Q6 V8 l6 {( I8 V
self.minfragmentlength = 500
, z- @/ w/ w8 u1 }; |! r4 q2 g self.maxfragmentlength = 800
9 Z8 e& h& F& f+ N8 e, R self.cloneRetainprobability = 1
" O" j7 u1 E7 p2 |* C: H- {. _ ]# c self.minreadslength = 50( A6 q1 b4 a( k* ]
self.maxreadslength = 150- C* i! R; P8 A0 I1 n
self.N = 10; H7 d/ S8 T- C3 G1 Y, ?2 z1 _
self.genomeLength = 0
9 u1 k' [% ]# u/ s2 x self.allreadslength = 05 _" j; Y3 \, g1 O% C1 P. k6 f
' `0 u+ v4 P1 V; L # 生成断裂点
. ]. H# U, u0 \ def generatebreakpoint(self, seqlen, averageLength):
; b8 y( ]! e r7 Z # 假设平均每500bp 产生一个断裂点(averageLength = 500),通过随机函数生成seqlen/500个随机断裂点(1到seqlen之间的随机整数)5 y1 \% z2 v6 f
breakpoint = [random.randint(0, seqlen) for _ in range(int(seqlen / averageLength))]8 u0 f. i9 F+ U. K9 X
breakpoint.append(seqlen)
I; K' _. N# F2 s& A8 ?/ O* e& C; Q breakpoint.append(0)
0 g3 s0 w9 e) q9 Y* l0 ?* M # 把随机断裂点从小到大排序; _* g1 F/ |0 V! [! K
breakpoint.sort(), S& N: Q( t2 t& k( a
return breakpoint
' m& o2 p x7 T' \% | O( Z) B2 W5 }0 |! R: t% O9 k0 n
# 沿断裂点打断基因组,并删除不符合长度要求的序列片段,定义片段范围:200-1000bp q' M4 q, V: u8 r
def breakgenome(self, seq, breakpoint, minfragmentlength, maxfragmentlength):
1 Z: k5 @4 @. _5 V- G: u! y# } for i in range(len(breakpoint) - 1):
4 K- `) t; _: q1 z4 i6 k6 f fragment = seq[breakpoint:breakpoint[i + 1]]; F/ ?& t. [" q, y3 ]& |
if maxfragmentlength > len(fragment) > minfragmentlength:
! J+ p2 v2 M! Y% p% p2 G self.fragmentList.append(fragment)
8 W3 K* f( S2 }: D! X1 l+ { return self.fragmentList
, Q/ e) f, S( {. x& E* X
6 N* `# B8 s& V # 模拟克隆时的随机丢失情况,random.random()生成0-1的保留概率5 r1 q/ |; F; e
def clonefragment(self, fragmentList, cloneRetainprobability):
$ B/ ?. F& A2 R- \ clonedfragmentList = []/ S) K: o9 T( H9 \5 O
Lossprobability = [random.random() for _ in range(len(fragmentList))]6 V6 ?+ N0 I1 ~7 @8 X4 p
for i in range(len(fragmentList)):
7 G9 }1 b! C+ s: U0 s! e if Lossprobability <= cloneRetainprobability:
. H# v8 Z# Y6 K# b# J; P clonedfragmentList.append(fragmentList)2 H6 |1 [( B5 n( a3 `- F% b1 L
return clonedfragmentList4 w* ?* W( S% R
2 N0 B- L; }& \' y
# 模拟单端测序,并修改reads的ID号
p" |4 S; M F) C6 w* R def singleread(self, clonedfragmentList):
6 p9 w( j% ?" [ for fragment in clonedfragmentList:
5 d Z9 w# K% H& x& o/ g fragment.id = ""4 J* U/ Q5 j% {( }
fragment.name = ""% k/ a: Q- J9 U' [( e
fragment.description = fragment.description[12:].split(",")[0]
. _0 D- M. C7 f/ i2 B fragment.description = str(self.readsID) + "." + fragment.description9 o3 v; D/ W- d# @# C! N$ I
self.readsID += 19 _; f+ i+ V7 H/ y/ ]
readslength = random.randint(self.minreadslength, self.maxreadslength)* r; A7 E( q" J k( ^. V+ ^
self.allreadslength += readslength; l( W" I% Z+ n+ Y$ m+ i. _5 L2 x
self.readsList.append(fragment[:readslength])
. ~- V, v/ n) x( J/ @- x, E' K8 u+ R( r. z& z- P' v6 S
def singlereadsequencing(self, genomedata, sequencingResult): H! s3 y* `' m# O
for seq_record in SeqIO.parse(genomedata, "fasta"):0 Q; ^% L* q: Y# @, ]
seqlen = len(seq_record)0 J( r7 R0 b( @9 g1 W
self.genomeLength += seqlen
" O6 [- o, a: o& I+ ` for i in range(self.N):2 {) B% _# T% l. a% B
# 生成断裂点2 x1 z: q7 k/ p5 a1 ~+ B+ S2 q
breakpoint = self.generatebreakpoint(seqlen, self.averagefragmentlength)
' u3 F: z8 s; F5 Q4 l. T$ l$ Y2 m% d # 沿断裂点打断基因组
7 J. o& y; t4 K5 `; Z self.breakgenome(seq_record, breakpoint, self.minfragmentlength, self.maxfragmentlength)
& A2 x* ]9 {1 D m/ S7 q$ L" P # 模拟克隆时的随机丢失情况
; x4 U% N9 B2 H- C# W clonedfragmentList = self.clonefragment(self.fragmentList, self.cloneRetainprobability)6 h/ f9 z/ d0 ~9 @
# 模拟单端测序
{2 `* o7 k. ? self.singleread(clonedfragmentList)- ~7 \# r5 M' P% S$ d% v+ P
SeqIO.write(self.readsList, sequencingResult, "fasta")
( w: ^3 A5 f( p# b
: y) f& I" K- K) u def pairread(self, clonedfragmentList):" _2 p* I; J8 c! t' m: R
for fragment in clonedfragmentList:6 C0 q+ P& u' g, f. ~8 z7 \
fragment.id = ""
5 c# m/ k9 c7 A% _; e fragment.name = ""6 L+ B% [ G' D, q) V/ U* i$ h
description = fragment.description[12:].split(",")[0]# y3 f4 h6 ^8 L: B" p2 S; E$ t
fragment.description = str(self.readsID) + "." + description
$ b/ X. S8 T( z7 F' _ readslength = random.randint(self.minreadslength, self.maxreadslength)% q! y( D* t5 j5 r
self.allreadslength += readslength% j7 y' W& H- `& o" N6 v. o) ~ t
self.readsList.append(fragment[:readslength])) s/ E6 ]7 T/ @; T X
, O" h! q! E0 G% p; F- r
readslength = random.randint(self.minreadslength, self.maxreadslength)
6 a5 @- }3 B! t- X( a: a2 ~: \ self.allreadslength += readslength
4 J- B3 @$ o. x; p9 B# h
+ E. K+ [" U1 i( y fragmentcomplement = fragment.reverse_complement()' d. ]; P) |: k! @- t- e/ S
fragmentcomplement.id = ""8 D3 M. r- v/ o
fragmentcomplement.name = "", W; M! D$ J' g& }- K
fragmentcomplement.description = str(self.readsID) + "." + description% C7 f, |$ `' p3 ~
self.readsList.append(fragmentcomplement[:readslength])
0 y* [1 S! V6 Q- d8 X7 n# K2 y
. n- q/ m. h/ g3 t self.readsID += 1( C" J7 f7 m: c' S) h* E
: Y0 O% [4 d$ q! B* a8 n4 w% a
def pairreadsequencing(self,genomedata, sequencingResult_1, sequencingResult_2):
8 |6 \* {; y% [. [! x for seq_record in SeqIO.parse(genomedata, "fasta"):! v: S+ P' m6 A+ v+ ~* ~ x
seqlen = len(seq_record)
% V0 w- D |& @6 I self.genomeLength += seqlen; w- C* x9 k. n) _# ?6 N
for i in range(self.N):
( j9 c# C3 [+ b9 B, g # 生成断裂点
. o3 V3 j1 i4 K2 _ breakpoint = self.generatebreakpoint(seqlen, self.averagefragmentlength); g. \% B9 k% f. ^! Z$ R1 G
# 沿断裂点打断基因组% ^4 z% }2 C1 B5 [( u2 c
self.breakgenome(seq_record, breakpoint, self.minfragmentlength, self.maxfragmentlength)
- c, D9 T2 u' ^ # 模拟克隆时的随机丢失情况
$ @- h0 H& g( N& S0 ^* W clonedfragmentList = self.clonefragment(self.fragmentList, self.cloneRetainprobability)- f9 @( l& a3 t5 t6 D" Z, v3 E3 E& Z
# 模拟双端测序
3 |2 x' ~. \2 y% _ ` self.pairread(clonedfragmentList)
( n* K8 X7 d1 K5 J readsList_1 = [self.readsList for i in range(len(self.readsList)) if i % 2 == 0]
$ T* b. n* j3 \, s4 Z0 t' | readsList_2 = [self.readsList for i in range(len(self.readsList)) if i % 2 == 1]6 }2 \) _7 ?' b" y
SeqIO.write(readsList_1, sequencingResult_1, "fasta")
/ G* N. @6 o1 f( l SeqIO.write(readsList_2, sequencingResult_2, "fasta")
! X2 L8 \) G# P% D; N. c4 e' B% Z& M* l1 b# U" N6 Q! r
def resultsummary(self):
4 T7 N% ?* r- R( p8 m* r print("基因组长度:" + str(self.genomeLength / 1000) + "kb")0 [1 v% W; h: F
print("片段长度区间:" + str(self.minfragmentlength) + "-" + str(self.maxfragmentlength))
% Q' E6 Z6 _0 ^' M i print("N值:" + str(self.N))
N% S# X5 w' l) d print("期望片段长度:" + str(self.averagefragmentlength))
" [4 ?3 G5 v% t/ X. z, n print("克隆保留率:" + str(self.cloneRetainprobability))
* B% j( X9 Q$ | K print("片段数量:" + str(len(self.fragmentList)))
5 L* L* T, C7 q* J1 H2 J7 P print("reads长度:" + str(self.minreadslength) + "-" + str(self.maxreadslength))
" `- G. I- h) ~9 i# v print("reads总数量:" + str(len(self.readsList)))
8 j9 y- }, [1 s+ Q& j1 P print("reads总长度:" + str(self.allreadslength / 1000) + "kb")
6 I8 Q4 a. l9 \% s% L m = self.allreadslength / self.genomeLength
! r, j6 [ c4 y4 h& \3 Y( T print("覆盖度(m值):" + str(round(m, 5)))8 N' q" K M. l Z& H" M
print("理论丢失率(e^-m):" + str(round(exp(-m), 5)))
" i$ z. u$ i& H$ S! i5 H+ J1 s print("覆盖率(1-e^-m):" + str(round(1 - exp(-m), 5)))' k: r: h; l9 a1 E) r( H0 ^7 x) F. J
# -------------------------------------------主程序-------------------------------------------/ t) a9 W: D/ S2 @3 \' f
# 模拟单端测序9 M& e; t3 A( n
sequencingObj = Sequencing()
3 v& ?7 R8 E2 @" gsequencingObj.singlereadsequencing("data/NC_025452.fasta", "result/virusSingleRead.fa")
! `8 s8 M- K; B* O0 rsequencingObj.resultsummary()
+ f, L+ F+ y% Q+ S1 M% w5 u
2 e' a5 e+ |( l2 B! k/ M: L) B# 模拟双端测序4 k$ j# i/ c: q* Z' i' o
sequencingObj = Sequencing()& y& _8 L9 Z" H' x4 W7 ^+ D3 n
sequencingObj.pairreadsequencing("data/GCF_000146045.2_R64_genomic.fna", "result/yeastPairRead_1.fa", "result/yeastPairRead_2.fa")
) n8 v g2 H# }3 O% P% B6 ssequencingObj.resultsummary()
0 j5 ]0 g, m0 e% T' n
# w- P% Q' n X) ]( S/ S0 j0 z' e' L& N8 w9 S9 N. [
% P. i/ [9 L" f9 c0 i3 N" t 1 @1 [+ W. F4 |4 v+ y: P
|
zan
|