- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 565528 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 174881
- 相册
- 1
- 日志
- 0
- 记录
- 0
- 帖子
- 5313
- 主题
- 5273
- 精华
- 3
- 分享
- 0
- 好友
- 163
TA的每日心情 | 开心 2021-8-11 17:59 |
|---|
签到天数: 17 天 [LV.4]偶尔看看III 网络挑战赛参赛者 网络挑战赛参赛者 - 自我介绍
- 本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。
 群组: 2018美赛大象算法课程 群组: 2018美赛护航培训课程 群组: 2019年 数学中国站长建 群组: 2019年数据分析师课程 群组: 2018年大象老师国赛优 |
基因组测序模拟
: z9 M- R+ s8 D. r6 ^- I0 N基因组测序模拟1 T6 q1 J5 n3 i, R
* [0 \- L) F, V( n( g, I5 |一、摘要
~; x0 }" }6 F1 u d
& y- h p* \0 O/ K& x; m- V6 c通过熟悉已有的基因组测序模拟和评估程序,加深全基因组鸟枪法测序原理的理解,并且能够编写程序模拟全基因组鸟枪法测序,理解覆盖度、测序深度、拷贝数等概念,设置测序相关参数,生成单端/双端测序结果文件- p& ~* H5 N3 ~9 ~
: {! P* Y% h/ F! g$ F9 k二、材料和方法1 v( ~ p; e9 i8 }$ p g
+ z3 G6 e# A6 {' R" E. U
1、硬件平台9 a3 p6 ?/ l+ m- z; U5 a @
' Z% e& p! Z% E( V" |0 ?
处理器:Intel(R) Core(TM)i7-4710MQ CPU @ 2.50GHz C/ [% T/ o3 n! e% U7 E
安装内存(RAM):16.0GB
, D8 e3 \' y2 l, ~
* i& L$ M0 w+ M4 Y3 B% K. Q2、系统平台4 h' b+ A) _5 E2 u
Windows 8.1,Ubuntu
/ c7 g+ r, k% U9 O1 ?$ C! ` T& F0 m; r
3、软件平台+ B3 m! W2 D( X. ^9 b2 o4 u) ?
' S/ g8 V' k% R, d# x) d" X0 `
art_4546 I$ }& q5 p/ Y" q
GenomeABC http://crdd.osdd.net/raghava/genomeabc/
0 s6 I5 @9 [; Y$ Q' |1 dPython3.5) `, }2 ]" |! v/ G( n. w9 U
Biopython/ V. R6 o6 s- X' g5 W6 p' d5 d: J
4、数据库资源
, F# @$ C% m8 i* d$ B3 R, K6 S: s3 a2 A' B& E0 U5 B! v: E
NCBI数据库:https://www.ncbi.nlm.nih.gov/
1 j- m# u: q9 o/ K/ b& A8 P* ~- Z) A7 l/ ?5 q
5、研究对象
# x# @/ ~/ a$ x6 E j& |& i$ @; l1 g& t& H/ `" a' F! s3 \
酵母基因组Saccharomyces cerevisiae S288c (assembly R64) . x: L) i) M q: }
ftp://ftp.ncbi.nlm.nih.gov/genomes/all/GCF/000/146/045/GCF_000146045.2_R64/GCF_000146045.2_R64_genomic.fna.gz
4 j$ S% h" u: D0 o: S, ?; v; G+ C# |+ `, @% P
6、方法
% l: f" p) u. E4 ~6 k. k
) V6 { n$ V4 y, ~art_454的使用 : m& s, d' E2 v" L7 N- ^+ d# v
首先至art系列软件的官网,下载软件,在ubuntu系统安装,然后阅读相关参数设置的帮助文档,运行程序。' y J" l) c& ]4 K0 g
GenomeABC
# G, H/ E# E# E0 n. s进入GenomeABC(http://crdd.osdd.net/raghava/genomeabc/),输入参数,获得模拟测序结果。
3 Z# F' O; v2 t6 R, b- d4 ~编程模拟测序 9 ]2 G1 e* Z1 N$ Y1 A
下载安装python,并且安装biopython扩展模块,编写程序,模拟单端/双端测序。! q0 k) L2 \ w2 Z7 x
三、结果4 b4 W: U& `9 Q. u
0 t) }0 d' t0 j3 \) W' g& E1、art_454的运行结果% ?4 M- f2 E* [. v9 M4 V: Z* h
, a! A' C, H* J, ]; }1 B
无参数art_454运行,阅读帮助文档
8 t7 S% k0 `6 k) U+ P" O% A# G$ H$ T# D2 E+ z
图表 1无参数art_454运行
" p/ h2 l) {0 i3 `$ k对酵母基因组进行基因组单端测序模拟,FOLD_COVERAGE设为20,即覆盖度为20. 7 k k3 o9 c* [( x+ Q
下图为模拟单端测序,程序运行过程及结果 . n8 {3 ]1 A7 R* p0 c; G5 T& k8 c
- g9 T% ^. M; s5 V图表 2 art454单端测序
- B$ e* _; h& P3 f+ P: B5 T9 b' G) |9 \
图表 3 art454单端模拟结果
/ T/ }4 {4 c y& q双端测序模拟,FOLD_COVERAGE设为20,即覆盖度为20;MEAN_FRAG_LEN设为1500,即平均片段长度为1500;STD_DEV设为20,即长度的标准差为20 / j7 a9 Q8 W+ R8 x, A6 e7 R
下图为模拟双端测序,程序运行过程及结果
9 @6 N: o, P, V( m1 a c/ R2 [
& {3 Q0 m4 q+ u+ i& X+ P, w% D$ E5 p图表 4 art454双端测序 - N3 w5 ~0 i1 A) W3 C
; \) G& B. l$ g
图表 5 art454双端模拟结果 2 E& o5 Z* Q+ W( R
2、GenomeABC 2 K! C% T0 A. Z! K, `3 C1 F
下图为设置参数页面
: J, }5 }6 J: a5 t& M
6 J; O# P/ s& M( D; G下图为结果下载页面
4 e* J1 x1 Q% K$ L) r! W3 L" k7 r0 W" ]0 _1 C8 z* W5 }
图表 6 结果下载页面 % I" O! @' s( ~( t, t( w
3、编程模拟测序结果
% a$ ^: O% j; X拷贝数是这里的N值;覆盖度是m,测序深度是宏观的量,在这里与覆盖度意思相同,就是测序仪10X,20X。 , p. Y& e7 d; q1 P S, a
单端测序 : l) }5 B1 _9 M: m* r$ e+ s
1 f+ F7 ] @. y
图表 7 程序模拟单端测序
1 z. A' F, A2 O/ m( v双端测序 5 T/ L% {3 \0 h+ O4 s! _) B: I
M. v4 `! t# i" B, s* |, ^
图表 8 程序模拟双端测序 8 ]. F6 n( S) I: e ^8 v2 l
测序结果 7 u# t. E% e4 B8 S, [8 H9 ~* I
; Y/ G% q) A L# K5 q: c9 S; R7 L; F
图表 9 结果文件
% J7 P8 U; R# \* h2 J
4 {, g, X* k. j$ S3 P( J因为期望片段长度是600bp,在片段长度区间200-1000bp内,所以大部分的片段都没有删除。 7 P6 U, K# C( i3 L
测序结果统计表
+ E- `' n9 O- G/ k8 W6 n' _& }0 G( x( E, c3 l3 L8 X
测序方式 基因组大小(bp) 片段长度区间 (bp) N值 期望片段长度 克隆保留率 片段数量 Reads长度范围(bp) Reads总数量 Reads总长度 覆盖度(m值) 理论丢失率(e-m) 覆盖率(1-e-m)
7 g% X8 t9 v, q# i单端 12157kb 200-1000 10 600 0.95 107378 50-100 101968 7645.541kb 0.62889 0.53318 0.46682
3 T/ @: B& }, C8 C. E单端 12157kb 200-1000 20 600 0.95 213722 50-100 202996 15227.882kb 1.25259 0.28576 0.714244 _! b( \" Y6 m$ g* M( `! Z
双端 12157kb 200-1000 10 600 0.95 106704 50-100 202770 15212.662kb 1.25134 0.28612 0.71388& B6 a4 x% ~3 \1 l; Q$ Q
双端 12157kb 200-1000 20 600 0.95 214212 50-100 407186 30534.265kb 2.51164 0.08114 0.91886" R3 X6 q( {% j/ c# n& R. C
四、讨论和结论
- c' R$ i# s8 @8 W
+ {1 N) ^9 C& ~$ }2 I程序运行方法
6 y8 Y- w! Z7 n1 A4 R, L
. x( A; j( {0 k% M r5 v b在类的构造方法init()中,调整参数。
# h3 y$ k2 E4 t* ]Averagefragmentlength为片段平均的长度; ' E% j" m ?; M# [4 H0 H
minfragmentlength和maxfragmentlength是保留片段的范围;
/ ?: ^7 |9 m6 O3 r7 QcloneRetainprobability是克隆的保留率; , a$ u, [. _4 c( X( G
minreadslength和maxreadslength是测序reads的长度范围
: ]! \9 A. w+ i9 Q" l! r$ u1 `- g
+ ~0 L2 Y' D. \& z, ^模拟测序的诸多方法都封装成了Sequencing类,只需要创建类,并调用singlereadsequencing()和pairreadsequencing()方法,传入文件名的参数即可。* `, l$ O) J( O3 Q
! T ?" K: z1 q2 I* @ N. R附录
) ^+ {# K( |, O* y; U) k0 V1 G! |7 l/ X3 v
from Bio import SeqIO }( ?/ Q5 j" x( G% ]0 E
from math import exp: N) \2 m. A% H3 f% c) R; s6 y+ j; I
import random! g) J: `2 b/ y' z# R; H
$ t$ s' h- i. N9 H
class Sequencing:1 [( Z; @7 ^. T7 B/ B# ]
# N代表拷贝份数
) x, I: d! B# w6 F def __init__(self)! r" j1 r- Y4 T |; U% a7 F" }% J
self.fragmentList = []
) h* @5 l) h- y7 m7 E9 t. U8 ? self.readsID = 1
! A) V3 V# _2 X9 U, c+ a( V self.readsList = []
' P* p7 ], Q+ u. r# F5 y+ d/ i self.averagefragmentlength = 650
4 `) C1 X! X5 n/ K& i9 r3 h! F self.minfragmentlength = 5009 Q, [* G; O# s' A h" \( D3 d+ ~5 n. I
self.maxfragmentlength = 800
/ |0 y6 |1 q; Z8 g0 p' w self.cloneRetainprobability = 1. q; D7 `, k2 J* {
self.minreadslength = 50/ D. d* y/ ? P: w1 Z
self.maxreadslength = 150
8 X% m, Q) J9 b2 J self.N = 10& D" v- I% u2 t0 e) u# g
self.genomeLength = 0
. T; C5 @6 G$ O self.allreadslength = 00 d. O) H$ F7 J2 K: Y
7 @( p% @# u8 V2 W! I! S # 生成断裂点# }& w/ a5 Q4 x! m; h2 D
def generatebreakpoint(self, seqlen, averageLength):$ j* v N9 O9 E4 |1 i
# 假设平均每500bp 产生一个断裂点(averageLength = 500),通过随机函数生成seqlen/500个随机断裂点(1到seqlen之间的随机整数)
9 B {; C2 t5 e# K+ g breakpoint = [random.randint(0, seqlen) for _ in range(int(seqlen / averageLength))]9 Q) [: r3 S3 B' m8 S
breakpoint.append(seqlen)' n% N& k0 k: F/ z9 n" A$ e/ Q
breakpoint.append(0)
8 F2 U9 N/ I1 d # 把随机断裂点从小到大排序
' b9 T, n) h- s* O7 z# | breakpoint.sort()5 m; Z. Y1 E# L7 D' M2 e& s
return breakpoint! i8 S* I' X+ Z* C/ h8 \1 T
. }0 ^0 K B" p0 ^ a1 t+ P # 沿断裂点打断基因组,并删除不符合长度要求的序列片段,定义片段范围:200-1000bp
( o" ^9 Q$ Y* \7 u3 f, h def breakgenome(self, seq, breakpoint, minfragmentlength, maxfragmentlength):
! k8 N8 j; ?3 {+ ]' {7 r( R for i in range(len(breakpoint) - 1):
+ H; I$ G( t3 y! d7 p d6 | fragment = seq[breakpoint:breakpoint[i + 1]]
# Q' z- Q- `' N' L if maxfragmentlength > len(fragment) > minfragmentlength:
( u$ [ X- |7 Q) t" I4 l1 a& _3 l8 p self.fragmentList.append(fragment): [- X0 W5 K1 ~3 r* c
return self.fragmentList; L* J1 R5 ~( O
5 u( C( A! j m8 u2 Y9 k- h# k
# 模拟克隆时的随机丢失情况,random.random()生成0-1的保留概率. f$ V, ~" N- n2 _5 h" u6 `& Z
def clonefragment(self, fragmentList, cloneRetainprobability):
" h: w. D0 x6 P, G6 U clonedfragmentList = []% j- q& P& H5 M' Z# l" X ~# x
Lossprobability = [random.random() for _ in range(len(fragmentList))]/ x5 g3 k& l" Z. @) M
for i in range(len(fragmentList)):
8 j3 i/ `3 i, v/ M5 `) }: D if Lossprobability <= cloneRetainprobability:
9 I# T5 [% F1 t( V& T1 H k clonedfragmentList.append(fragmentList)
* R0 [" M# L$ @1 O% C. [ return clonedfragmentList
. v" C5 G4 f9 o/ k* R
+ }" T3 g* ]. d6 m' \ # 模拟单端测序,并修改reads的ID号
. `+ m# D5 k% S' y: D5 b def singleread(self, clonedfragmentList):$ i6 e: b) H2 w6 ?; P" E' L2 k. n) |* y
for fragment in clonedfragmentList:
, b' t4 `+ ~" A1 R# R fragment.id = ""
# \4 P! J D& e6 G; r fragment.name = ""+ c/ X* Y' k/ ?" W/ U8 J
fragment.description = fragment.description[12:].split(",")[0]" X; C( i- S+ q9 V0 o0 p
fragment.description = str(self.readsID) + "." + fragment.description
% `/ D' i7 q" O9 L2 Q! O$ H4 e' g self.readsID += 1
2 ]. s: J; F0 l4 ~ readslength = random.randint(self.minreadslength, self.maxreadslength)/ u3 [' c" C7 H* _7 Q& h; u
self.allreadslength += readslength
/ B- d' j* W7 i1 G4 u self.readsList.append(fragment[:readslength])
- D8 s5 L( T1 p
- l- U/ {' x0 `* h' m1 x def singlereadsequencing(self, genomedata, sequencingResult):' |+ O% J4 ]7 f9 [0 z
for seq_record in SeqIO.parse(genomedata, "fasta"):
$ V2 _! V4 I8 A seqlen = len(seq_record)* g( [8 c8 g" o
self.genomeLength += seqlen3 d# p& H# j. ^1 g( o
for i in range(self.N):$ Y* }2 d- A7 Y6 W4 v( `
# 生成断裂点
: l0 d5 {8 f3 c- M2 P: j( ]8 {0 X breakpoint = self.generatebreakpoint(seqlen, self.averagefragmentlength)
- Y7 _2 |7 j0 I% } # 沿断裂点打断基因组
# W8 {; P5 {* ^/ q" o self.breakgenome(seq_record, breakpoint, self.minfragmentlength, self.maxfragmentlength)
1 b( ?, q3 N% G' v: Y5 g" s Q; k # 模拟克隆时的随机丢失情况* b* s8 ]: ~) ^' H
clonedfragmentList = self.clonefragment(self.fragmentList, self.cloneRetainprobability)
! a% ?9 v3 M; l5 `) l4 l # 模拟单端测序
1 g# a( S a- K. s' Y6 P. N self.singleread(clonedfragmentList)
; ~3 `3 Q+ m/ ]1 A. C7 n SeqIO.write(self.readsList, sequencingResult, "fasta")" W% g- i0 R- N9 t* E9 {7 r H: Y
! z. r' J9 q# Y+ U: U" e0 x8 B1 d6 r
def pairread(self, clonedfragmentList):# L& r5 u2 H6 I1 p9 |
for fragment in clonedfragmentList:
) _3 X+ a9 j; _# s% S2 ~- ]+ W) C7 f- K fragment.id = """ @9 f( L8 ]2 N+ j) o3 ?3 v
fragment.name = ""! Y6 ^9 _( j: G# C, [
description = fragment.description[12:].split(",")[0]
5 _4 K: F+ O* j8 `. M fragment.description = str(self.readsID) + "." + description0 z& y2 I7 y$ f; T0 P
readslength = random.randint(self.minreadslength, self.maxreadslength)) J& ^! n4 b) U, ? k- i) R1 [2 `
self.allreadslength += readslength# i, x! M% o5 f, t* T
self.readsList.append(fragment[:readslength]), J0 y2 q8 y" M3 S% n- q
0 z t6 U% q- z" J% {" ~ readslength = random.randint(self.minreadslength, self.maxreadslength)
! u1 l0 T' `' m/ s, r1 B self.allreadslength += readslength1 c- O' E# e+ h/ |' m
" {9 k8 I/ ^) I7 w4 J
fragmentcomplement = fragment.reverse_complement()9 A' [3 H0 P6 w8 V$ S# [
fragmentcomplement.id = """ h @+ T. A; w- M" N0 j1 }9 M
fragmentcomplement.name = ""# Q8 b c- g5 X; _6 M) o
fragmentcomplement.description = str(self.readsID) + "." + description
2 W4 D) O. U" u self.readsList.append(fragmentcomplement[:readslength])5 M) o4 T+ E% Q F' ^8 d
, X8 N! L: B+ O! }2 g self.readsID += 1
* G8 [: ^+ A. ?- E: o5 {) P0 J, q0 ?
def pairreadsequencing(self,genomedata, sequencingResult_1, sequencingResult_2):# H3 A0 P$ ~& _2 {; U( ?5 H
for seq_record in SeqIO.parse(genomedata, "fasta"):5 U$ `: B3 V# j9 g: I. x
seqlen = len(seq_record)
7 ?4 C& m8 l2 [8 a" z self.genomeLength += seqlen1 R' i2 ]* u: m+ p* g
for i in range(self.N):+ q+ @" a5 ]2 {4 n0 T& {
# 生成断裂点
9 m, v* f( `3 ~$ j! |1 S; X4 N& [ breakpoint = self.generatebreakpoint(seqlen, self.averagefragmentlength)
6 f; u1 N5 \: d) D # 沿断裂点打断基因组) @. @$ c- f& L# I
self.breakgenome(seq_record, breakpoint, self.minfragmentlength, self.maxfragmentlength)
" ~8 S/ T6 k' n2 o. o( \/ v% s # 模拟克隆时的随机丢失情况
/ C+ ^. F2 E( } clonedfragmentList = self.clonefragment(self.fragmentList, self.cloneRetainprobability)
* |# Y* {4 K' r' m # 模拟双端测序
& Y# p$ g1 J8 d) O% L- Y self.pairread(clonedfragmentList)
/ K+ x9 N, }; K) }+ ?* U! R" a, s readsList_1 = [self.readsList for i in range(len(self.readsList)) if i % 2 == 0]: t+ j9 i, m- t/ D
readsList_2 = [self.readsList for i in range(len(self.readsList)) if i % 2 == 1]. L8 |& m3 H" v% v$ Z- @- V: D
SeqIO.write(readsList_1, sequencingResult_1, "fasta")
+ c9 z5 M: a W& u3 Z1 z, l* ?: ~ SeqIO.write(readsList_2, sequencingResult_2, "fasta")6 r9 i6 {3 h h! g: I
4 l( J" T- ?6 }
def resultsummary(self):( m1 }. c. }2 ^- `9 u3 Y4 l8 k
print("基因组长度:" + str(self.genomeLength / 1000) + "kb")# y% P; {: Q) a' X5 `, F2 s
print("片段长度区间:" + str(self.minfragmentlength) + "-" + str(self.maxfragmentlength))
7 o8 Q, ~ n$ T* z print("N值:" + str(self.N))
J6 b+ r! }$ o print("期望片段长度:" + str(self.averagefragmentlength)); m5 K1 b& I: ~" c1 Q
print("克隆保留率:" + str(self.cloneRetainprobability))- l, [- g" o, C; G
print("片段数量:" + str(len(self.fragmentList)))
" `+ [, e; ?6 e, l print("reads长度:" + str(self.minreadslength) + "-" + str(self.maxreadslength)) q/ t- l: z2 y' u7 ]. I- E O
print("reads总数量:" + str(len(self.readsList)))
& |) {; m/ @0 O. m& ?+ C2 | print("reads总长度:" + str(self.allreadslength / 1000) + "kb")
$ G; k5 |, O! o; I m = self.allreadslength / self.genomeLength
% j8 B9 \8 w/ m( c7 M print("覆盖度(m值):" + str(round(m, 5)))
' g/ n( R- o5 D t) L print("理论丢失率(e^-m):" + str(round(exp(-m), 5)))/ k0 _; m& o) @$ U9 z" a- }
print("覆盖率(1-e^-m):" + str(round(1 - exp(-m), 5)))* {3 c2 I2 l8 s5 G, w3 R
# -------------------------------------------主程序-------------------------------------------
" q) k% {: r' J. f t8 V" y# 模拟单端测序
9 O% g$ t; b; h! }sequencingObj = Sequencing()
+ E7 p- c; ]4 ^sequencingObj.singlereadsequencing("data/NC_025452.fasta", "result/virusSingleRead.fa")
8 B- J* l& F7 x; k6 p& b$ F5 ZsequencingObj.resultsummary() m7 A" {1 B) `6 ?& r) h
f3 ]7 N# D; I) R4 h0 k4 `+ M# 模拟双端测序% b. N9 {- P! B
sequencingObj = Sequencing()* I6 @- d) L/ p( b
sequencingObj.pairreadsequencing("data/GCF_000146045.2_R64_genomic.fna", "result/yeastPairRead_1.fa", "result/yeastPairRead_2.fa")6 x/ h2 y" ^9 H
sequencingObj.resultsummary()3 U8 r# Y; r. b, V
from Bio import SeqIO
0 ~* O) N$ K" U( r; }from math import exp
/ q a) [1 b3 ~5 x, o& cimport random6 R8 I4 V. q4 W) Y. a) L
; p- N5 S3 D4 C ~1 z) a# T7 Aclass Sequencing:
( G8 O3 X9 V& j; w* i; [ # N代表拷贝份数- P+ p5 t0 L( M5 J! O
def __init__(self):
! r y, d. O% Z J5 D" z$ x6 d; g$ z$ c self.fragmentList = []
5 J U3 T! z7 k8 ?4 @( @ self.readsID = 1+ {" b# ^6 _5 B! a! Y* u
self.readsList = []
$ ~8 Q- N: ? x9 F: T self.averagefragmentlength = 650/ F' @. C/ l" S6 o
self.minfragmentlength = 500
1 i6 F1 D) Y4 g self.maxfragmentlength = 800
1 C( ]. `0 E3 e8 Q( V' p self.cloneRetainprobability = 15 x( d o1 \: m3 W. @
self.minreadslength = 50
5 V0 \ ^/ c6 z" ?0 c self.maxreadslength = 1502 R6 X* Z7 D9 z$ R% I9 i- j9 m" E
self.N = 10$ ]( h5 k+ E$ c- G
self.genomeLength = 0
+ E. i8 s, @% s$ y( P; r p5 Q self.allreadslength = 0& G4 |+ g5 Y% q4 R& D( J
: e6 p6 M% |+ ]' T. z
# 生成断裂点! Q( [+ ?: U) T0 Q* n+ R# C. \( Y W
def generatebreakpoint(self, seqlen, averageLength):
9 X0 U: A7 w# Z. C' _& H, [ # 假设平均每500bp 产生一个断裂点(averageLength = 500),通过随机函数生成seqlen/500个随机断裂点(1到seqlen之间的随机整数)8 G" n* B) o6 b; F: K9 m, p+ r
breakpoint = [random.randint(0, seqlen) for _ in range(int(seqlen / averageLength))]
( r3 `* _' N* D) _. d& c breakpoint.append(seqlen) W& R! j+ S# T( H! Z' Y) X
breakpoint.append(0)- ^" z6 Z8 I) Q! k8 G) c
# 把随机断裂点从小到大排序. n& Q7 ^7 b2 J
breakpoint.sort()4 m+ i' A9 ?& H! P, M0 p4 I
return breakpoint
0 J0 c, f% m! d, Y; G6 k
/ s0 C; h2 I3 G) ]3 B # 沿断裂点打断基因组,并删除不符合长度要求的序列片段,定义片段范围:200-1000bp+ T/ H0 n7 L4 P: x" ~6 v
def breakgenome(self, seq, breakpoint, minfragmentlength, maxfragmentlength): j: s1 I# d8 N/ e( |. g+ r
for i in range(len(breakpoint) - 1):5 |; ~- W9 G* R
fragment = seq[breakpoint:breakpoint[i + 1]]6 u% B5 c+ ?+ N c! r/ o
if maxfragmentlength > len(fragment) > minfragmentlength:
4 ]( f' c4 H! p" S, e self.fragmentList.append(fragment)
( E2 @6 @8 H8 v0 s3 F A return self.fragmentList) f! E+ F# c, R- }% Q7 h3 K5 y
7 s: \6 G8 n* h* a% k1 r
# 模拟克隆时的随机丢失情况,random.random()生成0-1的保留概率
7 J, v# F% Z, j8 r& `* x/ A [ def clonefragment(self, fragmentList, cloneRetainprobability):% _& X' y% v& d. [/ Q" u$ V
clonedfragmentList = []
; B1 H* i1 I% r6 ]6 p+ R Lossprobability = [random.random() for _ in range(len(fragmentList))]* r$ b/ r F8 I- ]+ H- m9 L
for i in range(len(fragmentList)):. K: V; q; f% T+ n, q* B$ }
if Lossprobability <= cloneRetainprobability:1 |5 H2 K- O% D/ x' m9 u Z
clonedfragmentList.append(fragmentList)8 v s- S4 [; }3 v& E1 O; G
return clonedfragmentList* D3 d- ]! J' s. V
: p" M1 o8 H+ S B5 P
# 模拟单端测序,并修改reads的ID号
) R0 K" Y! t' L% O. h9 ^ def singleread(self, clonedfragmentList):4 o+ q0 _+ p6 ~+ w8 `) J0 q7 v# Q4 b
for fragment in clonedfragmentList:3 C& u5 e; x. W) ] l
fragment.id = ""
6 j: V: \; J, l$ t% i, ]* J fragment.name = ""
' `% ]: f& R$ h" `1 E fragment.description = fragment.description[12:].split(",")[0]8 q+ R7 E0 j0 ^( d- r1 \ j% \
fragment.description = str(self.readsID) + "." + fragment.description
3 z5 k# J h& G9 `5 m9 n3 `2 U8 @ self.readsID += 1
5 t% V0 Z% v! m: B) ] readslength = random.randint(self.minreadslength, self.maxreadslength)
: Q% f# G: N4 C0 Z6 G self.allreadslength += readslength& i J7 U+ L# n9 d# R
self.readsList.append(fragment[:readslength])
5 n6 a: O$ y# q- ^# r# e; }5 [/ R3 f+ C% W9 S
def singlereadsequencing(self, genomedata, sequencingResult):
$ K' P4 q1 @/ L+ n: H for seq_record in SeqIO.parse(genomedata, "fasta"):
4 ]7 k/ `0 Z. K! B( s) n% E seqlen = len(seq_record)
1 y* n8 S, B5 P" i- M. k self.genomeLength += seqlen2 \- b" d) t2 J; G' F- s5 Q
for i in range(self.N):- x6 n, I) @$ w: \7 H
# 生成断裂点4 Z: P: L0 r1 P2 ?0 b
breakpoint = self.generatebreakpoint(seqlen, self.averagefragmentlength)
# v `1 `2 F- K3 _ # 沿断裂点打断基因组5 {! Z: m1 O _9 j, g% ?5 T0 N
self.breakgenome(seq_record, breakpoint, self.minfragmentlength, self.maxfragmentlength)
6 q" q) g: _! h e0 b1 t # 模拟克隆时的随机丢失情况
, t" _: C2 n4 c. M8 @ clonedfragmentList = self.clonefragment(self.fragmentList, self.cloneRetainprobability)
7 ~5 ?0 y# @2 ^' p # 模拟单端测序% {8 ?& E( k1 u; G' ?" C/ c
self.singleread(clonedfragmentList)5 L' y8 |9 l1 k; k% t" ]
SeqIO.write(self.readsList, sequencingResult, "fasta")
" D5 P5 b4 Z) D7 P. R: ^: _8 ~1 {! d: Q3 [ @
def pairread(self, clonedfragmentList):
& Q1 Y* Z$ a j; V: f6 l" S for fragment in clonedfragmentList:, Y) i2 m) l2 Z4 Q- ~, z$ p
fragment.id = ""
- h$ j7 a+ x3 A# P/ R; S" e fragment.name = ""1 W6 C' R: ]; R6 a+ ?1 _
description = fragment.description[12:].split(",")[0]+ ~/ ^) i- U( H5 ^4 i
fragment.description = str(self.readsID) + "." + description1 P7 O+ c1 R. H! q& @: ~/ n
readslength = random.randint(self.minreadslength, self.maxreadslength)
# |6 A- [2 F9 {! d2 l5 ]" H$ w self.allreadslength += readslength
/ {2 g3 L4 }7 r0 T& {& z, E' W! } self.readsList.append(fragment[:readslength])
n( {0 u$ W7 A# x; X8 D2 j7 G+ s1 \: s7 T# o/ N0 j9 w
readslength = random.randint(self.minreadslength, self.maxreadslength)1 V$ W4 R3 C( n$ g. `$ M2 R. E
self.allreadslength += readslength
8 r7 I5 X! U8 {% V* j
% \6 I; ^- v( Q) n fragmentcomplement = fragment.reverse_complement()
9 I+ e9 v5 t! C' i. t+ A3 { fragmentcomplement.id = ""
. _7 n9 h# t9 g1 e fragmentcomplement.name = ""
" I/ A V, Q! r fragmentcomplement.description = str(self.readsID) + "." + description% O, y- z2 E, B3 o2 Z
self.readsList.append(fragmentcomplement[:readslength])7 y; F) U/ t0 E- G$ e* V2 C7 u; ?1 U
3 M2 s1 F8 v2 [7 b9 e0 S+ H8 r& ]' S
self.readsID += 1
& K0 J+ l8 @( t# l, N z
/ o4 E6 `/ [$ F$ ]( F& N def pairreadsequencing(self,genomedata, sequencingResult_1, sequencingResult_2):
9 X& Z, g, z9 L for seq_record in SeqIO.parse(genomedata, "fasta"):
% ^( \; _4 u, J& F: j4 o" x seqlen = len(seq_record); a$ g" h; a/ \
self.genomeLength += seqlen
# l$ i( \) t6 |/ i) q S S for i in range(self.N):
/ A' b1 c, T, u( f% O # 生成断裂点4 U P9 ^* H' k# `
breakpoint = self.generatebreakpoint(seqlen, self.averagefragmentlength): `% e" I \7 l" U6 }5 ?. W
# 沿断裂点打断基因组: l1 I9 f/ ~5 E: \) h' Z
self.breakgenome(seq_record, breakpoint, self.minfragmentlength, self.maxfragmentlength)# t( L& k) x$ f9 [5 A! t
# 模拟克隆时的随机丢失情况
8 w1 b3 {4 t3 S- B+ v clonedfragmentList = self.clonefragment(self.fragmentList, self.cloneRetainprobability)3 \0 I! h6 H% g+ o* S& u
# 模拟双端测序% [5 J! q2 |7 ] N4 e2 P' R% R0 g
self.pairread(clonedfragmentList)8 N) O9 C* q4 C& h' }- x6 T
readsList_1 = [self.readsList for i in range(len(self.readsList)) if i % 2 == 0]
5 E/ C, s1 D, S8 X readsList_2 = [self.readsList for i in range(len(self.readsList)) if i % 2 == 1]0 a- w1 Y( e( t: z2 S
SeqIO.write(readsList_1, sequencingResult_1, "fasta")# {" |% n3 B5 P0 U; |7 d: s5 R/ o
SeqIO.write(readsList_2, sequencingResult_2, "fasta")
, M9 q( o5 L& g v( l, Y
" o, X0 y f7 m& l& h* @4 B6 j; Y def resultsummary(self):7 r$ k+ c! L+ y& u
print("基因组长度:" + str(self.genomeLength / 1000) + "kb")" K+ s% j9 S) U, O# s0 B
print("片段长度区间:" + str(self.minfragmentlength) + "-" + str(self.maxfragmentlength))
2 d' L5 B. w. E; M+ m W print("N值:" + str(self.N))" s: l/ v2 _5 C" Z+ q$ H) w
print("期望片段长度:" + str(self.averagefragmentlength))& Y+ b P' y" k5 V
print("克隆保留率:" + str(self.cloneRetainprobability))- U: l; x- f) s4 K) a' \
print("片段数量:" + str(len(self.fragmentList)))
u. m Z+ T) _9 d/ ~2 x( H print("reads长度:" + str(self.minreadslength) + "-" + str(self.maxreadslength))) Y$ W9 c- m% n8 U4 Z2 |
print("reads总数量:" + str(len(self.readsList)))4 a, X, p8 Y% N8 \6 H* K1 w
print("reads总长度:" + str(self.allreadslength / 1000) + "kb")
]' F, k. x) i y+ t' _ m = self.allreadslength / self.genomeLength P+ w x) n* x- |9 b* F! ]. w
print("覆盖度(m值):" + str(round(m, 5)))
7 O/ q! O# e4 d; H# ?3 B$ E print("理论丢失率(e^-m):" + str(round(exp(-m), 5)))
, I- v" _7 g$ E% C print("覆盖率(1-e^-m):" + str(round(1 - exp(-m), 5)))
% i# P& G3 ^( T' c# -------------------------------------------主程序------------------------------------------- X" \: s8 p) {2 T4 C O- h
# 模拟单端测序
1 h" V K% B' \, o! S% _sequencingObj = Sequencing()
# V2 r3 P5 H" csequencingObj.singlereadsequencing("data/NC_025452.fasta", "result/virusSingleRead.fa")
0 `6 o0 R1 Q& L( H. \! |sequencingObj.resultsummary()
8 ?8 G: l3 s6 _1 t8 E: Y
; Y$ m# W& S+ y8 d j# 模拟双端测序, o% U$ z- D7 I7 m9 A! F
sequencingObj = Sequencing()
( `' w$ {) f, l0 I% xsequencingObj.pairreadsequencing("data/GCF_000146045.2_R64_genomic.fna", "result/yeastPairRead_1.fa", "result/yeastPairRead_2.fa")
1 j: O3 [8 O$ S. |( s6 o+ v; ssequencingObj.resultsummary()" p( }4 `$ B8 ^7 w
2 s* I' }+ r4 T2 ^$ }0 u$ `* c% e" f. t6 r
; U+ g, m& N& O# t2 g3 W9 I
9 I5 n! H m, Q5 }$ j2 O" i |
zan
|