- 在线时间
- 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年大象老师国赛优 |
基因组测序模拟
' ^5 x9 n0 D7 {+ q$ n基因组测序模拟
) A [( v4 U4 P
$ ~! t# x ]- @$ C) T* s一、摘要
, ~! m$ q4 {; U
' K! O: h' r1 G ?! c通过熟悉已有的基因组测序模拟和评估程序,加深全基因组鸟枪法测序原理的理解,并且能够编写程序模拟全基因组鸟枪法测序,理解覆盖度、测序深度、拷贝数等概念,设置测序相关参数,生成单端/双端测序结果文件# j2 v( c9 w2 d# y# n, r
7 s' [8 c- t) l& C
二、材料和方法
( N/ V, `3 f; R( X& P* ]( U2 @0 T# L# C: P* H; ]
1、硬件平台9 ]$ ~- e. v% ~& @* y: L0 v0 y3 O
4 `5 u' R9 }7 h7 T/ x处理器:Intel(R) Core(TM)i7-4710MQ CPU @ 2.50GHz
; E5 k, C/ ~5 ]. _- f6 w安装内存(RAM):16.0GB
/ f) X* h4 d, X O2 N: s; u5 }. Z; C
' j; I6 B- Q6 H! \7 ~2、系统平台
# o, a' N8 _9 g& ]8 W. GWindows 8.1,Ubuntu
$ j w0 v6 ^1 n% I# O$ l+ c3 P1 t# X" }6 j' G+ w6 U
3、软件平台
- O' z7 h6 Z l# g. q& L
6 e7 h# j- A/ {2 i* x! Q4 ~art_454
+ O* j0 Y+ N& D' r; pGenomeABC http://crdd.osdd.net/raghava/genomeabc/
) @) G$ {6 ~2 Z" g; _3 PPython3.5
2 r- ~) p$ T3 E; m' d5 BBiopython
0 [% W: l) ~1 N' M8 F9 E, x" b" @0 B4、数据库资源1 f/ O. ^ C8 P3 p9 H( D
+ |4 E6 s, ]: x5 n+ ] M0 B
NCBI数据库:https://www.ncbi.nlm.nih.gov/
1 b4 b, s x8 |) R/ v
+ j7 m( W* H' f, b: z @( T! z" F% i5、研究对象
, W" O& u( ^! h4 j7 x0 b. n) m/ g; n" S) h) w% a2 A% z" x( Y
酵母基因组Saccharomyces cerevisiae S288c (assembly R64)
4 i0 T2 k: T& [0 Cftp://ftp.ncbi.nlm.nih.gov/genomes/all/GCF/000/146/045/GCF_000146045.2_R64/GCF_000146045.2_R64_genomic.fna.gz
0 Y2 y! e0 a b2 G; r- R( T
5 W. u- L. R& }5 O" U/ l& G6、方法. b7 G" ~% U: R2 V- ?2 L
+ T/ V* I2 P$ w- U8 _! iart_454的使用 . K3 O' ?/ B) O( @
首先至art系列软件的官网,下载软件,在ubuntu系统安装,然后阅读相关参数设置的帮助文档,运行程序。
# y5 ?( M( Q9 ?9 N0 T; x, aGenomeABC
4 b) v2 x9 ^$ R' R: N% w4 f进入GenomeABC(http://crdd.osdd.net/raghava/genomeabc/),输入参数,获得模拟测序结果。
! ~+ U2 m" ~! c$ @+ I& F编程模拟测序 * x L1 P" e O6 @% t1 U
下载安装python,并且安装biopython扩展模块,编写程序,模拟单端/双端测序。* {' K% r. N7 U
三、结果( o1 J2 s, Z! z$ a
( c1 ~! J+ q, A& k6 G7 ~' _$ a
1、art_454的运行结果' t; O1 Q1 l, u
& e0 z' `/ ^3 k- g
无参数art_454运行,阅读帮助文档
# H( K0 X& s, l1 q5 w
1 T w( v" L' A9 A图表 1无参数art_454运行 , m, C. x! D S$ @
对酵母基因组进行基因组单端测序模拟,FOLD_COVERAGE设为20,即覆盖度为20. / p' g0 z& b; A/ @8 Y6 j& }
下图为模拟单端测序,程序运行过程及结果
4 Y a" S3 Q0 r; f0 H# h; I- ]. y/ e
图表 2 art454单端测序 8 O; H' x& \/ O' e! h
! N+ b! I. {3 ?$ s. c图表 3 art454单端模拟结果 - Y D' [; q* v! a+ R" T: ]
双端测序模拟,FOLD_COVERAGE设为20,即覆盖度为20;MEAN_FRAG_LEN设为1500,即平均片段长度为1500;STD_DEV设为20,即长度的标准差为20 $ Y0 B7 i+ ~& f0 x7 B0 y/ n+ x
下图为模拟双端测序,程序运行过程及结果
& \! R2 u8 q6 o/ H6 K: {- {3 N# m
" o* b2 h2 h9 U/ h& r: b( `图表 4 art454双端测序 % {8 B) q2 y3 w4 Z& j3 \
$ u9 I7 O- i/ {8 l( K q' Z图表 5 art454双端模拟结果 ~; X2 m( K% e( |; j$ ]' G
2、GenomeABC
7 s( Q* U6 J0 F下图为设置参数页面
3 Y6 p1 L: O7 a: N( k
, ?! V& k1 { Q3 G/ n下图为结果下载页面
! @& _8 C5 b2 L1 Z6 R! Z1 X' V5 p5 S( i0 G. ?
图表 6 结果下载页面 2 u l- F6 d) h
3、编程模拟测序结果 ! U. ]$ w% S+ [1 v
拷贝数是这里的N值;覆盖度是m,测序深度是宏观的量,在这里与覆盖度意思相同,就是测序仪10X,20X。
; U0 P4 I. f7 B单端测序 / f8 H' K: G" u4 z0 Q
( {5 b! z3 B, s/ P1 w/ M图表 7 程序模拟单端测序 ) c/ v8 s4 P5 d1 k7 `, f
双端测序 ! H5 W9 \/ h$ W1 g# u2 a
8 T; B& P& t- M4 ?图表 8 程序模拟双端测序 , u( f' V7 ^9 e' T: {+ O
测序结果
# S8 W/ j' g* e5 s# b7 e- r, L+ ]+ p7 b
图表 9 结果文件1 Y" a1 X3 C+ T+ |* Q) h0 ~/ K
: b& \) P) A, W) {- H$ o
因为期望片段长度是600bp,在片段长度区间200-1000bp内,所以大部分的片段都没有删除。 9 e) X5 P/ Q# Q, V- x
测序结果统计表
7 l$ D! J% s/ Z- R" Q
$ L8 A: o5 B/ E; |. `5 }测序方式 基因组大小(bp) 片段长度区间 (bp) N值 期望片段长度 克隆保留率 片段数量 Reads长度范围(bp) Reads总数量 Reads总长度 覆盖度(m值) 理论丢失率(e-m) 覆盖率(1-e-m) p0 j3 R- u; Q* Z" ]
单端 12157kb 200-1000 10 600 0.95 107378 50-100 101968 7645.541kb 0.62889 0.53318 0.46682
% [) A- x: l8 g3 Q$ j2 U \$ l- F( C单端 12157kb 200-1000 20 600 0.95 213722 50-100 202996 15227.882kb 1.25259 0.28576 0.71424' y' ^0 ~4 F# Q( S
双端 12157kb 200-1000 10 600 0.95 106704 50-100 202770 15212.662kb 1.25134 0.28612 0.71388: t# l- m( s7 ?
双端 12157kb 200-1000 20 600 0.95 214212 50-100 407186 30534.265kb 2.51164 0.08114 0.91886
. T) q: ?; e) `& P四、讨论和结论" l1 V+ e) U) h @
6 P0 A; n& F# h2 V3 X! K
程序运行方法# b) ~/ d7 b s" k3 W) P
( x( \- X, A5 |在类的构造方法init()中,调整参数。 & C( C$ f8 R2 i. `/ M' \! c
Averagefragmentlength为片段平均的长度;
! ? D! A+ _$ z6 W) r- s, O" fminfragmentlength和maxfragmentlength是保留片段的范围; 8 U1 |! b: z" r
cloneRetainprobability是克隆的保留率;
* L0 Y# Z8 U0 l c. ?3 R5 e5 Dminreadslength和maxreadslength是测序reads的长度范围
|$ q1 I) m7 {& r& D0 x
3 v, o% \+ ?. {; n模拟测序的诸多方法都封装成了Sequencing类,只需要创建类,并调用singlereadsequencing()和pairreadsequencing()方法,传入文件名的参数即可。2 r+ E/ L& A M, W' ?' [* x1 I& u
( e; F: z; L! l0 P! ?5 \! F8 E# {附录9 Y1 Z, m5 _+ K
% J1 q$ {9 i/ e$ Y- j
from Bio import SeqIO2 A& s$ Q' f9 U, {
from math import exp
. [# R7 u W% j |% Kimport random
( Y }$ {6 U, ]8 a
* n! ~- o8 Z- |3 pclass Sequencing:+ R. m" ]; c, F* V
# N代表拷贝份数! r8 H$ i- z7 y' j: A
def __init__(self)
% e' T9 y2 X( _9 b2 d( C1 o self.fragmentList = [], n. ?. u# A( H. [( _
self.readsID = 1' Y5 U( [$ i0 d. l6 ?
self.readsList = []: w, \2 ?& N2 |. J i" |
self.averagefragmentlength = 650
$ l( r' f; N1 E' i- L* b& n# _ self.minfragmentlength = 500
" g5 ~7 e2 ]# a( ?- H self.maxfragmentlength = 800
/ p% A: P- i C* s" x self.cloneRetainprobability = 1
9 I- h7 R* h. M3 T# q+ [/ j self.minreadslength = 50
$ l; h" m: W; t( z H self.maxreadslength = 150
2 }- v z& o, p4 x' D self.N = 10
+ u) {- q& ~ U9 ~) P7 N self.genomeLength = 0
, ]5 H4 G" K3 M: [$ s: j) x self.allreadslength = 01 U9 x. D+ F) L9 u
. `$ q1 q) b8 D* h3 t( t # 生成断裂点
% a) T5 E, j2 N6 n- C9 G def generatebreakpoint(self, seqlen, averageLength):
7 {- [7 s' ?; Q, I& e # 假设平均每500bp 产生一个断裂点(averageLength = 500),通过随机函数生成seqlen/500个随机断裂点(1到seqlen之间的随机整数)
! ~3 _9 u1 p! d3 N breakpoint = [random.randint(0, seqlen) for _ in range(int(seqlen / averageLength))]
3 \. ^4 j+ x" E2 m+ g7 D8 \8 Y, O8 Y: t breakpoint.append(seqlen)
; a' `8 `- x; n2 W breakpoint.append(0)
3 i/ C1 X" }! D; r: Z( x # 把随机断裂点从小到大排序
u j; S8 w& ~ breakpoint.sort()
6 B: y0 a4 Q! x return breakpoint
5 V$ P& D. R+ {# J7 _/ ?" s5 g9 @3 P: v$ I
# 沿断裂点打断基因组,并删除不符合长度要求的序列片段,定义片段范围:200-1000bp
6 _# C3 X9 Y1 W- r# m def breakgenome(self, seq, breakpoint, minfragmentlength, maxfragmentlength):2 c0 V* t: a& _' C$ w- C* a
for i in range(len(breakpoint) - 1):3 j& [8 M0 s4 q* J% @
fragment = seq[breakpoint:breakpoint[i + 1]]1 q6 ^+ A7 a+ I! `' I) E9 f/ f
if maxfragmentlength > len(fragment) > minfragmentlength:
) M( O- r: R I2 E- c- A self.fragmentList.append(fragment)) m, O5 K9 |/ [) e/ H' @( n
return self.fragmentList
; [1 a7 _1 b+ Y) O
7 j, h) _. T* D # 模拟克隆时的随机丢失情况,random.random()生成0-1的保留概率
3 [' V& E8 s# u( J def clonefragment(self, fragmentList, cloneRetainprobability):
' Q) C0 P" N& d# E( Q$ O clonedfragmentList = []
2 ? Q2 y) U: u3 p Lossprobability = [random.random() for _ in range(len(fragmentList))]) v- _& F5 p8 _9 i( s
for i in range(len(fragmentList)):$ {' }/ B- t Z
if Lossprobability <= cloneRetainprobability:+ \+ ^$ ^" l4 `3 u3 G1 g) C
clonedfragmentList.append(fragmentList)' o) e# c/ h0 o9 l( }: I/ a' R( f
return clonedfragmentList
2 E5 C6 p; M- C6 Q
0 v8 l1 _# X" _" C6 O7 k # 模拟单端测序,并修改reads的ID号& d5 |) g5 k/ F& ?) W. k
def singleread(self, clonedfragmentList):
I: Q% P- z( }! d for fragment in clonedfragmentList:+ A% k1 S1 n% j; {
fragment.id = ""$ I0 k, h, O) L2 W- `0 ~; ^. |) r
fragment.name = ""
. a( O G# S8 A0 n# l7 D! u0 g3 q fragment.description = fragment.description[12:].split(",")[0]6 p2 |. @1 Z8 r
fragment.description = str(self.readsID) + "." + fragment.description
4 ?! M7 ~3 D$ n2 F9 G+ E5 K self.readsID += 1
% P2 P7 M* b; b' q8 ~3 M) w readslength = random.randint(self.minreadslength, self.maxreadslength)9 f$ c$ W; f1 Z/ A7 O& U
self.allreadslength += readslength" Y K5 r; C0 J$ n
self.readsList.append(fragment[:readslength])
m0 U( i- Q1 w2 b2 D$ a {
1 J: D: _% s4 x9 Q def singlereadsequencing(self, genomedata, sequencingResult):% E: d- `, O0 i Z
for seq_record in SeqIO.parse(genomedata, "fasta"):
9 O8 f) i, K* \2 E0 E; d6 e seqlen = len(seq_record)/ `" o3 W4 S: {3 g( ~
self.genomeLength += seqlen
( Q0 ?5 Z! Y. k! g; o for i in range(self.N):8 C9 S3 I! \1 U, X) u
# 生成断裂点
8 l- W4 t( I) C' @. C' f5 t breakpoint = self.generatebreakpoint(seqlen, self.averagefragmentlength)3 p6 ] R d) Q+ S
# 沿断裂点打断基因组
( c$ j* X: s8 p% n- X self.breakgenome(seq_record, breakpoint, self.minfragmentlength, self.maxfragmentlength)
2 g4 ~; Y+ `/ D3 o6 W( K4 C% z. A # 模拟克隆时的随机丢失情况4 {5 f( p1 z( _7 \
clonedfragmentList = self.clonefragment(self.fragmentList, self.cloneRetainprobability)
( O1 y+ {8 k8 a C* T, ~' [. w # 模拟单端测序1 }, }% |# \' k+ L4 Y& t, K
self.singleread(clonedfragmentList)
; g' F* ^. @9 M4 B SeqIO.write(self.readsList, sequencingResult, "fasta")' m" u/ j7 @% [ _
7 ]5 q% L, R. U3 m4 a1 a7 P# r
def pairread(self, clonedfragmentList):. n5 k# |# d# ^7 w
for fragment in clonedfragmentList:" C6 A2 L: |" Y/ @2 t$ b9 G& c: N
fragment.id = ""7 I9 h2 ^- D) N0 {: U* w
fragment.name = ""
6 R& S( v) v1 m6 ] description = fragment.description[12:].split(",")[0]: `" _( M7 d9 P3 I/ [1 R
fragment.description = str(self.readsID) + "." + description0 z; ?9 ^$ \% a3 h6 w$ `
readslength = random.randint(self.minreadslength, self.maxreadslength)/ P2 @9 g) m- h2 y# T
self.allreadslength += readslength
( I: P% l& k: T9 N5 G/ E self.readsList.append(fragment[:readslength])4 x3 C" ]3 y, o$ E7 h4 |& z& Z& A
I6 j0 m& l* {
readslength = random.randint(self.minreadslength, self.maxreadslength)+ {9 G& F: r" b- k' d5 t$ R# A
self.allreadslength += readslength8 _9 a( \9 q6 `6 S' O E" \$ l
B9 j' D! `6 U* S( O fragmentcomplement = fragment.reverse_complement()8 ?! z& m3 ^% k0 v1 |( g
fragmentcomplement.id = "" V% p& z9 P0 b
fragmentcomplement.name = ""7 D' A6 m5 q d( I8 b* e
fragmentcomplement.description = str(self.readsID) + "." + description8 x3 u2 _) k$ A, s
self.readsList.append(fragmentcomplement[:readslength])/ z" g1 N ]; x, r
+ t6 ~) C. m. {0 J
self.readsID += 1. E: _* B" p( B+ _$ z/ T" C. x% T
' S7 O. }% B! P1 Y def pairreadsequencing(self,genomedata, sequencingResult_1, sequencingResult_2):( R# a) n3 Z; J; h3 o' i) i+ ^
for seq_record in SeqIO.parse(genomedata, "fasta"):+ s, i" y9 M R; T
seqlen = len(seq_record)
6 F" @; t$ N. k self.genomeLength += seqlen
8 s/ ]( Q) ^/ u$ r0 F for i in range(self.N):
# ]& Q0 |: C& d! X; i# U # 生成断裂点6 }/ H0 H+ g' E. ?( r9 ?9 j1 J9 h
breakpoint = self.generatebreakpoint(seqlen, self.averagefragmentlength)
' [1 q! Q+ ~( G/ z1 j5 z8 X9 F' h # 沿断裂点打断基因组
4 B% h' [9 R) u self.breakgenome(seq_record, breakpoint, self.minfragmentlength, self.maxfragmentlength)
* f, i, W6 t) W" s; @. f- n # 模拟克隆时的随机丢失情况
* e4 h3 U. L! a3 Y! ^ clonedfragmentList = self.clonefragment(self.fragmentList, self.cloneRetainprobability)
$ Q. i- z. S2 y" M3 T$ L. j( ~ # 模拟双端测序
9 t3 V' ~" w& ]- a8 v+ M& o self.pairread(clonedfragmentList)0 }- \% \9 X# L( R) X& r6 n
readsList_1 = [self.readsList for i in range(len(self.readsList)) if i % 2 == 0]
8 H5 M. I) i) U2 ]" ?6 B/ r" B3 b readsList_2 = [self.readsList for i in range(len(self.readsList)) if i % 2 == 1]- e: e# \7 Z! p
SeqIO.write(readsList_1, sequencingResult_1, "fasta")0 ^: u7 G( r+ t3 @
SeqIO.write(readsList_2, sequencingResult_2, "fasta")) z& ^8 u2 Q4 q- H, O4 }( q6 D4 e- N/ e
. Z/ b/ {, L. C+ X; C& u2 p
def resultsummary(self):
- ]7 H% n5 i' R* t9 _2 f6 R print("基因组长度:" + str(self.genomeLength / 1000) + "kb")
; N8 R( n3 p. h0 M print("片段长度区间:" + str(self.minfragmentlength) + "-" + str(self.maxfragmentlength))5 @7 u O0 X) d' d
print("N值:" + str(self.N))" `# |3 |9 [4 @! ~$ |
print("期望片段长度:" + str(self.averagefragmentlength))7 q5 |$ o7 `- V% ^, R3 K
print("克隆保留率:" + str(self.cloneRetainprobability)), \& [# J/ q4 j- s
print("片段数量:" + str(len(self.fragmentList)))
+ \ @5 d4 a8 z/ U+ e print("reads长度:" + str(self.minreadslength) + "-" + str(self.maxreadslength)), \4 y; {' {0 @
print("reads总数量:" + str(len(self.readsList)))
) N. Z% f8 k8 N: Y print("reads总长度:" + str(self.allreadslength / 1000) + "kb")
% f! x3 Z: s4 T' j m = self.allreadslength / self.genomeLength
0 {) T# l$ O- G/ X+ c! f8 w print("覆盖度(m值):" + str(round(m, 5)))
% m6 K: n" Y% l7 ]7 f print("理论丢失率(e^-m):" + str(round(exp(-m), 5)))
# G* G5 v% _2 V$ D9 s$ a# A2 d5 ~ print("覆盖率(1-e^-m):" + str(round(1 - exp(-m), 5)))
, X" [& v v/ u& n# -------------------------------------------主程序-------------------------------------------
" Z& @! K9 j- O. s! _. M5 m C5 b# 模拟单端测序8 S! n5 z+ s3 J/ w8 V" z" N
sequencingObj = Sequencing()5 `: m5 Z2 x0 u' z/ p( ~
sequencingObj.singlereadsequencing("data/NC_025452.fasta", "result/virusSingleRead.fa")5 F" C P9 m3 d7 ^# g! [' a
sequencingObj.resultsummary()
- s8 N/ u5 j4 K# L- n( Q+ t( X
& H% J1 [! E% ?4 n# 模拟双端测序
0 g; [/ n$ R8 o* `% P7 K$ KsequencingObj = Sequencing()! v' U7 \ S6 y
sequencingObj.pairreadsequencing("data/GCF_000146045.2_R64_genomic.fna", "result/yeastPairRead_1.fa", "result/yeastPairRead_2.fa")
* w( }0 o9 |; Q: x; z3 p) B# GsequencingObj.resultsummary()) j- ?) N; I: q4 Y7 b
from Bio import SeqIO
7 y1 `1 K$ j& D3 Wfrom math import exp
. ], G2 A) P- \+ i' ?1 n8 s8 C$ dimport random
$ ?/ h) \1 T6 n- e
0 J6 x! o5 W- _/ S4 j, _5 K( iclass Sequencing:& h) @" q' e" N
# N代表拷贝份数
0 v) b' E% a- |5 ~! d6 m" s def __init__(self):
* G( `/ |8 H! [# W self.fragmentList = []
$ v4 R4 J7 l* S- H self.readsID = 1
6 I5 D1 c; l5 G$ ~3 n self.readsList = []
0 d" E& K" [! _2 W- D. F0 W; ?# _ self.averagefragmentlength = 650( _+ r/ s' i# r5 Z
self.minfragmentlength = 500* T7 \ s, n) k, I' H8 `- S" W
self.maxfragmentlength = 800
% C0 t; [& `. a$ J& b$ b self.cloneRetainprobability = 1# o- s1 R9 t3 f Z& V- w
self.minreadslength = 50/ N1 B" @# p& ^/ N: \
self.maxreadslength = 1508 Y/ k# F- A; ]& f3 S1 ^) u0 }6 n
self.N = 10
& R4 N9 L' |3 Y8 W' C- w self.genomeLength = 0) F3 Z1 [8 f" L+ v% o, }" G
self.allreadslength = 02 d9 _3 N' F# K
% g% s d3 T R. n; U1 \: e. t # 生成断裂点* M0 d( H6 M; n9 Y& e, }
def generatebreakpoint(self, seqlen, averageLength):& r% O3 t4 C& R ]8 ~" L
# 假设平均每500bp 产生一个断裂点(averageLength = 500),通过随机函数生成seqlen/500个随机断裂点(1到seqlen之间的随机整数)
8 c* s; |7 j5 I) s0 g- A breakpoint = [random.randint(0, seqlen) for _ in range(int(seqlen / averageLength))]6 d0 y! k: ?, T8 w
breakpoint.append(seqlen)
- b4 D7 Q& O9 G. E" D/ n breakpoint.append(0)
1 H# S3 @) [- s6 P7 P' n( x # 把随机断裂点从小到大排序
( c. I7 J( x" B$ u breakpoint.sort()
9 O, B' K/ `9 Z3 L( ~) u, q return breakpoint
% J* A: O7 @, [$ d# w' J$ R9 g1 c4 G4 }8 G
# 沿断裂点打断基因组,并删除不符合长度要求的序列片段,定义片段范围:200-1000bp; \6 h. L: Z! [/ X# h- }
def breakgenome(self, seq, breakpoint, minfragmentlength, maxfragmentlength):5 o, C1 K; D1 V( s. a
for i in range(len(breakpoint) - 1):
" K+ h8 M" Y" f fragment = seq[breakpoint:breakpoint[i + 1]]
c9 s F6 U! { if maxfragmentlength > len(fragment) > minfragmentlength:3 l, W2 G& M, F1 `5 W) U
self.fragmentList.append(fragment)
( a& B& s K$ B: ~9 [ return self.fragmentList
& Q0 ?9 d1 z+ p& Y- a8 X( H0 t& S" [; q
# 模拟克隆时的随机丢失情况,random.random()生成0-1的保留概率7 U8 X f) |; y$ B
def clonefragment(self, fragmentList, cloneRetainprobability):
; z1 P# x% \; T" S clonedfragmentList = []5 @* b6 Z( T! S6 [' ]+ U3 S
Lossprobability = [random.random() for _ in range(len(fragmentList))]: y0 ?" B6 R: C% M: ?2 z
for i in range(len(fragmentList)):
# o3 u' ~2 Y4 x if Lossprobability <= cloneRetainprobability:+ x; s" d- L E# W) C
clonedfragmentList.append(fragmentList)5 k' ?- a6 F6 @) F( i) y. i/ F4 r
return clonedfragmentList
5 ~& Y% _. X: R, y
5 y9 O6 j5 p# r- _) }% s # 模拟单端测序,并修改reads的ID号
# k8 Z2 n: c$ ]1 j, C! M def singleread(self, clonedfragmentList):' D$ J3 ~) i* c+ X$ Q# i; ^
for fragment in clonedfragmentList:
2 { D# b: g/ c* o U fragment.id = ""
; [' P5 }* w: m0 L7 M fragment.name = ""5 Y4 ]/ W% v0 q. g
fragment.description = fragment.description[12:].split(",")[0], h( [! l) ^5 c4 X- R3 T( a
fragment.description = str(self.readsID) + "." + fragment.description, Y1 C5 v2 P- @& i
self.readsID += 10 K6 t! B% G, |
readslength = random.randint(self.minreadslength, self.maxreadslength)8 f( [6 Q B+ D+ D: T0 c
self.allreadslength += readslength
$ o* Q. p I0 _, U' a- H, n self.readsList.append(fragment[:readslength])* Q8 i. g+ p! I
$ v. A8 T6 j) b& @; f4 m5 J: d) M: H& o
def singlereadsequencing(self, genomedata, sequencingResult):
5 |/ B# n% p0 n1 o& r for seq_record in SeqIO.parse(genomedata, "fasta"):
5 ^7 S' B0 r/ q! l1 P' g( X seqlen = len(seq_record)4 q, E7 f# ]' E" X9 z0 A* c$ ?( ~
self.genomeLength += seqlen
3 D7 a; `3 H @5 T$ c6 ~ for i in range(self.N):+ Y* ]9 O' p& ], X+ I1 Q: |0 }8 S
# 生成断裂点$ h$ J$ [0 A# D. C) ]# f5 a
breakpoint = self.generatebreakpoint(seqlen, self.averagefragmentlength)3 g* M: n0 F# z
# 沿断裂点打断基因组5 D0 N4 h! {- h$ S
self.breakgenome(seq_record, breakpoint, self.minfragmentlength, self.maxfragmentlength)
& ?! u2 C/ @8 i: y6 `% ` # 模拟克隆时的随机丢失情况1 `8 T4 L7 o( ? }
clonedfragmentList = self.clonefragment(self.fragmentList, self.cloneRetainprobability)
3 P! r! y' G/ b( }' N" v # 模拟单端测序
; L. R. a/ z: e6 H/ E( ? self.singleread(clonedfragmentList)
& A" a& d0 c* O( v' \4 D SeqIO.write(self.readsList, sequencingResult, "fasta")% W1 Z0 G+ o2 s0 k& v
. r. y4 w5 f' D- M8 J def pairread(self, clonedfragmentList):. u: ~7 R8 V0 m4 L
for fragment in clonedfragmentList:/ K8 t7 D) ^% P% I, n! ?
fragment.id = ""4 T9 Z4 v8 a% t6 B& _, G% q
fragment.name = ""
4 H/ ?: c- I' x( S description = fragment.description[12:].split(",")[0]
% K; ?0 v; a+ X# Y" e5 g2 G fragment.description = str(self.readsID) + "." + description$ w5 ^. g# }* c" k3 t( x5 W
readslength = random.randint(self.minreadslength, self.maxreadslength)# n0 v4 `& A$ q& |8 \! V
self.allreadslength += readslength3 R3 \/ R. Q9 o4 r
self.readsList.append(fragment[:readslength])
7 Q# `2 @8 `" i( |5 N! Z5 ?' v6 |- }. I- @, Y3 h% R) v$ a
readslength = random.randint(self.minreadslength, self.maxreadslength)
! g# V. ~$ s5 y" j$ T# A3 o2 K self.allreadslength += readslength
# [' N, x1 e( [( Z o# M
; y7 {6 b9 d' g fragmentcomplement = fragment.reverse_complement()
% _ t4 k6 e; J6 O& T fragmentcomplement.id = ""$ \' {3 j3 P; W+ V6 u; m
fragmentcomplement.name = ""
2 E- b, w2 B# n2 [' e* S3 ^ fragmentcomplement.description = str(self.readsID) + "." + description
0 V# |$ M3 L4 s, ^ \ L4 T/ p! a self.readsList.append(fragmentcomplement[:readslength])7 p' ^, k) q' W$ S8 w2 J
- X9 s( s* |8 \6 X) E! m2 J, P self.readsID += 1
$ y( }9 d: R0 }( Y; h- m
# I! R" K8 Y2 t$ b9 `, K1 r ] def pairreadsequencing(self,genomedata, sequencingResult_1, sequencingResult_2):
# Z" j) { h* |1 C$ H for seq_record in SeqIO.parse(genomedata, "fasta"):9 A& |) b5 L+ g5 t. U- J d+ ?6 V
seqlen = len(seq_record) p5 ^( o( r! V$ ^ ~$ l+ M+ \* o
self.genomeLength += seqlen
6 l4 T7 c) r1 M8 i for i in range(self.N):; c6 r" U) s! z& w$ o! `
# 生成断裂点
3 c- L, }8 K6 K6 Z breakpoint = self.generatebreakpoint(seqlen, self.averagefragmentlength)) ^, r# b3 P1 l" ?! I
# 沿断裂点打断基因组
f1 B; U+ h% o9 q1 u self.breakgenome(seq_record, breakpoint, self.minfragmentlength, self.maxfragmentlength)
3 n; r+ [ E( B0 V4 m # 模拟克隆时的随机丢失情况
+ {7 G" P6 Z# s( `$ o. R clonedfragmentList = self.clonefragment(self.fragmentList, self.cloneRetainprobability)" K6 e* u# u6 j0 L$ b: \( U
# 模拟双端测序
. r# B2 Z6 e! w: O: Q. i self.pairread(clonedfragmentList)$ s( W; l6 x4 m1 \' ]
readsList_1 = [self.readsList for i in range(len(self.readsList)) if i % 2 == 0]: `2 I' z( l1 D6 L5 H) B+ n
readsList_2 = [self.readsList for i in range(len(self.readsList)) if i % 2 == 1]
, u" P1 m9 n$ I: s( i1 i( { SeqIO.write(readsList_1, sequencingResult_1, "fasta")6 ?$ F- R0 s w2 u2 e
SeqIO.write(readsList_2, sequencingResult_2, "fasta")) E% o \' j4 f) T& g: e
5 R7 Y; t1 C: }# h def resultsummary(self):
1 I i; f/ W# q$ }, h' w print("基因组长度:" + str(self.genomeLength / 1000) + "kb")" g. a3 `8 o& Z5 z# R
print("片段长度区间:" + str(self.minfragmentlength) + "-" + str(self.maxfragmentlength))
( _ t( Q8 P1 P3 @: D print("N值:" + str(self.N))/ V8 f7 e' G% S& Q3 z5 o/ B
print("期望片段长度:" + str(self.averagefragmentlength)): \8 Z: P1 j5 T% c) S' q
print("克隆保留率:" + str(self.cloneRetainprobability))* K% l6 G' u6 J5 `* v% R
print("片段数量:" + str(len(self.fragmentList)))/ d3 h5 P5 y( Y) e1 W
print("reads长度:" + str(self.minreadslength) + "-" + str(self.maxreadslength))9 N& Y* q& X, y0 `$ T
print("reads总数量:" + str(len(self.readsList))): O7 }* p- p) a# v" S h6 g
print("reads总长度:" + str(self.allreadslength / 1000) + "kb")% }% ]- d K5 K$ y
m = self.allreadslength / self.genomeLength5 \1 K% O3 h1 L; |" e: C+ |
print("覆盖度(m值):" + str(round(m, 5)))
0 q& Q9 \+ T5 _1 I( p O' D print("理论丢失率(e^-m):" + str(round(exp(-m), 5)))
- h" f" J" S4 A+ O print("覆盖率(1-e^-m):" + str(round(1 - exp(-m), 5)))
7 o9 j* E7 O z- O6 T: l# -------------------------------------------主程序------------------------------------------- U c! ~9 b1 {" {" R! s
# 模拟单端测序
' M) f7 b4 e; d$ x6 W4 G" t) T4 PsequencingObj = Sequencing(), G* B- c0 j2 K$ @0 H
sequencingObj.singlereadsequencing("data/NC_025452.fasta", "result/virusSingleRead.fa")
! ^' O) p8 Y/ gsequencingObj.resultsummary()" n4 X0 V9 t* k/ Y, e9 D9 p
/ G0 m6 g/ i$ M) F. ?) G
# 模拟双端测序5 c& L* [) \! G; j
sequencingObj = Sequencing()
& x& m0 O2 M; N; A& h7 t9 Z4 HsequencingObj.pairreadsequencing("data/GCF_000146045.2_R64_genomic.fna", "result/yeastPairRead_1.fa", "result/yeastPairRead_2.fa")! K, @( ~, ~1 w6 L4 h7 Y
sequencingObj.resultsummary()+ `8 n$ e F: N% Q% ^3 ]9 p: c
3 U- U8 {9 v; O
$ Z) C) c" b9 f, G5 |- Q+ _! E
. |: ^- l5 B: ^ ; E* Y) {9 `3 Y" K
|
zan
|