- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 566885 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 175288
- 相册
- 1
- 日志
- 0
- 记录
- 0
- 帖子
- 5313
- 主题
- 5273
- 精华
- 3
- 分享
- 0
- 好友
- 163
TA的每日心情 | 开心 2021-8-11 17:59 |
|---|
签到天数: 17 天 [LV.4]偶尔看看III 网络挑战赛参赛者 网络挑战赛参赛者 - 自我介绍
- 本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。
 群组: 2018美赛大象算法课程 群组: 2018美赛护航培训课程 群组: 2019年 数学中国站长建 群组: 2019年数据分析师课程 群组: 2018年大象老师国赛优 |
基因组测序模拟
0 f9 W5 y7 E' y基因组测序模拟* [) {( T4 V5 M4 ~1 \
: m6 i+ F9 W- i1 G
一、摘要
2 u3 J; v4 @( u% F, b; J- ^9 u2 |
C7 B+ S7 J8 v通过熟悉已有的基因组测序模拟和评估程序,加深全基因组鸟枪法测序原理的理解,并且能够编写程序模拟全基因组鸟枪法测序,理解覆盖度、测序深度、拷贝数等概念,设置测序相关参数,生成单端/双端测序结果文件
f9 f/ k# I3 C- L; \1 u/ a- g1 A3 f7 \$ F
二、材料和方法
4 U9 l5 y9 M" b( [7 X. g8 R; s U3 c" u6 o" ^
1、硬件平台
: h8 ^$ _* j; w6 g
) H1 ~4 `, n3 P1 z/ o处理器:Intel(R) Core(TM)i7-4710MQ CPU @ 2.50GHz
- X7 {( z4 S5 |3 Y5 p+ q; H: r" I安装内存(RAM):16.0GB
Z& Y) ~, _0 T* b
0 d9 s8 k T* {: w5 L$ f6 I" ^% Y2、系统平台# t) ?# D/ e) d2 p! H
Windows 8.1,Ubuntu. s5 e x N0 D7 x2 x5 U
B F, F; }3 K# i
3、软件平台
, R/ W$ Y, W& r0 [7 S% j- ?6 u! G( J: n
art_454. |- |( _2 H$ y$ p% W' p
GenomeABC http://crdd.osdd.net/raghava/genomeabc/- b. D" d4 x1 t- r# u
Python3.5- R o$ H3 x$ \, [, B) M3 }
Biopython: J% s' b1 [! @" r, C4 D. L
4、数据库资源2 _% |7 |" {, j9 b/ F
+ C9 r0 O( C3 U' T6 F( P! L1 @
NCBI数据库:https://www.ncbi.nlm.nih.gov/
6 S* I+ ?- ?' \( H1 Q5 F9 n8 z- Q
5、研究对象; ~7 V7 J; w2 i
- R. I P9 ?. H( u
酵母基因组Saccharomyces cerevisiae S288c (assembly R64)
, |5 `6 d' F" A% aftp://ftp.ncbi.nlm.nih.gov/genomes/all/GCF/000/146/045/GCF_000146045.2_R64/GCF_000146045.2_R64_genomic.fna.gz. l( R. {% k9 n) U" e1 \
8 }* y+ I3 a* k* H- L! c
6、方法- _/ _# J O& R3 D# F! C
3 q( o3 B l7 c3 I- ^5 @& R; {" m
art_454的使用 1 O7 K; i, ]# d2 e/ R
首先至art系列软件的官网,下载软件,在ubuntu系统安装,然后阅读相关参数设置的帮助文档,运行程序。
* `$ v" r* r8 C, ]' ^# fGenomeABC * h) X% J6 X$ W* d* M8 p# p7 W
进入GenomeABC(http://crdd.osdd.net/raghava/genomeabc/),输入参数,获得模拟测序结果。
3 W9 @' S* l# q- t! e/ R. H# j" `编程模拟测序 * p4 \$ Z, w# R" {: [' Y; V
下载安装python,并且安装biopython扩展模块,编写程序,模拟单端/双端测序。0 s9 f& Z- Q6 Q' f
三、结果5 i4 C. g7 `1 d) E) Z5 b$ z, U
- W* C) {2 @" I5 q) s; q# G9 Y
1、art_454的运行结果) s7 l+ m" i* k# }" Y4 P
, B' T. a, C9 H( D
无参数art_454运行,阅读帮助文档
+ i1 W/ X9 N5 T5 _/ w' w2 ]- ?. W! y( I: X
图表 1无参数art_454运行 2 {/ N# b7 u& ~8 c+ h; b( x/ q% W) g
对酵母基因组进行基因组单端测序模拟,FOLD_COVERAGE设为20,即覆盖度为20.
2 f$ |" v* |4 V* B, W/ O e' @下图为模拟单端测序,程序运行过程及结果 7 r( K# e8 n& F( \
: C( J2 u6 H/ u
图表 2 art454单端测序 7 X$ @; C- a! f6 L* d# C& i
8 p8 }8 T; |0 N* E# B1 z/ a I
图表 3 art454单端模拟结果 / G& c+ ?' R& H8 @! c3 [8 Z- ?8 w
双端测序模拟,FOLD_COVERAGE设为20,即覆盖度为20;MEAN_FRAG_LEN设为1500,即平均片段长度为1500;STD_DEV设为20,即长度的标准差为20
. O7 W8 T8 s5 W6 m下图为模拟双端测序,程序运行过程及结果 9 G$ U, R. N* g3 O
; F: B( U# t% Q6 H+ x7 L9 c
图表 4 art454双端测序
; w. L+ F! S7 E9 I4 ^
8 Y, f; n3 v1 r' m% |/ }图表 5 art454双端模拟结果 & A" l3 \! J( |! G. V
2、GenomeABC
; X) K; h4 U# R下图为设置参数页面
" ?. Q" v- b3 _5 D" R C( c* S$ _2 Q4 }- @: T# y; C* M. p
下图为结果下载页面
1 {9 {! s7 k: N- I* }
- @7 Z/ c# w! g+ H3 o. A# i0 ~图表 6 结果下载页面
7 c4 \/ g( o; a# C: u5 i3、编程模拟测序结果 - t9 A* H2 W3 m9 e5 A
拷贝数是这里的N值;覆盖度是m,测序深度是宏观的量,在这里与覆盖度意思相同,就是测序仪10X,20X。 * Z9 W3 G& c7 _& ]/ T- \. R% T8 S
单端测序
9 r9 [1 @( g' R: ], z# H2 W! o. w0 a# w
图表 7 程序模拟单端测序 # i( O. x$ U' x Z
双端测序
2 R, v% T' P J/ d5 d6 K3 U+ {
, s6 a1 [/ M3 b P) S0 S2 H. T图表 8 程序模拟双端测序 + @# ?/ S6 g7 x; `* X" w# W
测序结果 & w. _# |9 ?' V g; C
O b5 p4 h: X! V) M# ^: \
图表 9 结果文件
1 v; F5 \" h" z/ D* ]- h; H
2 Q' p# W+ \- u5 S z9 K5 C/ M因为期望片段长度是600bp,在片段长度区间200-1000bp内,所以大部分的片段都没有删除。 + b) {3 d3 ^1 J, M6 z1 ?
测序结果统计表- k/ c1 N3 Q3 J
6 ^* i4 F; C# H7 V. Y2 e测序方式 基因组大小(bp) 片段长度区间 (bp) N值 期望片段长度 克隆保留率 片段数量 Reads长度范围(bp) Reads总数量 Reads总长度 覆盖度(m值) 理论丢失率(e-m) 覆盖率(1-e-m)
4 f' e" j# g# ]" P, {' [单端 12157kb 200-1000 10 600 0.95 107378 50-100 101968 7645.541kb 0.62889 0.53318 0.46682
( w6 p) G6 t+ a% B单端 12157kb 200-1000 20 600 0.95 213722 50-100 202996 15227.882kb 1.25259 0.28576 0.71424
) x3 _1 B1 c7 X! O+ ~双端 12157kb 200-1000 10 600 0.95 106704 50-100 202770 15212.662kb 1.25134 0.28612 0.71388
3 }. S9 Y: m1 i$ T: J6 \- |双端 12157kb 200-1000 20 600 0.95 214212 50-100 407186 30534.265kb 2.51164 0.08114 0.91886
% i6 @( C1 K) ]5 ?4 S8 }$ d四、讨论和结论 G* X7 `* w" F& [
/ ?4 t+ {- z, U) y5 v6 e$ D程序运行方法
; b- g1 L; `) ^3 g3 U2 U. C% S& n8 {7 ]$ i8 y- C! ]
在类的构造方法init()中,调整参数。 0 l* ?* Z6 Q# _# i! s* H6 w8 m
Averagefragmentlength为片段平均的长度; ) w: z4 O8 ~1 r# p% `
minfragmentlength和maxfragmentlength是保留片段的范围; ; r( j$ c6 S) q I/ ^: A- K
cloneRetainprobability是克隆的保留率;
; l% p8 ~3 ^" l# d( }minreadslength和maxreadslength是测序reads的长度范围
7 _- }' J9 M6 n. Z: ], Z. `- [$ @4 _# i5 F$ n7 }
模拟测序的诸多方法都封装成了Sequencing类,只需要创建类,并调用singlereadsequencing()和pairreadsequencing()方法,传入文件名的参数即可。& _* |% ]4 t4 _/ Q3 E& h1 _
. U Y5 V: F! k附录8 `: F0 w/ r7 D6 Z# |5 b, K) Q
b5 Q6 s c, {" s7 I, O% ^; Gfrom Bio import SeqIO
$ i& x- c9 F6 @' w2 l- j8 Ffrom math import exp: E4 m9 I" o% b* @
import random
" b; U$ s( t: N: e% ]3 H
/ M/ {6 z- a1 Q O7 pclass Sequencing:' M0 J g0 ?2 o. D
# N代表拷贝份数
/ ` z5 X" r- l4 `( H def __init__(self)
6 q- Z5 D3 I# [! Z2 w8 ? self.fragmentList = []
. g' d4 D" U9 P, U2 |: y, `$ T self.readsID = 1
- |2 A" o& f1 j* g, C- { self.readsList = []- Q$ p2 l( Y9 B
self.averagefragmentlength = 650
3 r% G( y" E6 `+ R self.minfragmentlength = 500
8 y: M; K' W) {2 E6 j- \ self.maxfragmentlength = 800
) ?; F6 I( g l. d3 [% l$ P self.cloneRetainprobability = 1: a, G5 g' v5 I* X8 G
self.minreadslength = 501 b" b; w9 e% t7 q( {9 O
self.maxreadslength = 1507 j$ V+ M% D4 S- x
self.N = 10* v4 b; J+ B/ k& l+ s
self.genomeLength = 0
5 K% _2 ?: {" L! ` self.allreadslength = 02 n% X' D2 S4 W; M: _+ J0 {; O4 p
* H9 h+ t* H3 D0 u( l# e) t, o
# 生成断裂点8 D4 d' j" x3 G
def generatebreakpoint(self, seqlen, averageLength):
# j0 |4 U( k- c$ N9 P9 V9 T7 z # 假设平均每500bp 产生一个断裂点(averageLength = 500),通过随机函数生成seqlen/500个随机断裂点(1到seqlen之间的随机整数)
3 A0 h" M8 I5 I" c L, w: e breakpoint = [random.randint(0, seqlen) for _ in range(int(seqlen / averageLength))]
! H7 O# n$ G5 h# \3 v- L& T1 l# W breakpoint.append(seqlen)
, ^: ^, Q6 P+ q! P+ n1 | breakpoint.append(0)
" h1 d6 T- c1 y" {( o+ ] # 把随机断裂点从小到大排序: g1 v1 J, D! X" i. p1 O: f& \& x0 b
breakpoint.sort()
: f; y( F% o3 Z6 l! O! x: k1 L return breakpoint) t* t# G, l, y; R
# Y& h) d; _6 g+ {5 W
# 沿断裂点打断基因组,并删除不符合长度要求的序列片段,定义片段范围:200-1000bp
@2 ~5 P6 z* E! J [% w& X def breakgenome(self, seq, breakpoint, minfragmentlength, maxfragmentlength):* o1 ^% l% W1 U& N. ~$ g9 f! P5 _
for i in range(len(breakpoint) - 1):
8 Q8 C% F* Q$ Q+ {4 U2 ]/ m5 O( R fragment = seq[breakpoint:breakpoint[i + 1]]
* [+ m7 L* _. g C$ G$ ^( d if maxfragmentlength > len(fragment) > minfragmentlength:
* ~8 {, s& S$ c: g" e3 i/ \ self.fragmentList.append(fragment)
1 B c$ @+ }0 B0 m8 ~ return self.fragmentList% o' D9 u' b! d8 ~4 `
1 w; d+ y. }/ [: f* L # 模拟克隆时的随机丢失情况,random.random()生成0-1的保留概率6 N3 @9 |* q) d
def clonefragment(self, fragmentList, cloneRetainprobability):
# ^; G: @9 V1 ], v& F" [ clonedfragmentList = []
/ g9 F( v- y1 }* @) U8 K. M9 M Lossprobability = [random.random() for _ in range(len(fragmentList))]3 t9 X' p( G, {
for i in range(len(fragmentList)):
& @. M5 H' w/ V! o4 @ if Lossprobability <= cloneRetainprobability:1 A% k; J1 b$ E$ \+ b" A
clonedfragmentList.append(fragmentList)
# L! R5 ~) ~2 H7 A2 {- I return clonedfragmentList9 y, a5 r5 j" j
0 W* e, t5 m2 c! D # 模拟单端测序,并修改reads的ID号 c2 z' O! A! V& C
def singleread(self, clonedfragmentList):$ c6 ?& L4 o9 P; X
for fragment in clonedfragmentList:
9 i, p$ L% e: t1 I) J. { fragment.id = ""0 B" T7 ]: g7 W$ p5 x" o* M
fragment.name = ""9 S2 g- f' M' v' y! m% f! O; R
fragment.description = fragment.description[12:].split(",")[0]
: d9 C4 E1 [7 R# _2 I fragment.description = str(self.readsID) + "." + fragment.description2 {8 Z6 }: v6 u
self.readsID += 1& _( f+ ^! B' e( G' Z8 ?
readslength = random.randint(self.minreadslength, self.maxreadslength)
( d) U. K! ^8 Z! g/ y self.allreadslength += readslength% D+ U: Q& R1 `/ N" S, A% J
self.readsList.append(fragment[:readslength])/ {4 @( G$ o& P
, r# q9 t! S" q- F: T def singlereadsequencing(self, genomedata, sequencingResult):* u1 m& I( z3 j8 z3 f7 Z1 F
for seq_record in SeqIO.parse(genomedata, "fasta"):0 L4 `" L0 s, k* H4 q1 t; P
seqlen = len(seq_record)
: S6 N2 S) |! s! ` self.genomeLength += seqlen, | {" x1 s4 A2 c3 N) e
for i in range(self.N):* a6 ^% j3 K, T! R& k% j/ K0 j! `; n
# 生成断裂点
& X [* w, x! l4 Y) k3 p breakpoint = self.generatebreakpoint(seqlen, self.averagefragmentlength) \& \! a o! P- z! C9 o% r
# 沿断裂点打断基因组: k0 h) ?3 S7 l: Y
self.breakgenome(seq_record, breakpoint, self.minfragmentlength, self.maxfragmentlength)2 l1 `+ c7 ?$ R& y
# 模拟克隆时的随机丢失情况6 H" ]* k- @9 H
clonedfragmentList = self.clonefragment(self.fragmentList, self.cloneRetainprobability)% K* v4 }8 b- L, x0 [8 g. O
# 模拟单端测序* c: N2 e6 w. i5 B. l9 p
self.singleread(clonedfragmentList)
) B( o) K0 k6 r6 `1 R0 q SeqIO.write(self.readsList, sequencingResult, "fasta")0 J: c- Z$ g% s$ {, X
+ J# {+ C! E9 X3 R7 r/ w" h4 D
def pairread(self, clonedfragmentList):3 N9 s+ r4 [/ S3 p1 d
for fragment in clonedfragmentList:/ Q: [) O1 y% f/ f( [2 t- C
fragment.id = ""# H* X' d/ S, ]4 ]5 n1 L( G' _
fragment.name = ""
' K3 k- X$ h8 m5 v: b; ` description = fragment.description[12:].split(",")[0]8 h |. k6 q8 R4 U- z: {
fragment.description = str(self.readsID) + "." + description
$ q x; W+ U% m, g$ f! b, [) J readslength = random.randint(self.minreadslength, self.maxreadslength)
' a# `* F- J4 Q, S$ K7 z self.allreadslength += readslength$ r. ]$ ?$ m% [; C: l
self.readsList.append(fragment[:readslength])& ~! y; m* f3 T$ @0 b$ q7 y
4 m7 A$ c$ S2 D" R# @
readslength = random.randint(self.minreadslength, self.maxreadslength), [% |& b4 G$ C8 S+ X3 R" d! |
self.allreadslength += readslength
?) T1 S& l n7 F
2 f7 D5 L6 X' [0 g4 d fragmentcomplement = fragment.reverse_complement()1 q: a; T' b3 K- }) n$ z$ j6 Z/ s
fragmentcomplement.id = ""* Z6 }$ \* E- L2 P! [5 Y' n# q" e
fragmentcomplement.name = ""
* E: E" j8 U7 |) N/ T1 g' w fragmentcomplement.description = str(self.readsID) + "." + description
" K& N( D* l: f5 z9 J0 W self.readsList.append(fragmentcomplement[:readslength])- M' H9 N, O* v( P R j$ p- @
7 Z4 n9 @+ k% {' h7 _
self.readsID += 1* Y9 @+ |/ Z- `: H5 [
8 F$ c A& V/ U+ I def pairreadsequencing(self,genomedata, sequencingResult_1, sequencingResult_2):
- G- L1 D% C" H0 ]2 x$ \5 E for seq_record in SeqIO.parse(genomedata, "fasta"):/ m* y! H, P* U C- Y+ k
seqlen = len(seq_record)% E' w1 U3 u/ \7 {' S6 Y
self.genomeLength += seqlen
, S9 ^# N6 c6 i# e. [& L0 ~ for i in range(self.N):
* p3 ?: z8 l, ?% V% b: c0 F7 m F # 生成断裂点6 g7 c+ p& s; b3 r+ C& r
breakpoint = self.generatebreakpoint(seqlen, self.averagefragmentlength)
0 q. ^$ K$ _; t! A2 ]% S # 沿断裂点打断基因组$ e2 v) T! P0 ~% E, a( s) T
self.breakgenome(seq_record, breakpoint, self.minfragmentlength, self.maxfragmentlength)6 f# ]8 `0 G+ v/ j' f( Y
# 模拟克隆时的随机丢失情况 t' h6 F' y+ A- o
clonedfragmentList = self.clonefragment(self.fragmentList, self.cloneRetainprobability)! R0 Z. |! Q; q0 g* T. f
# 模拟双端测序
: o+ F, H3 j9 Z& U* ]5 S self.pairread(clonedfragmentList)6 E5 C) d- T' ]0 K. d2 _( `5 ?
readsList_1 = [self.readsList for i in range(len(self.readsList)) if i % 2 == 0]8 d& x( j1 @% X1 C" }1 r/ h* ~' W
readsList_2 = [self.readsList for i in range(len(self.readsList)) if i % 2 == 1]
5 f" f( @5 v6 j$ @" ~ SeqIO.write(readsList_1, sequencingResult_1, "fasta") y: {( y9 d, Q- _6 g- L/ ~/ b& O6 V
SeqIO.write(readsList_2, sequencingResult_2, "fasta")! x. O R3 H( A) |1 z
, v: x1 H' g: v. S+ k6 { def resultsummary(self):
$ A2 q x- W+ N" D% j print("基因组长度:" + str(self.genomeLength / 1000) + "kb")
7 e& E0 H r) C* K print("片段长度区间:" + str(self.minfragmentlength) + "-" + str(self.maxfragmentlength))
9 N9 @: J b$ g Z print("N值:" + str(self.N))
/ T* `% S& t3 g5 p& |, ~ print("期望片段长度:" + str(self.averagefragmentlength))7 [2 m$ F! s8 ^2 [9 l6 `! ^
print("克隆保留率:" + str(self.cloneRetainprobability))
0 H% |. K; s. X" `5 L9 o print("片段数量:" + str(len(self.fragmentList)))% o8 l2 |( [* v6 m! I% @
print("reads长度:" + str(self.minreadslength) + "-" + str(self.maxreadslength))
7 l2 p1 U9 G" f$ J. D print("reads总数量:" + str(len(self.readsList)))
@/ w, |+ f! {4 Z' p print("reads总长度:" + str(self.allreadslength / 1000) + "kb")
% u; W- `( N) [, c+ J4 G- I m = self.allreadslength / self.genomeLength2 z! J+ j) i& n: D$ h3 ], T9 V
print("覆盖度(m值):" + str(round(m, 5)))( G+ ]- W/ e \; z1 d; _
print("理论丢失率(e^-m):" + str(round(exp(-m), 5)))
# E5 W5 d9 }, M" S/ f* ]7 j. h1 @ print("覆盖率(1-e^-m):" + str(round(1 - exp(-m), 5)))! D U! x! J& K3 d, A, D. ~
# -------------------------------------------主程序-------------------------------------------
* _4 z7 E. n2 ~3 e/ t- Z, K# 模拟单端测序
5 \ @: c; ^) }9 \ [sequencingObj = Sequencing(): } y7 p# [9 D
sequencingObj.singlereadsequencing("data/NC_025452.fasta", "result/virusSingleRead.fa")" H5 s8 L- e% d6 T! h. q
sequencingObj.resultsummary()
9 `3 D- _* g1 J$ B! Z4 N/ c0 \3 e6 `3 w* X! B% N
# 模拟双端测序' w4 M8 K8 g* c+ l1 J" C& {& y) h
sequencingObj = Sequencing()
. C7 T( ~( N3 `" e; z r; vsequencingObj.pairreadsequencing("data/GCF_000146045.2_R64_genomic.fna", "result/yeastPairRead_1.fa", "result/yeastPairRead_2.fa")
7 g1 _! L& [. Y! D9 QsequencingObj.resultsummary(); Q2 B- e$ s7 K9 m% D
from Bio import SeqIO
0 Y* |( {+ I, T+ E% ^0 `3 M$ ^. Kfrom math import exp: q: D$ V, q! b2 w
import random, N1 \9 M- s$ O' C8 v& F& `$ G a0 D
# S3 d; M2 [' @3 wclass Sequencing:% e3 k9 F* L$ ]7 v3 a7 s1 U6 v
# N代表拷贝份数
5 q# u7 z4 k" q* X7 {1 S5 J+ [: M! a def __init__(self):
& `; u/ y+ J6 @( l+ \8 r self.fragmentList = [] Y* @1 `8 U7 V; p" h. ~& {
self.readsID = 17 u& O; R9 v$ h `* Y( H
self.readsList = []: ]" ?1 |; Q( u( D e8 [
self.averagefragmentlength = 650
' _/ e" w1 n+ l7 O7 n# J6 E2 g8 |: V. ~ self.minfragmentlength = 500
* x( t7 Q5 r: [& B. X. N5 i6 d0 A self.maxfragmentlength = 800# q. z# e6 F: [. F/ ~% |
self.cloneRetainprobability = 1$ O: {/ J' r* j" s7 E
self.minreadslength = 50
" Y5 X# _( P# t% V self.maxreadslength = 150
; `8 n1 m3 b: z& `; f self.N = 10% C3 z) T8 c4 A3 {- B
self.genomeLength = 0" v* J7 e4 {* o/ X' q ~
self.allreadslength = 0
. c7 w/ y+ _+ z8 s7 l/ z4 x/ J6 [6 f& X% t/ j' n L# g) h
# 生成断裂点) [. D' G. u0 K; a1 n
def generatebreakpoint(self, seqlen, averageLength):! p j- m# T/ v* c6 V1 p' N
# 假设平均每500bp 产生一个断裂点(averageLength = 500),通过随机函数生成seqlen/500个随机断裂点(1到seqlen之间的随机整数)% U; c+ o: @7 r
breakpoint = [random.randint(0, seqlen) for _ in range(int(seqlen / averageLength))]
1 |4 `1 E; I3 r breakpoint.append(seqlen)) R& d3 `) k9 Q( F9 Q
breakpoint.append(0)
- j/ Z) V3 T* ~0 K- A- {7 O # 把随机断裂点从小到大排序# _$ r, U8 D7 s) @: E
breakpoint.sort()$ h* l' e5 C1 n( \7 G
return breakpoint
2 `( ?8 ^: A6 n& u0 q3 }: j k0 m
c/ x4 g' ^1 B' d" u # 沿断裂点打断基因组,并删除不符合长度要求的序列片段,定义片段范围:200-1000bp
1 q. Y9 G! R+ @! \- l! z6 [ def breakgenome(self, seq, breakpoint, minfragmentlength, maxfragmentlength):2 {% J) m6 W4 @" H
for i in range(len(breakpoint) - 1):
. K4 v; E2 E# ]9 i, Y# l l fragment = seq[breakpoint:breakpoint[i + 1]]
1 q5 {7 a: J( `3 U# r if maxfragmentlength > len(fragment) > minfragmentlength:
) F; P7 v/ h3 J) ]! ^) M8 q6 ? f self.fragmentList.append(fragment)/ v4 M7 Z# B* ~/ \: ~6 J
return self.fragmentList9 `, N) H. M, `, e8 u) g% w
* x0 E2 E5 O U; E6 r # 模拟克隆时的随机丢失情况,random.random()生成0-1的保留概率
' x d5 t5 {5 H4 U def clonefragment(self, fragmentList, cloneRetainprobability):
. G* g6 [' N/ z5 m0 E9 h6 K; ] clonedfragmentList = []
/ V8 v; m" L+ O3 U Lossprobability = [random.random() for _ in range(len(fragmentList))]6 ]" _( K3 u v3 S e& Z2 u
for i in range(len(fragmentList)):; R+ Z, y1 l1 t& u
if Lossprobability <= cloneRetainprobability:0 ^/ R! i7 d/ U1 o! W+ R
clonedfragmentList.append(fragmentList)! v8 @1 W9 s' |! ?( c$ |
return clonedfragmentList4 l U; H2 s0 d+ u( Z! C5 e. m C
4 j% P$ [. ~) f0 S& F0 `5 Q- C6 _; _4 n2 S
# 模拟单端测序,并修改reads的ID号
r) | G0 t* ~0 ]# s& B def singleread(self, clonedfragmentList):7 a) v2 P1 g1 k9 e9 m7 p6 o H
for fragment in clonedfragmentList:
; h: `2 o; S, ]& q2 O4 c fragment.id = "". K6 E/ j. d0 D, D7 t/ N: R
fragment.name = ""
9 l$ j+ @# q$ K6 U fragment.description = fragment.description[12:].split(",")[0]5 G# C* e1 X( ~2 G' q( |
fragment.description = str(self.readsID) + "." + fragment.description% n+ k8 W8 J( U9 p# O8 i
self.readsID += 1
- |+ a5 g6 U8 V% \+ d readslength = random.randint(self.minreadslength, self.maxreadslength)
: B8 C) T" d# l3 \6 _( O self.allreadslength += readslength& Y' l. L: T+ r2 R* A
self.readsList.append(fragment[:readslength])* Z! X P' `, w6 D! R- m9 T
$ t& V4 i2 \* R1 k0 A# R6 s" V def singlereadsequencing(self, genomedata, sequencingResult):
/ `8 e8 |% X) i* O4 V' R ]2 N9 \7 z for seq_record in SeqIO.parse(genomedata, "fasta"):. p( E! y' K9 ^! E$ k/ h
seqlen = len(seq_record)
* u9 q- U; U J. _% r( p: n. l self.genomeLength += seqlen& j& y; b) H" A- J
for i in range(self.N):; E8 E$ ]5 n$ s2 L
# 生成断裂点
& ~+ o! ~- _: ^, l" ]$ a/ `. A breakpoint = self.generatebreakpoint(seqlen, self.averagefragmentlength)
9 J# K+ d. \: p1 ^+ i# ~7 k# Z # 沿断裂点打断基因组% n7 g; d/ n% h. C! e# o
self.breakgenome(seq_record, breakpoint, self.minfragmentlength, self.maxfragmentlength)
7 @8 g# y0 ~. _; W# z, u X # 模拟克隆时的随机丢失情况# \7 C+ W5 u7 R4 Z2 g2 W9 b" D
clonedfragmentList = self.clonefragment(self.fragmentList, self.cloneRetainprobability)
" e: Y$ Z4 }; B# V" S9 H7 M # 模拟单端测序; `& J- j; b' K2 Z5 `# x
self.singleread(clonedfragmentList)/ ~( N F4 K# N( @
SeqIO.write(self.readsList, sequencingResult, "fasta"), l, w7 M) o5 A& T" h/ _! r: x
" D# R. F/ {9 V
def pairread(self, clonedfragmentList):3 D6 b: V% j7 e& _
for fragment in clonedfragmentList:, s) C" a! b: J _- [; U
fragment.id = "") m. w% T7 l% D$ l( }$ X
fragment.name = ""
/ a5 e. T/ m" b2 ~. _$ a description = fragment.description[12:].split(",")[0]
7 h# |% e6 i) U fragment.description = str(self.readsID) + "." + description4 E4 ]3 Y, L9 C5 S
readslength = random.randint(self.minreadslength, self.maxreadslength) ~, S$ y# {1 `5 x
self.allreadslength += readslength: P. l4 k/ W ^4 [! |
self.readsList.append(fragment[:readslength])
6 [7 g* C; A4 _+ o1 M s( `! R
( p! m% N; M3 n& R- p% S readslength = random.randint(self.minreadslength, self.maxreadslength)) N* w+ t7 L9 g* g. h
self.allreadslength += readslength
1 I6 Z- Y( j3 e, y9 l6 D. C+ m# m X- s6 x% y, H
fragmentcomplement = fragment.reverse_complement()
[9 T) K+ ]; V/ \) B fragmentcomplement.id = ""
2 M5 `4 O0 F: {9 W; X0 t7 | fragmentcomplement.name = ""8 i( V j. r# ]' M/ A
fragmentcomplement.description = str(self.readsID) + "." + description
" V$ Z& s7 ?) L; F* o self.readsList.append(fragmentcomplement[:readslength])
4 H7 N& z% I& A
% i% o5 O1 ?! [ K R self.readsID += 1
& `" p0 Q: B7 u4 J
5 Q- Y$ Z# w% a! ]4 a def pairreadsequencing(self,genomedata, sequencingResult_1, sequencingResult_2):
6 U5 q! W3 e) S8 S( Q5 ^ for seq_record in SeqIO.parse(genomedata, "fasta"):
1 m4 @ Y+ T' J# f) u) K- j seqlen = len(seq_record). m* h7 e* ^ X" l" \0 i7 u
self.genomeLength += seqlen
7 Z6 U- p6 w3 [ for i in range(self.N):' @5 _# x! M; s' t
# 生成断裂点
6 ?) D) F3 t, K$ W/ d' Y. G breakpoint = self.generatebreakpoint(seqlen, self.averagefragmentlength)
. d/ {- z; E# J! x: l6 o # 沿断裂点打断基因组
7 N2 k" K# I; w, @+ Y E self.breakgenome(seq_record, breakpoint, self.minfragmentlength, self.maxfragmentlength)
2 C3 T* s# i+ V' p$ {$ T$ F [6 n # 模拟克隆时的随机丢失情况
* _, X. l1 {& r4 s5 u7 I clonedfragmentList = self.clonefragment(self.fragmentList, self.cloneRetainprobability): _+ b- }8 T- l6 {8 b
# 模拟双端测序
6 d1 C$ v. J" ]6 b/ l. W: q self.pairread(clonedfragmentList)8 Q( `+ I2 O3 M7 r; O) R
readsList_1 = [self.readsList for i in range(len(self.readsList)) if i % 2 == 0]
c8 f- I9 V0 s- E. ]2 F readsList_2 = [self.readsList for i in range(len(self.readsList)) if i % 2 == 1]
$ H/ [; \$ x4 t0 k; D SeqIO.write(readsList_1, sequencingResult_1, "fasta")
9 R) f! W, |9 k$ ?2 I4 J SeqIO.write(readsList_2, sequencingResult_2, "fasta")
1 m$ p* `. X& x ?% H' S/ R' s
& V" ^5 H. H/ Z! u J0 w; o) J5 p def resultsummary(self): D1 `5 w/ D; }8 \5 i9 ~* {
print("基因组长度:" + str(self.genomeLength / 1000) + "kb")
* {3 E$ D2 q0 c print("片段长度区间:" + str(self.minfragmentlength) + "-" + str(self.maxfragmentlength))
, o+ ^3 f7 L% m6 b# N5 M' V1 o, n* R print("N值:" + str(self.N)) j. _) j9 n. _* W9 E
print("期望片段长度:" + str(self.averagefragmentlength))
; r9 [* a' X3 A1 d6 L print("克隆保留率:" + str(self.cloneRetainprobability))
+ i* X- X3 M, j5 {* r+ V print("片段数量:" + str(len(self.fragmentList)))
6 j1 m/ I% V& U7 E" |' N print("reads长度:" + str(self.minreadslength) + "-" + str(self.maxreadslength))
( G4 m- b# z/ A( i3 R6 ` print("reads总数量:" + str(len(self.readsList)))+ h% h7 i8 T2 @( t( l
print("reads总长度:" + str(self.allreadslength / 1000) + "kb")
6 D! A I# g8 G& w. s2 a5 [ m = self.allreadslength / self.genomeLength6 ~3 H- W7 B$ \
print("覆盖度(m值):" + str(round(m, 5)))
3 z7 G9 b7 h: u% v/ n, g5 K! w5 V print("理论丢失率(e^-m):" + str(round(exp(-m), 5)))
2 t% t1 w" N# t; p9 f5 @ print("覆盖率(1-e^-m):" + str(round(1 - exp(-m), 5))), T k) ?! j* Z5 g
# -------------------------------------------主程序-------------------------------------------
1 C* ~7 M: t) w% S# 模拟单端测序
* J" }' l$ `$ w1 SsequencingObj = Sequencing()6 u; S( \* s- u! E+ ]7 P2 i
sequencingObj.singlereadsequencing("data/NC_025452.fasta", "result/virusSingleRead.fa")5 f9 g" W+ W; E. [% p* V$ _1 f
sequencingObj.resultsummary()! Z4 A N( P7 C2 A: ^+ E
/ y1 D/ @7 j" J' Y# 模拟双端测序
$ K9 F3 L8 r3 y' ~3 {sequencingObj = Sequencing()
/ }) I Q" C, x: W ?/ ]# a% ysequencingObj.pairreadsequencing("data/GCF_000146045.2_R64_genomic.fna", "result/yeastPairRead_1.fa", "result/yeastPairRead_2.fa"); m& m2 i& s2 ~" x8 `. ~& V. @' D9 U
sequencingObj.resultsummary(); r; I2 h) h2 E+ W; \+ J
* z. Y! ~1 b0 ^: L. J
' E0 s9 a. R1 ~, t, W+ C8 ~6 u- K8 y. ^
7 z2 N' W- H P1 E% Y Q |
zan
|