- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 566811 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 175266
- 相册
- 1
- 日志
- 0
- 记录
- 0
- 帖子
- 5313
- 主题
- 5273
- 精华
- 3
- 分享
- 0
- 好友
- 163
TA的每日心情 | 开心 2021-8-11 17:59 |
|---|
签到天数: 17 天 [LV.4]偶尔看看III 网络挑战赛参赛者 网络挑战赛参赛者 - 自我介绍
- 本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。
 群组: 2018美赛大象算法课程 群组: 2018美赛护航培训课程 群组: 2019年 数学中国站长建 群组: 2019年数据分析师课程 群组: 2018年大象老师国赛优 |
基因组测序模拟2 G( F k( v4 x$ O8 M
基因组测序模拟4 |. I# b# q" Y- ]' g/ [
5 n# i9 _6 o9 L- {: ?. ?2 M( @一、摘要' m9 x/ f) O0 Q! _5 A7 S
8 t0 W$ V3 K: N
通过熟悉已有的基因组测序模拟和评估程序,加深全基因组鸟枪法测序原理的理解,并且能够编写程序模拟全基因组鸟枪法测序,理解覆盖度、测序深度、拷贝数等概念,设置测序相关参数,生成单端/双端测序结果文件# b% p$ W& D5 H8 E% C; b3 E
# `& z2 k! {, M I二、材料和方法$ z: z1 M3 @9 V# ]/ ?
z) Z6 X8 \# r+ c# v3 T1、硬件平台
9 q$ L( e4 |6 _+ f9 v
% t$ L' r, N! ]4 }& w% v3 s处理器:Intel(R) Core(TM)i7-4710MQ CPU @ 2.50GHz
$ G6 \1 m1 F4 ?& @安装内存(RAM):16.0GB( f( ?& [) c9 h$ t3 X4 }
' h" s# ]& g4 i/ w$ I2、系统平台. @# L) e8 H& S* N* I3 H" }: ?8 G' y& ]
Windows 8.1,Ubuntu
( v0 R" Z5 y. M- `5 B$ _- \( [* G& o
3、软件平台
' m9 B6 D' H+ T; i, S0 N" X0 f4 a# ^/ o. Q
art_4547 T2 ?2 w- h" C6 ~( I
GenomeABC http://crdd.osdd.net/raghava/genomeabc/
. N* @9 P& a* T1 c- IPython3.5
* J+ D7 @6 T( ^4 xBiopython5 n3 _' |! k' t$ n# T
4、数据库资源" Q# {. @* Y) @
' T0 @0 A9 ^- z0 u2 A" @3 D0 X2 @
NCBI数据库:https://www.ncbi.nlm.nih.gov/# l" t6 i7 n# V, G" W, h/ _
5 }' w; ?# r, n
5、研究对象
, t! v& j* E8 r: S/ ^, o: b9 e8 @7 B( ?1 O
酵母基因组Saccharomyces cerevisiae S288c (assembly R64) ) h& }$ p- |& s2 n: Y
ftp://ftp.ncbi.nlm.nih.gov/genomes/all/GCF/000/146/045/GCF_000146045.2_R64/GCF_000146045.2_R64_genomic.fna.gz
/ F+ `$ h% q+ r; c, j, O+ C4 C8 a3 H3 `; Q/ V: I: v
6、方法
& f( P a1 D7 ~3 ]' `$ f6 }8 A6 h. X8 i; A8 `
art_454的使用 & Z e4 G( D3 g2 d
首先至art系列软件的官网,下载软件,在ubuntu系统安装,然后阅读相关参数设置的帮助文档,运行程序。! D: _4 O0 V& ]4 a5 R
GenomeABC & `/ l3 w3 q. m8 a% H# @( U6 H
进入GenomeABC(http://crdd.osdd.net/raghava/genomeabc/),输入参数,获得模拟测序结果。* P! Y. _0 p) Q. r6 o) \
编程模拟测序 , S3 f. \( Q3 M
下载安装python,并且安装biopython扩展模块,编写程序,模拟单端/双端测序。
" v/ f! r6 G/ Z三、结果
+ b7 w. ?' e# U# w+ l% U; m/ ?; C9 {$ H; ~ m
1、art_454的运行结果' N/ f* [4 a1 K; F% {
; d' O4 c! y- C8 Y/ z
无参数art_454运行,阅读帮助文档
% K% s! V5 r6 k- ?! [2 q8 t$ {5 J0 _; m
( e* k5 J P' ?9 v0 ^图表 1无参数art_454运行
4 j0 D; c0 V3 l9 |对酵母基因组进行基因组单端测序模拟,FOLD_COVERAGE设为20,即覆盖度为20.
9 [, b! I( p1 L9 \下图为模拟单端测序,程序运行过程及结果
1 I8 n) G7 A m2 o( e# G4 ?9 Z9 x+ x6 `8 Y" }% g
图表 2 art454单端测序 1 b5 _$ N5 c( ]2 H8 _
2 J- j7 X( M4 m' g+ S8 ]. ~7 ^4 x图表 3 art454单端模拟结果
' f* M$ H: k: q( V' r$ e双端测序模拟,FOLD_COVERAGE设为20,即覆盖度为20;MEAN_FRAG_LEN设为1500,即平均片段长度为1500;STD_DEV设为20,即长度的标准差为20
z9 T3 [1 x8 n+ p+ }& R$ ?下图为模拟双端测序,程序运行过程及结果 , N# W/ P5 _5 ?' r; }7 _8 W
5 J, U" d! T1 q; G- N. m) _* H图表 4 art454双端测序
9 y2 \1 P1 d4 q3 h4 @: C+ { B+ q; X0 h) ]' F
图表 5 art454双端模拟结果 " C# {! o. p, F v1 ^: l* Y
2、GenomeABC ( H7 Q) T+ V5 m! ]6 Q
下图为设置参数页面 2 J. O |7 \' I: M
. e; l4 \/ E0 E$ P! o下图为结果下载页面 , E1 _2 T+ c0 n& z! Y1 D% [! ]
+ ]! s; p: W2 P# h5 }+ C- }' K3 i图表 6 结果下载页面 9 \1 a! E! X( H4 f, [3 Q4 K
3、编程模拟测序结果 : u# \, D, h; u% X5 g
拷贝数是这里的N值;覆盖度是m,测序深度是宏观的量,在这里与覆盖度意思相同,就是测序仪10X,20X。 {# O3 K' B% c: b4 v* Z$ l8 f
单端测序
/ Z3 V1 `5 s. Y9 q( }* @5 e
1 N# b( Y! G' w& _9 d2 O图表 7 程序模拟单端测序
2 M, l) G) I8 ~双端测序 / j4 s8 C7 ~" u. l; f7 V
& S7 b ]/ o7 B4 g0 j! C图表 8 程序模拟双端测序
$ r8 n* i6 {2 `7 [4 M: O) m测序结果
) ~" M% @* B& s2 D/ ^, c" t0 n# Y. a0 }8 D( ~% {. _
图表 9 结果文件
! `5 o* t0 z; x+ a- |
1 Z3 }& |; p8 L1 J因为期望片段长度是600bp,在片段长度区间200-1000bp内,所以大部分的片段都没有删除。 * E. @8 J4 |4 F! x2 `- v
测序结果统计表! i. y; q$ F( f$ n
; o/ ]( |. q: z* h8 D' R( g* I- t测序方式 基因组大小(bp) 片段长度区间 (bp) N值 期望片段长度 克隆保留率 片段数量 Reads长度范围(bp) Reads总数量 Reads总长度 覆盖度(m值) 理论丢失率(e-m) 覆盖率(1-e-m)
9 w P4 A4 I* \+ ?" L单端 12157kb 200-1000 10 600 0.95 107378 50-100 101968 7645.541kb 0.62889 0.53318 0.46682 p; @% h. A- c' H) E
单端 12157kb 200-1000 20 600 0.95 213722 50-100 202996 15227.882kb 1.25259 0.28576 0.71424# W: C- O& j+ h6 b4 @$ h* x/ H
双端 12157kb 200-1000 10 600 0.95 106704 50-100 202770 15212.662kb 1.25134 0.28612 0.713885 \- b8 C& f7 J9 \% t' L+ r& i- I7 T
双端 12157kb 200-1000 20 600 0.95 214212 50-100 407186 30534.265kb 2.51164 0.08114 0.91886: P+ x8 \ w2 Z- ^* l
四、讨论和结论6 `7 C' x/ G, n. O+ a% Y" ~$ J
8 Y! ~5 ?* B1 _程序运行方法5 K/ i( i6 t- a5 N. V! A
" H/ g7 r( B4 Z7 ]6 r1 u8 w; n
在类的构造方法init()中,调整参数。
2 S" u2 F* z5 I0 J; e! \Averagefragmentlength为片段平均的长度; * O7 {3 t. d" u" w+ M8 I
minfragmentlength和maxfragmentlength是保留片段的范围; - t- |7 U% X7 |1 m$ _3 S" T. }
cloneRetainprobability是克隆的保留率; : Z; R3 u G4 B2 I0 i1 N; r/ F$ K
minreadslength和maxreadslength是测序reads的长度范围' r: k! z" J% ?4 \( B9 U
. ~% X K+ q+ b) B' t
模拟测序的诸多方法都封装成了Sequencing类,只需要创建类,并调用singlereadsequencing()和pairreadsequencing()方法,传入文件名的参数即可。0 @5 D4 p" e# L6 y5 T; i/ W
- a" s" N; n8 O x' o附录3 N* K2 s3 Q& @
+ B: ^# K. ~: a+ B2 M/ kfrom Bio import SeqIO/ y! X$ @/ n1 | N4 j
from math import exp! P- O8 c# h+ o2 s' B* H3 S" f5 t
import random+ Z- M7 N6 b4 {- j0 z: ]% |" W
) d K. h/ U2 Dclass Sequencing:$ h/ s/ @. ~ a1 R
# N代表拷贝份数
* k4 |' @$ [$ w- v4 i def __init__(self)
! e, y# W) D4 B1 l+ ^* {9 }; s& ` self.fragmentList = [] f }, O T: D
self.readsID = 1
$ `* n* X$ H* b- U self.readsList = []- U& H8 |/ ]& O0 p- W4 p, O7 S
self.averagefragmentlength = 6507 K* G# @3 q- V c& Q
self.minfragmentlength = 500
' x7 r& I# W P self.maxfragmentlength = 800
) T& l2 P7 B8 \) M7 S% { self.cloneRetainprobability = 1
: c9 S6 n5 H( Z' U/ o self.minreadslength = 50
2 r) _ K, k9 c/ h# }# h3 H- v self.maxreadslength = 150* G2 v% h' I6 b* F
self.N = 103 x w! J. ?6 P) c5 p
self.genomeLength = 0
( P) J' g) U" D% |4 B0 f6 ]7 h self.allreadslength = 0 }1 T- q/ z% s
/ Z8 y" J2 Y) a D5 c4 b # 生成断裂点
0 ^3 E4 o6 q C" ^9 k5 B def generatebreakpoint(self, seqlen, averageLength):( ?8 o% F9 }' v$ }/ I: ^8 _8 X
# 假设平均每500bp 产生一个断裂点(averageLength = 500),通过随机函数生成seqlen/500个随机断裂点(1到seqlen之间的随机整数)4 x5 C$ t3 N ?8 n0 Q$ `
breakpoint = [random.randint(0, seqlen) for _ in range(int(seqlen / averageLength))]
0 f8 x- o8 a) @! M+ j9 P breakpoint.append(seqlen)
8 x9 @# I2 D; {! B5 s0 C breakpoint.append(0)
, B7 K; S9 D9 s; z5 q2 X b8 ? # 把随机断裂点从小到大排序
; v8 y6 _8 W: i# O6 H( Z5 y breakpoint.sort(): u7 p: A( ]% m, @
return breakpoint
3 ~& h) A _4 j; u- n' G4 y- F$ u$ E+ F5 M4 u5 M
# 沿断裂点打断基因组,并删除不符合长度要求的序列片段,定义片段范围:200-1000bp. B5 v5 O( J X- W. B* ]
def breakgenome(self, seq, breakpoint, minfragmentlength, maxfragmentlength):
9 W; C4 Q# k3 K for i in range(len(breakpoint) - 1):1 f# a/ G2 f$ X% J! K# G7 o
fragment = seq[breakpoint:breakpoint[i + 1]]
- N6 ^0 y; z7 @, j0 r if maxfragmentlength > len(fragment) > minfragmentlength:
4 i% B6 j2 r# W# }: V self.fragmentList.append(fragment)- C! F% x: j4 E4 Y% S4 t! s
return self.fragmentList; b# r; \& ^) z, K% P/ {% g
( T4 r1 w; n3 h- e, W& A: `! n& { # 模拟克隆时的随机丢失情况,random.random()生成0-1的保留概率
+ s+ ^+ N8 s) `& M4 a2 e( E def clonefragment(self, fragmentList, cloneRetainprobability):
J6 ?# a. H8 n' c8 g m' k$ ? clonedfragmentList = []
! n& X' R5 D0 D+ D5 l Lossprobability = [random.random() for _ in range(len(fragmentList))]
; m- x6 L; I- t4 l+ p# k for i in range(len(fragmentList)):; u, U8 K+ ^1 x9 H$ Z/ V
if Lossprobability <= cloneRetainprobability:
0 q, y6 r) X% P! B1 n, ]- v6 ]% P clonedfragmentList.append(fragmentList)
8 L( C0 T. O5 A7 s return clonedfragmentList
- l0 z1 l2 @, c2 B: c% B0 n" V! V7 ?8 _
# 模拟单端测序,并修改reads的ID号7 V# c2 P9 @& I, ^7 {" u
def singleread(self, clonedfragmentList):0 @+ p5 W2 M2 _4 ]# w" F$ s. e% n
for fragment in clonedfragmentList:9 D: \* f+ S/ P
fragment.id = ""
$ j u+ w1 i# j fragment.name = ""# D* }/ Z M8 `% |
fragment.description = fragment.description[12:].split(",")[0]
7 q$ [1 B; O. Q& `1 o' l fragment.description = str(self.readsID) + "." + fragment.description4 U4 s/ _! v- b4 u _) g( O! U& n; m
self.readsID += 1
. h8 O/ y+ g0 d- A) l readslength = random.randint(self.minreadslength, self.maxreadslength)
6 D1 \& C$ n3 B+ l$ v# M4 n" O self.allreadslength += readslength% ^: D6 S" F) e0 X9 @! i
self.readsList.append(fragment[:readslength])9 q0 e. }3 | i' \. o
0 Z7 z, u% E# m7 t
def singlereadsequencing(self, genomedata, sequencingResult):) L! U9 l+ ~4 `/ @0 O9 l! D' G
for seq_record in SeqIO.parse(genomedata, "fasta"):9 G) t T, }$ b! z$ {9 O+ I
seqlen = len(seq_record)
) n5 n# U1 p$ ~# Y* G9 { self.genomeLength += seqlen
0 d) f: k1 @ y6 K! ~) ^ for i in range(self.N):# W' x: d$ _2 c% t' A; C
# 生成断裂点
& I) @, E3 \1 u/ s& g% v breakpoint = self.generatebreakpoint(seqlen, self.averagefragmentlength)
2 x" u! r1 m1 e7 y: R) ?6 B, w # 沿断裂点打断基因组" t* H F0 r% X g4 h
self.breakgenome(seq_record, breakpoint, self.minfragmentlength, self.maxfragmentlength)
4 r5 P& U0 [) T l- |* g # 模拟克隆时的随机丢失情况' e0 L* h! s. i' z# y7 t" b
clonedfragmentList = self.clonefragment(self.fragmentList, self.cloneRetainprobability)9 P7 A6 V$ A) K. w, O
# 模拟单端测序" T$ q: Y w# p) D/ t! y
self.singleread(clonedfragmentList)$ E$ L: b1 c! u! Q
SeqIO.write(self.readsList, sequencingResult, "fasta")( j$ N8 v, r0 W9 Q+ |9 [. f9 t
* }3 T9 P" e0 B def pairread(self, clonedfragmentList):* h( P6 V7 k1 I4 B) T
for fragment in clonedfragmentList:
5 E; p |2 y! _* C3 ~! Q fragment.id = ""
" X0 Q; ] N0 q3 F fragment.name = ""
- t3 r" U6 k' G/ B- `8 C0 m description = fragment.description[12:].split(",")[0]! K: f3 g2 ~9 \ r: L0 k8 P
fragment.description = str(self.readsID) + "." + description
" o1 a6 F5 d* u9 l' m3 Y' W readslength = random.randint(self.minreadslength, self.maxreadslength)
# ~" b2 U8 [) _& I0 @3 k- w/ `" k self.allreadslength += readslength6 M4 V+ Y0 Y; t% E' o" s1 q& } t
self.readsList.append(fragment[:readslength])$ F: p" Y+ W/ d( z. i
2 q; k, v! J8 m. ~3 [$ ? readslength = random.randint(self.minreadslength, self.maxreadslength)
+ U( j4 \/ L2 O self.allreadslength += readslength7 u. b1 p* v- D& l5 w h% ?, @( A
; C& ^: n+ M* Y fragmentcomplement = fragment.reverse_complement()& T9 D/ L) i0 a+ d
fragmentcomplement.id = ""0 L% m. p8 K, H$ m( G& C) K, s
fragmentcomplement.name = ""
0 z" f. S/ m+ v' Z2 @: o fragmentcomplement.description = str(self.readsID) + "." + description
S0 R: w& o. w5 j5 n, | self.readsList.append(fragmentcomplement[:readslength]); J4 h: x$ I& Y9 I. i
) c& @3 R3 G' {$ l* A. ^8 ]1 ~8 f v
self.readsID += 12 l9 [8 Y2 X$ g4 R* e" B5 a
! }; h. K% K: P
def pairreadsequencing(self,genomedata, sequencingResult_1, sequencingResult_2):
' h6 b" F" X E( T1 Y% K7 m for seq_record in SeqIO.parse(genomedata, "fasta"):
! C# Z/ ^9 l" a: R& R; \ seqlen = len(seq_record)+ M& M: ~2 m7 i! Z+ S( S
self.genomeLength += seqlen4 l) o& `5 k: F
for i in range(self.N):
% Q9 P" Q% C; z1 Y- ^& k" ` # 生成断裂点: J% ^+ Z, a% Y+ o8 M; X; C" A+ d
breakpoint = self.generatebreakpoint(seqlen, self.averagefragmentlength)# B% U3 L/ m2 M& g6 d
# 沿断裂点打断基因组
: j3 b& v$ y3 Q8 C7 { self.breakgenome(seq_record, breakpoint, self.minfragmentlength, self.maxfragmentlength)$ O& C* ]: }2 Y& E7 _5 v/ V4 Z6 J
# 模拟克隆时的随机丢失情况4 Y% l+ D1 u J" }+ j1 U4 Q3 F# ~
clonedfragmentList = self.clonefragment(self.fragmentList, self.cloneRetainprobability)
( Q; O q! W1 Z* a. k Q # 模拟双端测序
Z# Q# n+ y4 I1 S8 S self.pairread(clonedfragmentList)' w' n. M- ]- d
readsList_1 = [self.readsList for i in range(len(self.readsList)) if i % 2 == 0]. ]7 R, n4 X# B0 {/ P& t$ t
readsList_2 = [self.readsList for i in range(len(self.readsList)) if i % 2 == 1]
2 e. b# W/ w% P/ d SeqIO.write(readsList_1, sequencingResult_1, "fasta"): `* l2 d/ v7 W7 E* w
SeqIO.write(readsList_2, sequencingResult_2, "fasta")6 k% z9 o4 @3 z' @0 k! R2 M8 f
# v( ~' o# d; m, O, j5 l4 a
def resultsummary(self):
) l, p" c4 a1 b0 g print("基因组长度:" + str(self.genomeLength / 1000) + "kb")
/ u# M/ V" I9 b print("片段长度区间:" + str(self.minfragmentlength) + "-" + str(self.maxfragmentlength))5 r% K3 k0 Y: @4 M @& {6 X
print("N值:" + str(self.N))
* L" `) ^6 |+ D& C9 D5 ^4 L print("期望片段长度:" + str(self.averagefragmentlength))6 q/ B! f3 S9 q# j% }
print("克隆保留率:" + str(self.cloneRetainprobability))
. Z5 m/ r J$ e) N z: B print("片段数量:" + str(len(self.fragmentList)))
1 H0 }2 p* x( }+ ?$ D1 O print("reads长度:" + str(self.minreadslength) + "-" + str(self.maxreadslength))4 @2 g5 m% v; M, u: O
print("reads总数量:" + str(len(self.readsList)))" l- [+ \6 l9 {) u3 F0 d! U
print("reads总长度:" + str(self.allreadslength / 1000) + "kb")
7 q6 g* A( z4 G5 u: o/ f } m = self.allreadslength / self.genomeLength) `: i' H# D; V# {3 L+ Q
print("覆盖度(m值):" + str(round(m, 5)))
$ K9 g9 F+ H4 [+ h Z7 i# D print("理论丢失率(e^-m):" + str(round(exp(-m), 5)))' t" D8 j% i8 W( A8 C/ k! ]4 i% K3 r
print("覆盖率(1-e^-m):" + str(round(1 - exp(-m), 5)))
9 A" U: J. l( b! w% d# -------------------------------------------主程序-------------------------------------------
6 F8 M: I$ d% X# 模拟单端测序6 R. E9 Y1 C- ?5 J, m8 K
sequencingObj = Sequencing()1 J5 d! R1 o- h, g9 L) J, Q
sequencingObj.singlereadsequencing("data/NC_025452.fasta", "result/virusSingleRead.fa")
1 Z4 _: d( n V- LsequencingObj.resultsummary(): M$ C/ }3 z# _4 b7 F, B8 |5 N
( j3 h& @0 E( |7 e9 T1 U, r
# 模拟双端测序
" q( j3 P* C; e: c% G* csequencingObj = Sequencing()# i% d6 i* U! K. v! e
sequencingObj.pairreadsequencing("data/GCF_000146045.2_R64_genomic.fna", "result/yeastPairRead_1.fa", "result/yeastPairRead_2.fa")
4 L1 r7 R7 [9 O' x1 ysequencingObj.resultsummary()
, C& F+ x0 k# i6 `from Bio import SeqIO
8 n' J& a! W: i* I0 m; I/ v/ nfrom math import exp1 _5 h, e6 o m
import random
4 j( b6 o0 |4 C; }% F& M; d
5 \! E& i2 \0 Fclass Sequencing:
# m9 U1 B- a- o3 M) l4 ~+ [- G # N代表拷贝份数& b! {+ f' W/ M3 [6 Y" W, t
def __init__(self):
+ m" j* Q( E+ u) M3 t, Z% m self.fragmentList = []
" ^5 ^% L+ P! i2 } self.readsID = 1' H) N# u' \) E2 _8 O! D1 t
self.readsList = []' X. J* p* ]; R1 M% m& Z1 W* L. \. _. }
self.averagefragmentlength = 650# Q. o# z2 X5 u: [
self.minfragmentlength = 5001 B6 h- _* q: p& o
self.maxfragmentlength = 800
+ h' ~) f7 B. J6 h self.cloneRetainprobability = 1
& {0 ?! D/ F6 c. s self.minreadslength = 50$ \* w) l& I1 g# e
self.maxreadslength = 150
& q+ ~5 n- C) m$ v. y self.N = 100 p4 q8 H. t; O/ Q0 N+ M
self.genomeLength = 0) g% L" H1 G* Q" F
self.allreadslength = 00 |" d9 t7 F$ [% \+ u0 a
$ [) Z2 Z3 P/ n8 N
# 生成断裂点! d' J' j8 C; ~! _/ A
def generatebreakpoint(self, seqlen, averageLength):
: U" T) t2 g* D3 q # 假设平均每500bp 产生一个断裂点(averageLength = 500),通过随机函数生成seqlen/500个随机断裂点(1到seqlen之间的随机整数)
8 D- d( M1 e6 L& x breakpoint = [random.randint(0, seqlen) for _ in range(int(seqlen / averageLength))]
; Y; N: J1 Y# v* x/ K, Z breakpoint.append(seqlen)
( o- @% s5 n! m4 G$ U0 ~5 j: j breakpoint.append(0)
% y5 H2 H- ~& U0 j' B1 d # 把随机断裂点从小到大排序
( D: Y: e- r7 O8 g0 i, D breakpoint.sort()8 r* |4 N, ?( J: j. Q
return breakpoint
y/ l2 ]( C, v$ ]+ V! b/ d$ ~5 i* M6 j2 J+ u- K2 a" r n& S5 P
# 沿断裂点打断基因组,并删除不符合长度要求的序列片段,定义片段范围:200-1000bp6 m0 \" `: B" ]% t- q
def breakgenome(self, seq, breakpoint, minfragmentlength, maxfragmentlength):- i, ?3 g$ C0 r( M9 f! b
for i in range(len(breakpoint) - 1):
: V R. Y) O6 u$ z3 Y# z fragment = seq[breakpoint:breakpoint[i + 1]]# o$ h% H7 R0 {; T
if maxfragmentlength > len(fragment) > minfragmentlength:# E% x0 b, W( t4 e8 d& r
self.fragmentList.append(fragment)
( A& G7 ?/ b) g0 y return self.fragmentList% t$ L1 |. g. i$ p; l" i4 @' G
! S# m: W! q2 g( s. j1 v& `6 l
# 模拟克隆时的随机丢失情况,random.random()生成0-1的保留概率
1 p1 R' q0 ~, B r- z4 A2 A def clonefragment(self, fragmentList, cloneRetainprobability):
1 ?; ^4 i1 V7 ~( K clonedfragmentList = []' N+ g5 B! o3 Q& t& m9 }* v1 z5 y
Lossprobability = [random.random() for _ in range(len(fragmentList))]4 ?8 n! f3 X, S, z. L
for i in range(len(fragmentList)):6 i! W1 z. z5 L7 C) x5 E3 N
if Lossprobability <= cloneRetainprobability:- y8 b+ d, F0 k7 [
clonedfragmentList.append(fragmentList)) X6 n9 i( e) ~ F% E3 B
return clonedfragmentList! ~. V. e: w& h
5 G( i$ X0 V) U0 m: Z# f2 f # 模拟单端测序,并修改reads的ID号
- O0 |- s, H: q& X8 a* V7 T4 F def singleread(self, clonedfragmentList):% C% j. b3 {9 R0 O! s J) G
for fragment in clonedfragmentList:9 s' R- m, _' h ^
fragment.id = ""0 r9 G; U9 ~$ a+ X$ P7 U
fragment.name = ""
1 V& ~, R6 O U1 q/ l: k fragment.description = fragment.description[12:].split(",")[0]2 T1 v- S" ^% P# e& `0 ]
fragment.description = str(self.readsID) + "." + fragment.description
8 X& }. R. m4 L! {& ^! {4 C self.readsID += 1
; R; b$ Q, X" X% J1 ^ readslength = random.randint(self.minreadslength, self.maxreadslength)
' P% O& L% S* T/ K( f2 h2 O self.allreadslength += readslength
% t# V& D+ K2 A* p' p4 f+ f$ z self.readsList.append(fragment[:readslength])
, u; }! b3 |0 Z7 u* b4 Y
8 n2 F) U5 Y! t: N" Y def singlereadsequencing(self, genomedata, sequencingResult):
# M; x [: t9 G1 V* b6 h for seq_record in SeqIO.parse(genomedata, "fasta"):3 T* V( H: `4 T. ]4 y
seqlen = len(seq_record)& w: b! f6 T1 t. b+ ^* b, ]7 n
self.genomeLength += seqlen
6 A% p" F7 h0 Z, E; n5 I3 e for i in range(self.N):
3 A; R& B9 i# _+ r1 j' p # 生成断裂点
' j$ ]6 X% ^" c; B& j5 Q breakpoint = self.generatebreakpoint(seqlen, self.averagefragmentlength)* q+ \5 M$ b$ n+ `+ z' |. h' j
# 沿断裂点打断基因组# s, w% u3 O' Z7 r8 f% s
self.breakgenome(seq_record, breakpoint, self.minfragmentlength, self.maxfragmentlength)
, n3 w3 K! D+ R$ v # 模拟克隆时的随机丢失情况9 u$ ~4 M" R0 S8 y( p' f" D
clonedfragmentList = self.clonefragment(self.fragmentList, self.cloneRetainprobability)0 r7 z+ |/ y1 T. W" g
# 模拟单端测序
5 t9 L$ i4 n$ V1 S self.singleread(clonedfragmentList)" e6 p0 o9 g1 f$ [* {8 j* u
SeqIO.write(self.readsList, sequencingResult, "fasta")
4 G% D" _* j1 }0 i9 B. }- b' T' I) G7 q
def pairread(self, clonedfragmentList):
( R% F$ ?8 L: j) }* C3 O for fragment in clonedfragmentList:
. g f6 I% E1 X' F9 P& q. |7 j L fragment.id = ""
m% z" B, F1 Z% m0 @0 ? fragment.name = ""7 h( r' t r: W, w }) y4 s% m) R
description = fragment.description[12:].split(",")[0] l$ |3 Q0 m& w. Y9 J" J
fragment.description = str(self.readsID) + "." + description/ z$ Z+ H- e& e- t
readslength = random.randint(self.minreadslength, self.maxreadslength)
8 g- |- e+ P4 Q+ D, o1 K* k$ z self.allreadslength += readslength
q8 R$ J! t$ ~7 Y# R% l4 k3 T9 f; I# w self.readsList.append(fragment[:readslength])
: W) _9 V# R E; x- ? L& c7 [; s. j2 t) r5 k. O5 Z
readslength = random.randint(self.minreadslength, self.maxreadslength)
! k4 z; S( Y# X, Q) s8 t3 u9 X self.allreadslength += readslength
" C! j$ k% B8 ]/ P7 K0 d5 L! O2 N, |8 ]! Q
fragmentcomplement = fragment.reverse_complement()
/ F% |0 \; R4 F5 n fragmentcomplement.id = ""
7 U8 d9 g8 L5 g+ R( b$ K \$ M0 F fragmentcomplement.name = ""
% d- f5 {6 w8 D4 ` fragmentcomplement.description = str(self.readsID) + "." + description5 S& B* ^8 [# J6 b
self.readsList.append(fragmentcomplement[:readslength])$ D6 U8 _, Y* p% t9 K) C! i/ B! o
, k2 I" q8 B! w self.readsID += 1
9 m8 }* I& n' L# R5 X) v7 M
$ h o6 i# l# ~ def pairreadsequencing(self,genomedata, sequencingResult_1, sequencingResult_2):$ O' P# }$ W6 s; {: i& a6 V) i
for seq_record in SeqIO.parse(genomedata, "fasta"):3 C" e4 [: n0 {0 ~" {
seqlen = len(seq_record)0 i! q6 y& u; ?8 q* ^9 ]/ a/ n
self.genomeLength += seqlen) v# r5 \( k* N- j0 b& r5 l
for i in range(self.N): o- X6 l8 }7 H2 U
# 生成断裂点
. }5 r8 q, i; m4 Y* s breakpoint = self.generatebreakpoint(seqlen, self.averagefragmentlength)7 E0 X' |& O; x3 q- B* C( q$ w/ z
# 沿断裂点打断基因组
& h; b4 K/ c- G/ D/ C3 M0 ^. v self.breakgenome(seq_record, breakpoint, self.minfragmentlength, self.maxfragmentlength)
+ ]! a3 h; p8 q G3 F& M7 c! S1 d # 模拟克隆时的随机丢失情况
% x8 ]; G* H* o: L clonedfragmentList = self.clonefragment(self.fragmentList, self.cloneRetainprobability)9 h2 B& Y8 B: M" m; {
# 模拟双端测序3 G% J" ~% M6 O& P, ^
self.pairread(clonedfragmentList)
# c" C v! Q5 T# { readsList_1 = [self.readsList for i in range(len(self.readsList)) if i % 2 == 0], j( C- N# F: L
readsList_2 = [self.readsList for i in range(len(self.readsList)) if i % 2 == 1]
0 V8 e9 z# K, R h3 p; p$ u SeqIO.write(readsList_1, sequencingResult_1, "fasta")7 ]# H2 g5 L0 |
SeqIO.write(readsList_2, sequencingResult_2, "fasta")) A9 s* L t+ V4 v! y9 [
2 i! A( Q) k# o def resultsummary(self):
6 s4 F4 t3 {- x U3 ^6 ~ print("基因组长度:" + str(self.genomeLength / 1000) + "kb")
# p, ~5 l4 @# s( X: H2 B, |4 c print("片段长度区间:" + str(self.minfragmentlength) + "-" + str(self.maxfragmentlength))
$ `- k$ H7 I6 t$ Z. C0 { print("N值:" + str(self.N))
5 k' u6 E) f; G0 e) i* P print("期望片段长度:" + str(self.averagefragmentlength)); U7 N5 s% g! ~* P1 r
print("克隆保留率:" + str(self.cloneRetainprobability)) s. U% n4 B9 b% x2 h1 h- j
print("片段数量:" + str(len(self.fragmentList)))
+ S8 b7 P$ I' o9 _" g X print("reads长度:" + str(self.minreadslength) + "-" + str(self.maxreadslength))
0 [8 G0 R6 g" h M print("reads总数量:" + str(len(self.readsList)))' Y! {; V g: i$ B# S% x8 K6 d
print("reads总长度:" + str(self.allreadslength / 1000) + "kb")
b+ @0 Z1 j& G6 r! w- m# g m = self.allreadslength / self.genomeLength! f2 m4 T7 b! v9 }
print("覆盖度(m值):" + str(round(m, 5)))
W3 \& |$ i- h* f, Y- U5 J# [ print("理论丢失率(e^-m):" + str(round(exp(-m), 5))); f% n. Q% Q' S. B
print("覆盖率(1-e^-m):" + str(round(1 - exp(-m), 5)))
* `) h$ y4 t6 J4 c4 i) U5 Y c# -------------------------------------------主程序-------------------------------------------
8 y. P0 M! H7 L# 模拟单端测序
; R8 {' ~! e; C7 e+ TsequencingObj = Sequencing()8 Q4 U8 d; Y& O
sequencingObj.singlereadsequencing("data/NC_025452.fasta", "result/virusSingleRead.fa")- S: \& q$ z# w r
sequencingObj.resultsummary()
& ~' k' e$ N$ i: R3 W. v6 e5 N# | Q5 z5 t% m5 R6 e, h$ T; p
# 模拟双端测序
2 J, F( c7 ^. l4 w! ?sequencingObj = Sequencing()4 Y2 ]9 c1 F; y- Y, @5 C. M, G
sequencingObj.pairreadsequencing("data/GCF_000146045.2_R64_genomic.fna", "result/yeastPairRead_1.fa", "result/yeastPairRead_2.fa")
4 f4 d! P( X! A2 W: UsequencingObj.resultsummary()
7 [( W) H" R/ g' T! ^3 n: t( [6 M
, x$ ^: X9 U" H H$ D8 f, y5 E
r5 M) b* l, Y# e P- [! W6 _+ b! R( h4 I0 b4 A. G/ f, r/ B
]; D1 z. a" ]
|
zan
|