- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 566767 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 175253
- 相册
- 1
- 日志
- 0
- 记录
- 0
- 帖子
- 5313
- 主题
- 5273
- 精华
- 3
- 分享
- 0
- 好友
- 163
TA的每日心情 | 开心 2021-8-11 17:59 |
|---|
签到天数: 17 天 [LV.4]偶尔看看III 网络挑战赛参赛者 网络挑战赛参赛者 - 自我介绍
- 本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。
 群组: 2018美赛大象算法课程 群组: 2018美赛护航培训课程 群组: 2019年 数学中国站长建 群组: 2019年数据分析师课程 群组: 2018年大象老师国赛优 |
基因组测序模拟
, N* S U+ s, M; q1 Q基因组测序模拟/ B' x7 O+ l m$ ]3 G/ W
6 Z3 }7 s5 n0 c! [! `& N
一、摘要; j; V3 R* Z5 E- A9 d0 F( Y+ o
1 n* `/ j, d0 X8 S! j( X% ~7 e通过熟悉已有的基因组测序模拟和评估程序,加深全基因组鸟枪法测序原理的理解,并且能够编写程序模拟全基因组鸟枪法测序,理解覆盖度、测序深度、拷贝数等概念,设置测序相关参数,生成单端/双端测序结果文件% u' x" u( h; a" _" W
! f* A9 M0 ^( D0 b6 s二、材料和方法0 I* c6 v5 i1 m8 a
3 ~! L, `) D2 R7 |: w6 m
1、硬件平台, S' C# ~6 U7 o( w% K+ L
. V0 B1 u: }) Q. G$ Q5 B处理器:Intel(R) Core(TM)i7-4710MQ CPU @ 2.50GHz
* y1 N; G% h, ?( V# ~安装内存(RAM):16.0GB
% z: i; ~* g$ h6 r! c& F
/ t. m/ L9 Y& {' D* H2、系统平台
$ A6 P4 L' P3 x& P9 c# jWindows 8.1,Ubuntu
D4 ]$ J$ x# @' f. o$ F+ i6 T6 y* A! S$ C
3、软件平台
5 Y/ l$ l7 X% \, h; B7 u) v, `8 }- \7 {( P* ]
art_4542 B- M, W& `- |! P; x
GenomeABC http://crdd.osdd.net/raghava/genomeabc/
/ L$ M8 q: i4 }4 S& uPython3.54 \/ p+ Z# z: z" z
Biopython/ ], L0 Y' d" c$ P2 f, F- s
4、数据库资源" i* f! l# N+ `8 j
8 t: I' D+ E7 d
NCBI数据库:https://www.ncbi.nlm.nih.gov/
9 n P' z+ t* i+ F' Z0 M4 L2 x7 F, o9 w
5、研究对象
5 O' S3 R1 b2 |7 w9 i( J h7 p9 {5 w- X$ D$ o U% Y6 \6 h
酵母基因组Saccharomyces cerevisiae S288c (assembly R64) - v& a5 ?4 d% t* b( A3 K9 _# e
ftp://ftp.ncbi.nlm.nih.gov/genomes/all/GCF/000/146/045/GCF_000146045.2_R64/GCF_000146045.2_R64_genomic.fna.gz6 F9 t! o3 q% ~9 t
) C. p% W; _; }' H: R
6、方法1 G& [2 C+ }+ C U& P) u; @# s
! ~0 T0 u( W! @8 g- r7 h: v, }art_454的使用
2 K3 o6 q+ b$ G+ _首先至art系列软件的官网,下载软件,在ubuntu系统安装,然后阅读相关参数设置的帮助文档,运行程序。: d4 o, R' d& F6 K/ F3 E6 y4 A+ O% a
GenomeABC
- W! `* d- ]0 L5 V6 [6 [进入GenomeABC(http://crdd.osdd.net/raghava/genomeabc/),输入参数,获得模拟测序结果。
9 h1 m: a" ^. V+ g0 B) k编程模拟测序 # u* p" ` c1 n( B5 S' R
下载安装python,并且安装biopython扩展模块,编写程序,模拟单端/双端测序。! N9 `" V& S3 Z& U
三、结果
4 O( _& L( z+ [' @. g2 r& z6 e, Z5 v4 ~5 S d
1、art_454的运行结果
0 `+ p4 `5 s7 f( Q4 e- }$ O7 |0 P7 _! O9 a# x4 ~8 I1 f
无参数art_454运行,阅读帮助文档
# {. x0 D7 A, G2 ]
\" A9 V5 r0 ^) s& o图表 1无参数art_454运行
- e+ y( W7 V [" V. x1 N2 m对酵母基因组进行基因组单端测序模拟,FOLD_COVERAGE设为20,即覆盖度为20.
; ]8 s+ P( Z( }! d下图为模拟单端测序,程序运行过程及结果
" _* Q7 I% R; s5 I, `
1 }' t- [' Q! {& _, b( E" D( u图表 2 art454单端测序 8 U/ J1 V1 |+ D: V( N. R
" ~* j1 D7 J0 [, x1 A3 P; x: Z
图表 3 art454单端模拟结果
2 M7 D* N. ?& K1 r4 z双端测序模拟,FOLD_COVERAGE设为20,即覆盖度为20;MEAN_FRAG_LEN设为1500,即平均片段长度为1500;STD_DEV设为20,即长度的标准差为20 + _3 V' @+ {8 |( Y8 T1 s& V' ^ y
下图为模拟双端测序,程序运行过程及结果
2 R. U% l1 Q" y5 K0 d% V! R# @2 K7 e' j7 o U" f6 {$ L
图表 4 art454双端测序
- u- K% z) e! O1 M/ [ N" f' d
8 I4 ~' p& `# f7 W图表 5 art454双端模拟结果
; p- u! P* }7 R: n s2、GenomeABC
3 W6 K8 @. x5 Z$ E# Y/ X下图为设置参数页面 4 _6 E: A. M+ }& [
' K- C$ o) x. q& l7 L% S3 p# G* P: j% m
下图为结果下载页面
7 ^' ]( \: o! Y% K" M3 O5 A# y$ u" a) H/ x8 H
图表 6 结果下载页面 : ?! z5 p3 p7 g
3、编程模拟测序结果
" ^# P9 x% f3 H' B% ]拷贝数是这里的N值;覆盖度是m,测序深度是宏观的量,在这里与覆盖度意思相同,就是测序仪10X,20X。
8 V# ]8 N1 V2 y. Q; \ ?- S单端测序
& l- O$ y% I* a8 x; Q: ~7 L4 U( H" ^: T6 B# {
图表 7 程序模拟单端测序 ) i' j4 X _/ R% f! Z2 e1 n
双端测序 2 a: E4 R! ?! S/ W5 w
8 W t8 \& J2 y2 f图表 8 程序模拟双端测序
0 S+ _% [! L* f. t/ B测序结果
5 k: W( Z0 }, e* H. I2 _$ t7 K. E
图表 9 结果文件" a/ i, m5 x" [ L5 {
* a" |5 X2 J9 O; u1 S. u5 e' V因为期望片段长度是600bp,在片段长度区间200-1000bp内,所以大部分的片段都没有删除。
) w- c8 m6 F9 f) d3 N$ t9 `" Z7 @! w测序结果统计表
7 H' Y$ u5 X1 R6 N+ e6 ^
' [* s, U4 \4 {! h测序方式 基因组大小(bp) 片段长度区间 (bp) N值 期望片段长度 克隆保留率 片段数量 Reads长度范围(bp) Reads总数量 Reads总长度 覆盖度(m值) 理论丢失率(e-m) 覆盖率(1-e-m)8 { v7 B/ } ?! \6 k
单端 12157kb 200-1000 10 600 0.95 107378 50-100 101968 7645.541kb 0.62889 0.53318 0.46682 d+ `4 F* T; `9 V, z# g
单端 12157kb 200-1000 20 600 0.95 213722 50-100 202996 15227.882kb 1.25259 0.28576 0.71424
; ~4 _( _; ?8 I4 y! {* B双端 12157kb 200-1000 10 600 0.95 106704 50-100 202770 15212.662kb 1.25134 0.28612 0.71388
" z; U- p& [3 E s% P2 p双端 12157kb 200-1000 20 600 0.95 214212 50-100 407186 30534.265kb 2.51164 0.08114 0.918866 b7 V0 l) s2 u$ z+ R" s5 W
四、讨论和结论
- w% {6 Y$ h" r3 K1 ]0 F8 g2 m) a& z% _6 W. B7 v5 a) c& n
程序运行方法
; e5 @9 |& g: R
6 m3 [' ^/ g9 Q2 r$ g2 l在类的构造方法init()中,调整参数。 5 b( A1 Z' N# T7 f6 y$ d. p
Averagefragmentlength为片段平均的长度;
; b" P, M' ]3 ]: k8 [) nminfragmentlength和maxfragmentlength是保留片段的范围; 4 L( i) h$ I0 {0 G7 w
cloneRetainprobability是克隆的保留率; / B1 F. z, Z2 s) e0 i" C
minreadslength和maxreadslength是测序reads的长度范围/ Q8 d/ k6 R1 i- t
6 u" R5 q# u- I" ]% Y7 @
模拟测序的诸多方法都封装成了Sequencing类,只需要创建类,并调用singlereadsequencing()和pairreadsequencing()方法,传入文件名的参数即可。: ?2 u! Y" v+ X$ b; K! V, t
* p" C2 Z; D8 }$ e
附录
* z& J* D3 R& \! C5 e# ?" D8 t7 a L: o+ o7 ]9 b, A" ^/ }- [
from Bio import SeqIO
) g/ S* w, ^% Q' T+ i6 o8 Wfrom math import exp
* v7 z; f; X& {! U! S/ Q3 Z7 ~( k4 Zimport random
7 B* N7 [$ C' n# N* V" U$ g4 [$ B- e) ?
class Sequencing:
, a" ]) a( m2 u # N代表拷贝份数
" V0 B: @, B5 ]- n- r def __init__(self)9 s/ M9 B, R" H0 `* v6 l0 C
self.fragmentList = []
2 u2 \! {9 _8 a9 [$ |. ]* e; e self.readsID = 18 m( {! ]% ]# q( g' _, x! ^& w
self.readsList = []: s# Q: P" L# X6 M4 l& q1 s0 x
self.averagefragmentlength = 6504 U: P. k% h- O, x2 I
self.minfragmentlength = 500
4 q/ O" Z2 w+ y, _$ M self.maxfragmentlength = 8005 W5 K* _1 y! g* `) n
self.cloneRetainprobability = 1
: j2 q0 S6 R: K: s self.minreadslength = 508 O, n9 z {3 R4 z8 O" q
self.maxreadslength = 150
% W+ x- X! V5 F- K: A self.N = 105 m2 Y5 {$ O( R
self.genomeLength = 0
' w! V3 M$ _; ^9 }. l self.allreadslength = 0! }# W$ m) \4 ^
' Z7 ^* E2 A- k- D3 T- r( o4 t- q
# 生成断裂点
' Y. C7 o6 u. H6 z4 g- M+ M def generatebreakpoint(self, seqlen, averageLength):
, R/ P' G/ `6 ] # 假设平均每500bp 产生一个断裂点(averageLength = 500),通过随机函数生成seqlen/500个随机断裂点(1到seqlen之间的随机整数)
4 i4 C/ j2 C" K( ^+ t% ?, b7 h5 e breakpoint = [random.randint(0, seqlen) for _ in range(int(seqlen / averageLength))]* w6 x; \. m/ Z
breakpoint.append(seqlen)5 @! u7 L+ D; U( h
breakpoint.append(0)& G) G* J# s4 j5 _; Y& R! b
# 把随机断裂点从小到大排序
# R3 m" q; R) C( |; K4 ^ breakpoint.sort()+ k% @( n" f) @
return breakpoint# A. K& P6 ~+ x0 W' B) Z
& U/ ~$ j; o# p+ k
# 沿断裂点打断基因组,并删除不符合长度要求的序列片段,定义片段范围:200-1000bp! r* s; I' D- F8 _
def breakgenome(self, seq, breakpoint, minfragmentlength, maxfragmentlength):+ k9 w7 B6 h8 X9 V6 z
for i in range(len(breakpoint) - 1):
& p# ? Q( j4 | fragment = seq[breakpoint:breakpoint[i + 1]]$ ^& Z( s( l6 L1 a7 t8 K
if maxfragmentlength > len(fragment) > minfragmentlength:6 H& c: W0 p5 R- b6 G9 B1 Z
self.fragmentList.append(fragment): v3 |" n- D6 o2 T9 G" R6 x
return self.fragmentList
9 r% p0 L. z" t% I* [" b8 w/ M% i
# 模拟克隆时的随机丢失情况,random.random()生成0-1的保留概率# O3 V" e0 r7 y- O1 h$ S5 f
def clonefragment(self, fragmentList, cloneRetainprobability):
" }/ @, i3 y0 g$ n$ G clonedfragmentList = [] Z, ~& H& V7 B. L6 W' P0 M
Lossprobability = [random.random() for _ in range(len(fragmentList))]# K0 J _) K u& e% h$ y# ?( R
for i in range(len(fragmentList)):
3 O) {8 \( A, J& Z2 H1 e if Lossprobability <= cloneRetainprobability:) o$ x9 P, n& g$ v
clonedfragmentList.append(fragmentList); a# E/ R' J3 ~( x
return clonedfragmentList. \5 q/ }. c7 i. b6 |
$ A- d& q1 P5 }! v& }: m& R1 G
# 模拟单端测序,并修改reads的ID号
8 q9 D5 `2 z8 Y, n1 z/ b' i def singleread(self, clonedfragmentList):! R$ l; R: \1 W' U
for fragment in clonedfragmentList:* \) E7 d# H1 _( Q6 u% B `
fragment.id = ""% H3 g& A' j- M' F
fragment.name = ""
% n1 L d! {; e fragment.description = fragment.description[12:].split(",")[0]. |+ m9 u2 [8 t8 L3 z) u$ Q+ W5 t
fragment.description = str(self.readsID) + "." + fragment.description1 A B" f2 z7 q
self.readsID += 16 `% F# r+ P/ N0 U0 ~9 L
readslength = random.randint(self.minreadslength, self.maxreadslength)- _8 X6 ~1 \% l* @- H
self.allreadslength += readslength+ q4 I1 \4 z! I% F* j
self.readsList.append(fragment[:readslength])
7 E' P3 n' n* A& Z: v8 z3 e
8 l2 O* f' Y7 S) _; C3 H( H def singlereadsequencing(self, genomedata, sequencingResult):
3 i7 `% m# @; T3 r$ t& m for seq_record in SeqIO.parse(genomedata, "fasta"):
, j( F3 k) I2 n seqlen = len(seq_record)
+ H3 p0 T4 Q, ]2 Y! m! ^, N, Q: h self.genomeLength += seqlen
3 j# \* Z8 H1 ?% I3 v. m for i in range(self.N):2 V8 s8 Y% ]1 y% g* d+ N
# 生成断裂点
. e: C4 r" \" X4 Q- { t# j2 S breakpoint = self.generatebreakpoint(seqlen, self.averagefragmentlength)
' F+ x* }# y8 p! {# H2 U. O J/ } # 沿断裂点打断基因组4 w( V* g: G: s. D
self.breakgenome(seq_record, breakpoint, self.minfragmentlength, self.maxfragmentlength)& ~* i& a+ l2 G+ y% d) i# f9 M: O
# 模拟克隆时的随机丢失情况
& p( U$ }3 W; k n0 Q; k) F) e clonedfragmentList = self.clonefragment(self.fragmentList, self.cloneRetainprobability)
0 |" W4 c7 r3 X8 z% D& g3 F9 p8 { # 模拟单端测序5 u7 s. ^$ q% {
self.singleread(clonedfragmentList)
2 @5 o* [) e8 l. c5 _ SeqIO.write(self.readsList, sequencingResult, "fasta")
7 f+ S0 l9 ?! F( ]4 z# u- R; O8 U5 x; k% ~! j l# ], L
def pairread(self, clonedfragmentList):
$ `# W: N( _, E% s! V& m! {+ r for fragment in clonedfragmentList:2 H- A+ i9 c; [& d: }. D
fragment.id = "": `( m! R; X9 s( G* W4 N1 E
fragment.name = ""
. g! t8 A7 x$ d7 O4 Q( d( I description = fragment.description[12:].split(",")[0]3 Q/ B( |& g, S: I/ D) e
fragment.description = str(self.readsID) + "." + description
1 W0 d! E, Y5 Y# I* h: X; { readslength = random.randint(self.minreadslength, self.maxreadslength)
. z$ D) J3 w2 R7 J, H6 L0 D self.allreadslength += readslength
, H9 s6 p! y3 t self.readsList.append(fragment[:readslength])( r& {6 a6 Z0 r3 o) D
7 X7 l# ~6 x% }, z readslength = random.randint(self.minreadslength, self.maxreadslength)
% A( |! a# I+ {/ Y self.allreadslength += readslength
/ G; ]* }' M) P" R w1 t+ O
+ J9 }3 T0 O. \/ h7 `0 _ fragmentcomplement = fragment.reverse_complement()
% P6 F2 f4 t: r( ]9 _* r$ d fragmentcomplement.id = ""3 T" h1 s# H+ f! X2 _
fragmentcomplement.name = ""
5 q: i4 M* l8 I2 q9 f1 F- Z! j8 P fragmentcomplement.description = str(self.readsID) + "." + description
( Y8 s# T A* j! _ self.readsList.append(fragmentcomplement[:readslength])
4 V4 e: e7 w5 \* S+ Q; ~ W
% n( o% b! e% D' i3 M) i1 [9 S: ? self.readsID += 1
7 L& O7 n" d( F' k! x2 t
# L6 d0 `% s l! C: T2 a3 X def pairreadsequencing(self,genomedata, sequencingResult_1, sequencingResult_2):
: o2 z6 \( \* @ for seq_record in SeqIO.parse(genomedata, "fasta"):7 @6 k1 Z' S/ J' _% B- o
seqlen = len(seq_record)6 I9 O4 ~. S# E. r# D
self.genomeLength += seqlen
- v6 Z/ w- }1 Y8 \ for i in range(self.N):
5 ^1 N, H* l/ s$ u7 E # 生成断裂点$ N9 s9 @9 H- `5 n$ w! h
breakpoint = self.generatebreakpoint(seqlen, self.averagefragmentlength). N6 S m3 Z$ F1 I" b/ O
# 沿断裂点打断基因组+ ?' N# r% q D7 w) r
self.breakgenome(seq_record, breakpoint, self.minfragmentlength, self.maxfragmentlength)
% Z& w; F' l5 x7 p* \ # 模拟克隆时的随机丢失情况
5 k, ^0 T/ r4 t+ W: ]* k1 O N! b clonedfragmentList = self.clonefragment(self.fragmentList, self.cloneRetainprobability)7 ^9 C' ^; ^, V
# 模拟双端测序
8 x" z6 w Y: U: ]! E) R self.pairread(clonedfragmentList)
* ~5 u. t$ I" A readsList_1 = [self.readsList for i in range(len(self.readsList)) if i % 2 == 0]
2 o! I; I: C( y+ b readsList_2 = [self.readsList for i in range(len(self.readsList)) if i % 2 == 1]
% H; ~* A1 R1 x- d SeqIO.write(readsList_1, sequencingResult_1, "fasta"); b4 t# ^1 n; Z y" s
SeqIO.write(readsList_2, sequencingResult_2, "fasta")
/ g' ?/ J) M/ I, Z$ i3 X ?1 R# s
$ J6 B. l* A0 D def resultsummary(self):
" D& A: F1 v0 f1 ~$ [ print("基因组长度:" + str(self.genomeLength / 1000) + "kb")
1 h& x9 ~( c* g! n( t) i7 x print("片段长度区间:" + str(self.minfragmentlength) + "-" + str(self.maxfragmentlength))! o3 @# t+ m T a
print("N值:" + str(self.N))
: J7 ?0 W# ]' t; \; P: ^ print("期望片段长度:" + str(self.averagefragmentlength))
8 r, `5 S9 @3 t4 D; b8 R print("克隆保留率:" + str(self.cloneRetainprobability))
, s+ m/ J! k8 p print("片段数量:" + str(len(self.fragmentList)))* M, x( t0 r- T7 p1 _ J& G! G5 Y) `% m
print("reads长度:" + str(self.minreadslength) + "-" + str(self.maxreadslength))
; t0 l4 l4 F! ]& T print("reads总数量:" + str(len(self.readsList)))
& ~5 K; C# g0 k print("reads总长度:" + str(self.allreadslength / 1000) + "kb")
8 Z" ?7 P0 M( x2 c+ d2 l/ }- V m = self.allreadslength / self.genomeLength( o9 U0 W& S3 H9 i% p+ h
print("覆盖度(m值):" + str(round(m, 5)))
: z. Q/ Z/ b' M, _7 n& j print("理论丢失率(e^-m):" + str(round(exp(-m), 5)))
! b7 H3 W' P- f$ _0 N, K print("覆盖率(1-e^-m):" + str(round(1 - exp(-m), 5)))6 S; O& Z5 r6 P1 R) X3 I! F' R
# -------------------------------------------主程序-------------------------------------------
, {& A* M# c! h: E# 模拟单端测序
% o6 j4 h! D+ u5 L5 O: tsequencingObj = Sequencing()+ q9 U; j6 ` ^7 A2 N' Y
sequencingObj.singlereadsequencing("data/NC_025452.fasta", "result/virusSingleRead.fa")% _2 Y& ~$ P" r8 K& d0 A
sequencingObj.resultsummary()- F I* C. @9 r* J Q, x3 C
, |; D9 l, e! L# \7 Q$ W& _% ?# 模拟双端测序2 V7 Q! X/ Z9 j. v. U( Y: l2 w% m
sequencingObj = Sequencing()5 \# |1 D7 w0 f; o$ r7 [& V
sequencingObj.pairreadsequencing("data/GCF_000146045.2_R64_genomic.fna", "result/yeastPairRead_1.fa", "result/yeastPairRead_2.fa")
- y* i" |, L2 `1 ]sequencingObj.resultsummary()
* J2 X4 H- F* h( F1 dfrom Bio import SeqIO
0 k: q; x/ n q Nfrom math import exp5 ^# J5 l1 @0 Z( Q; i
import random
4 C8 o5 F0 q N0 V% g
3 C6 u; K' u1 n/ Uclass Sequencing:) G8 \: _6 |, t+ ~
# N代表拷贝份数
/ P! G7 ^4 z( d# e! h0 k def __init__(self):$ o$ x/ w+ Y& o4 _* J# f% x& ^
self.fragmentList = []: j: ~, B# S( R% @4 C
self.readsID = 1; _: J2 o; n: d- C0 D+ K
self.readsList = []
, m; d" B6 \2 l+ y6 u2 H self.averagefragmentlength = 650* @# V; ?# F8 h1 L
self.minfragmentlength = 500
2 S# w+ O: a# l5 f, S self.maxfragmentlength = 8000 a) B) e) e7 O; L4 \
self.cloneRetainprobability = 1; |& B, s) u" Y+ r* R
self.minreadslength = 50
/ o5 g! ~9 v, j self.maxreadslength = 150
M k5 L4 e4 o4 W$ N self.N = 10
' [5 ^: F7 g% S$ J% g$ ? self.genomeLength = 04 k: j( `2 d. |3 e7 K* W( V
self.allreadslength = 0
* m# u$ Q1 [( q+ p$ `" U) n# z# e8 f0 d* r" t4 O8 {
# 生成断裂点2 \1 u% ]% X2 p( S0 T
def generatebreakpoint(self, seqlen, averageLength):
* c7 R& [6 t2 r: [ # 假设平均每500bp 产生一个断裂点(averageLength = 500),通过随机函数生成seqlen/500个随机断裂点(1到seqlen之间的随机整数)
& W1 Z8 [2 a/ d' A breakpoint = [random.randint(0, seqlen) for _ in range(int(seqlen / averageLength))]
7 [" P/ F! o4 X/ a/ ^" D breakpoint.append(seqlen)$ C/ Y- l( |. \6 {$ X
breakpoint.append(0)0 J1 M$ y( P( ?. M: E6 G6 Q r" ~! ]# Y( O
# 把随机断裂点从小到大排序/ ]1 d! @9 ?& x5 g3 T1 q6 u
breakpoint.sort()
4 m0 M, t$ ~/ K3 `( k" p+ y! [! A return breakpoint# J6 F% J4 V a* p! y/ n, T4 s3 N
: n3 L# Q( j8 k2 h) O # 沿断裂点打断基因组,并删除不符合长度要求的序列片段,定义片段范围:200-1000bp( `$ ~2 w2 _0 G. `+ X* b8 d ]. o
def breakgenome(self, seq, breakpoint, minfragmentlength, maxfragmentlength):$ M/ W0 F# O! {1 F f/ R; F$ p- K
for i in range(len(breakpoint) - 1):
3 X' {# G2 a/ I3 M1 G8 t# |9 |; { fragment = seq[breakpoint:breakpoint[i + 1]]' W, s2 c# a( {5 ~
if maxfragmentlength > len(fragment) > minfragmentlength:$ m8 c5 r! S; W, e; T! ^' p
self.fragmentList.append(fragment)& A- s$ h! [! R# o
return self.fragmentList6 p+ C+ t8 e/ C$ Q4 Y2 ~
! |- e l" |5 m* ]0 T9 n8 X
# 模拟克隆时的随机丢失情况,random.random()生成0-1的保留概率
6 h- p# e8 U# F- @/ L def clonefragment(self, fragmentList, cloneRetainprobability):
) G' N! D9 m. T- Q5 }1 P8 S' G clonedfragmentList = []' c, t/ |! F! R
Lossprobability = [random.random() for _ in range(len(fragmentList))]8 {$ W3 ~5 T% I% o" v
for i in range(len(fragmentList)):5 a! n, q1 {! j( y# M g# D$ J# S
if Lossprobability <= cloneRetainprobability:
* L1 k7 y& _$ _; [; N* O( u0 O9 O clonedfragmentList.append(fragmentList)* B8 C/ b1 M& d* d! \) x! o% o0 I3 m' d
return clonedfragmentList
3 ^! T( }7 t, ]. n% `
5 Z. k7 } }! k # 模拟单端测序,并修改reads的ID号/ J; w" I7 s# [) W: `" u' j
def singleread(self, clonedfragmentList):
6 N4 k+ B5 n' G- }- Y5 v for fragment in clonedfragmentList:
! ^/ g/ O, m1 \, }$ ], t& x& B fragment.id = ""
$ g- L( g5 Y! ?2 X6 O fragment.name = ""
+ b$ ?4 d& j7 w& J fragment.description = fragment.description[12:].split(",")[0]
- }' e) B/ ~5 o) P$ V fragment.description = str(self.readsID) + "." + fragment.description
) @/ N: a7 f7 e7 d, J9 T self.readsID += 1
/ V0 z% K$ [- w; \& _7 U readslength = random.randint(self.minreadslength, self.maxreadslength)& _$ M% x* V* \. I7 O. j7 C4 q, p$ N
self.allreadslength += readslength9 i% R* }* m6 I6 N9 @' ^3 R! L7 \" L
self.readsList.append(fragment[:readslength])# g, E9 ~% ]- u
2 N6 S" v7 e7 F7 K* L+ t4 l! Z def singlereadsequencing(self, genomedata, sequencingResult):& t6 F' `- f" l: c
for seq_record in SeqIO.parse(genomedata, "fasta"):' Z7 Q$ \- J. E2 g
seqlen = len(seq_record)
& I4 k1 z2 k2 m" q v8 S1 j4 `7 a0 X self.genomeLength += seqlen+ N; M% _, Y% g
for i in range(self.N):; L: W3 c" {6 _# B
# 生成断裂点, y/ l8 [: ?3 z9 v- q' R
breakpoint = self.generatebreakpoint(seqlen, self.averagefragmentlength), }/ t0 A5 Y8 V( A; d) R
# 沿断裂点打断基因组
- B; z6 v' x0 O0 x8 D& f: Q self.breakgenome(seq_record, breakpoint, self.minfragmentlength, self.maxfragmentlength)8 i* W7 o' ^, l1 J/ {
# 模拟克隆时的随机丢失情况
2 Q/ j( {# C2 | clonedfragmentList = self.clonefragment(self.fragmentList, self.cloneRetainprobability)0 h( y4 T8 w6 e0 T8 P/ H
# 模拟单端测序6 F, I7 a2 u( ]. R6 v7 B8 q. ]1 V2 C
self.singleread(clonedfragmentList)) b# M3 L& U: H
SeqIO.write(self.readsList, sequencingResult, "fasta")8 N# m3 I. [4 H0 d W
* h7 F; r, P/ }2 J: {0 W def pairread(self, clonedfragmentList):+ |( v# f/ ^4 Z$ `
for fragment in clonedfragmentList:
6 ` c$ B" Z/ T+ Y' @& T fragment.id = ""
5 e' Q% ]6 l8 l fragment.name = ""
, H/ u. B# j2 i& j description = fragment.description[12:].split(",")[0]
8 g, {' J3 E$ b+ p fragment.description = str(self.readsID) + "." + description
6 |+ U4 j, n1 I6 d# X) u readslength = random.randint(self.minreadslength, self.maxreadslength)
; g5 v- ]! e" c( s7 i! ?+ n self.allreadslength += readslength
' j. M! t$ z$ N. H self.readsList.append(fragment[:readslength])
" l7 | v: ~5 T! v& S" x/ J' r9 r+ c! D8 B
readslength = random.randint(self.minreadslength, self.maxreadslength), P( C. b( }, |$ y$ V1 e! i
self.allreadslength += readslength" Z5 x+ e" T+ ~4 |; q( K4 `
. w! i; Y! G4 H* @7 w fragmentcomplement = fragment.reverse_complement()( j* z9 l* V! I h: P/ _
fragmentcomplement.id = ""9 R* }; n/ i5 m5 `% R7 d, @ y4 G
fragmentcomplement.name = ""
8 A7 [ X' l! u0 D9 [& x' j5 A fragmentcomplement.description = str(self.readsID) + "." + description
/ d& z l" O# L& ?6 Q self.readsList.append(fragmentcomplement[:readslength]) Y3 Z% o% R9 V; \& T
/ s+ p, H2 |- p0 v# L3 q self.readsID += 1
1 y0 u$ G' }1 Q g8 r9 m! f
) T$ g2 `* G m9 ^) d) k" @' J# j def pairreadsequencing(self,genomedata, sequencingResult_1, sequencingResult_2):( D% C4 j! d! z' i0 C3 Q: f
for seq_record in SeqIO.parse(genomedata, "fasta"):
! W" i0 O0 e$ n5 a seqlen = len(seq_record)
/ F2 F7 y/ k+ r1 r) x self.genomeLength += seqlen
: |: j8 B% S+ A8 j- P- H+ } for i in range(self.N):3 r* g8 Z$ S- n, y x' w, i) M. J
# 生成断裂点
+ t2 |, h" |5 O8 m* N+ J, b8 J breakpoint = self.generatebreakpoint(seqlen, self.averagefragmentlength)" P3 U6 @% |0 x) V! ?
# 沿断裂点打断基因组
( J5 I9 F0 ^4 g: @# ~ self.breakgenome(seq_record, breakpoint, self.minfragmentlength, self.maxfragmentlength)
( u B% V, H6 B7 N! Q/ K # 模拟克隆时的随机丢失情况
) v5 p& {& N$ w- N* ]; i clonedfragmentList = self.clonefragment(self.fragmentList, self.cloneRetainprobability)
( D% f0 j' I" M& o, h+ h # 模拟双端测序# y6 h# W) y2 `3 ?: F2 q) l
self.pairread(clonedfragmentList)& K" U& \1 U8 U; q/ ~
readsList_1 = [self.readsList for i in range(len(self.readsList)) if i % 2 == 0]
5 v b) c. B: j readsList_2 = [self.readsList for i in range(len(self.readsList)) if i % 2 == 1]' d8 B* \2 U) [# X- O
SeqIO.write(readsList_1, sequencingResult_1, "fasta")
: k9 U1 G( X" i0 L V6 \2 K& u SeqIO.write(readsList_2, sequencingResult_2, "fasta")& F' C3 m6 J# T- r3 m4 x+ }
* Q% u$ r# P2 m* | def resultsummary(self):
+ j5 j. b: q5 w8 e, r2 d n6 E! Z print("基因组长度:" + str(self.genomeLength / 1000) + "kb")
0 r5 D' F" Y5 n( j0 p0 [) d7 j print("片段长度区间:" + str(self.minfragmentlength) + "-" + str(self.maxfragmentlength))$ j1 U$ T6 D2 k* C/ {1 Q, g0 X+ r
print("N值:" + str(self.N))
/ H0 H& x3 J" u. ]& G1 f* \$ o8 O print("期望片段长度:" + str(self.averagefragmentlength)) k1 w- v, A% l3 l( P, q
print("克隆保留率:" + str(self.cloneRetainprobability))
$ u/ H$ a) [% x' O7 _0 }" ? print("片段数量:" + str(len(self.fragmentList)))
: f3 T5 r" h: I7 n3 y1 V z print("reads长度:" + str(self.minreadslength) + "-" + str(self.maxreadslength))
( O. K6 F. P& T1 b/ L print("reads总数量:" + str(len(self.readsList))). w# h! U4 m3 c6 y
print("reads总长度:" + str(self.allreadslength / 1000) + "kb"): j$ c5 _/ z R7 Z
m = self.allreadslength / self.genomeLength
$ u% V) Y* E; D! o print("覆盖度(m值):" + str(round(m, 5)))2 k/ c5 g0 ?' A$ o- A* ]
print("理论丢失率(e^-m):" + str(round(exp(-m), 5)))
6 O; c, @% C- [ print("覆盖率(1-e^-m):" + str(round(1 - exp(-m), 5)))
; g, t& z0 w2 D* a# -------------------------------------------主程序-------------------------------------------
$ o- G7 ^( Y% C7 q# 模拟单端测序7 C# [7 j: U+ r/ \! g) E1 g3 U; k
sequencingObj = Sequencing()- a" E: \ h8 W- G. p' f
sequencingObj.singlereadsequencing("data/NC_025452.fasta", "result/virusSingleRead.fa")
, L& ^8 C5 S$ F8 P# J9 s4 d5 }sequencingObj.resultsummary()+ u" [" S1 L) Q0 d$ [
$ S9 Q O5 V1 _# 模拟双端测序
, n; M; r& k; z+ e- PsequencingObj = Sequencing()
2 V8 S. `$ H) d4 [0 a% D" ]sequencingObj.pairreadsequencing("data/GCF_000146045.2_R64_genomic.fna", "result/yeastPairRead_1.fa", "result/yeastPairRead_2.fa")
/ q) M0 v" x4 P9 x% d# SsequencingObj.resultsummary()7 w9 B& K' \1 M/ ^# u# t
5 E' i* ? a* a' r# v6 s) i
( y! J" Y6 j# h: ~) {0 g0 p' E% \$ D0 ~6 S2 k- o
: Z6 B4 b% t A f5 j1 \% s& h
|
zan
|