我目前在文件中有一个基因列表。每条线都有一条染色体及其信息。这样的条目显示为:
NM_198212 chr7 + 115926679 115935830 115927071 11593344 2 115926679 ,'115933260', 115927221 ,'115935830' ,
染色体的序列从 115926679 开始,并持续到(但不包括)碱 115935830
如果我们想要拼接序列,我们使用外显子。第一个延伸自 115926679 到 155927221 ,第二个从'115933260'到'115935830'
但是,在使用互补序列时遇到问题,例如:
NM_001005286 chr1 - 245941755 245942680 245941755 245942680 1 245941755 ,'245942680'
由于第3列是' - ',这些坐标是指反义链(链的互补链)。第一个碱基(粗体)匹配有义链上的最后一个碱基(斜体)。由于文件只有感测架,我需要尝试将反义链上的坐标转换为有义链,选择正确的序列然后反向补充它。
那就是说,我只编程了大约半年,并且不确定如何开始这样做。
我写了一个正则表达式:
'(NM_\d+)\s+(chr\d+)([(\+)|(-)])\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+),(\d+),s+(\d+),(\d+),'
但我现在不确定如何启动此功能...... 如果有人能帮助我开始这一点,或许让我看到如何做到这一点,我会非常感激。
好的:假设这是25号染色体:
AAAAAAAAAACCCCCCCCCCTTTTTTTTTTGGGGGGGGGG
(每个角色有10个)。
现在:如果我正在寻找一个未拼写的基因:chr25 + 10 20
然后基因从第10位开始(从0开始),然后上升到但不包括位置20.所以它:
CCCCCCCCCC
这很容易。它很好地匹配python字符串切片。
如果我给你的话会更加困惑:
chr25 - 10 20
你拥有的是正向链。但这个基因位于负(互补)链上。记住染色体看起来像一条双链:
AAAAAAAAAACCCCCCCCCCTTTTTTTTTTGGGGGGGGGG
TTTTTTTTTTGGGGGGGGGGAAAAAAAAAACCCCCCCCCC
我们正在寻找底链上的基因。意思是我们从右边开始从0开始计算。从左边开始编号,从右边开始编号。所以我想要的是AAAAAAAAAA。
抓住的是我只给你顶线。我没有给你底线。 (你可以从顶层产生自己 - 但考虑到它有多大,我建议反对。)
所以你需要转换坐标。在底链上,碱基0(最右边的C)与顶部链上的碱基39相对。基数1与基数38相对。基数2与情况37相反。(重点:注意每次添加这两个数字时会发生什么情况。)因此,基数10与基数29相对,基数19与基数20相对。 / p>
所以:如果我想在底线上找到10-20的基数,我可以看一下顶部的20-29(然后反向补充它)。
我需要弄清楚如何将底线上的坐标转换为底线上的等效坐标。是的:这非常令人困惑
我试过weronika's original answer:
fields = line.split(' \t')
geneID, chr, strand = fields[:2]
start = int(fields[3])
end = int(fields[4])
if strand == '-':
start,end = -(start + 1), -(end + 1) # this part was changed from original answer.
这是正确的轨道,但这还不够。这将取10和20,并将其变为20和10。
我知道我可以通过这样做来反转字符串补充:
r = s[::-1]
bc = {'A': 'T', 'C': 'G', 'G': 'C', 'T': 'A'}
l = list(r)
o = [bc[base] for base in l]
return ''.join(o)
编辑!这看起来是否正确?!
fp2 = open('chr22.fa', 'r')
fp = open('chr22.fa', 'r')
for line in fp2:
newstring = ''
z = line.strip()
newstring += z
for line in fp:
fields = line.split('\t')
gene_ID, chr, strand = fields[:2]
start = int(fields[3])
end = int(fields[4])
bc = {'A': 'T', 'C': 'G', 'G': 'C', 'T': 'A', 'a': 't', 't': 'a', 'c':'g', 'g':'c', 'N':'N', 'n':'n'}
l = list(newstring)
if strand == '+':
geneseq = ''.join([bc[base] for base in l[start:end]])
if strand == '-':
newstart, newend = -(start + 1), -(end + 1)
genseq = ''.join([bc[base] for base in l[newstart:newend]])
答案 0 :(得分:0)
我没有理解域名问题,但看起来你正试图过多地填充一个正则表达式。尝试将其分解为更简单的子问题,如下所示(在伪代码中):
if third column is a '+'
parseRegularSequence()
else
parseComplementarySequence()
答案 1 :(得分:0)
正如我对这个问题的评论所指出的,这似乎是一种非常奇怪的文件格式,因此我最初的困惑。
注意:如果这是标准的生物学文件格式之一,那么最好使用Biopython或类似的解析它。
如果你想进行自己的解析,正则表达式似乎仍然是错误的方法 - 使用简单的空格/制表符分隔文件难以阅读和不必要。
我假设您已经解析了您的染色体fasta文件并将所有染色体的序列作为chrom_sequences
名称:seq字典,并且您还具有reverse_complement
函数(这些都很容易手动实现,但可能更好地完成biopython)。
fields = line.split(' ') # or '\t' instead of ' ' if the file is tab-separated
gene_ID, chr, strand = fields[:2]
start, end = [int(x) for x in fields[3:5])
this_chromosome_seq = chrom_sequences[chr]
# if strand is +, just take the sequence based on the start-end position
if strand == '+':
# be careful about off-by-one errors here - some formats give you a 1-based position,
# other formats make it 0-based, and they can also be end-inclusive or end-exclusive
gene_sequence = this_chromosome_seq[start:end]
# if your coordinates really are given as antisense strand coordinates when strand is -,
# you just need to subtract them from the chromosome length to get sense-strand coordinates,
# (switching start and end so they're still in smaller-to-larger order),
# and then reverse-complement the resulting sequence.
if strand == '-':
chrom_length = len(this_chromosome_seq)
# again, be careful about off-by-one errors here!
new_start,new_end = chrom_length-end, chrom_length-start
gene_sequence = reverse_complement(this_chromosome_seq[new_start:new_end])
原始回答,实际上并未按要求进行操作:
如果您只想获得开始/结束位置,请执行以下操作:
fields = line.split(' ') # or '\t' instead of ' ' if the file is tab-separated
gene_ID, chr, strand = fields[:2]
start = int(fields[3])
end = int(fields[4])
if strand == '-':
start,end = end,start
然后你必须解析你的fasta文件以实际获取这些起始端坐标的序列,并在strand=='-'
时反向补充它。同样,我认为Biopython可以为您完成大部分工作。
另一个注意事项 - Biostar是一个专门针对生物信息学的优秀StackExchange类型网站,您可能会在那里获得更好的答案。
答案 2 :(得分:0)
如果您使用否定编号对字符串进行切片,则Python会从末尾向后计数。
complement = {'A': 'T', 'C': 'G', 'G': 'C', 'T': 'A'}
s = "AAAAAAAAAACCCCCCCCCCTTTTTTTTTTGGGGGGGGGG"
"".join(complement[c] for c in s[-20:-10])
编辑:
你的编辑看起来对我来说是对的,是的。我非常擅长检查fencepost errors,但你最好还是去看看那些比我还要好的事情!
我已经将你的代码重写为Pythonic,但没有改变任何重大内容。
bc = {'A': 'T', 'C': 'G', 'G': 'C', 'T': 'A', 'N':'N'}
f = open('chr22.fa')
l = ''.join(line.strip() for line in f)
f.seek(0)
for line in f:
fields = line.split('\t')
gene_ID, chr, strand = fields[:2]
start = int(fields[3])
end = int(fields[4])
if strand == '-':
start, end = -(start + 1), -(end + 1)
geneseq = ''.join(bc[base.upper()] for base in l[start:end])
答案 3 :(得分:0)
我想(特别是因为你的文件很大),直接从文件缓冲区读取和写入会更容易。
假设您已经解析了头文件。您解析的行如下所示:
line = "NM_001005286 chr1 - 245941755 245942680 245941755 245942680 1"
然后确定起始/终止位置是什么(在反义坐标中):
name, chromosome, direction, start, end = line[:5]
然后,执行以下操作:
#Open up the file `chr1.txt`.
f = open("chr1.txt", "r")
#Determine the read length.
read_len = end - start
#Seek to the appropriate position (notice the second argument, 2 -- this means
#seek from the end of the file)
f.seek(-end, 2)
#Read the data
sense_seq = f.read(read_len)
之后,这只是将序列转换为反义的问题。
简单:)