2012-07-27 5 views
3

pdb 파일에서 체인을 추출하고 싶습니다. 나는 아래와 같은 pdb ID를 포함하는 pdb.txt라는 파일을 가지고있다. 처음 네 문자는 PDB ID를 나타내며 마지막 문자는 체인 ID입니다.PDB 파일에서 체인을 추출하는 방법은 무엇입니까?

1B68A 
1BZ4B 
4FUTA 

I)는 라인 (2)에 의한 파일 선 판독 대응 PDB 파일에서 각 체인의 원자 좌표를 다운로드) 1 싶다.
3) 출력을 폴더에 저장합니다.

다음 스크립트를 사용하여 체인을 추출했습니다. 그러나이 코드는 pdb 파일에서 A 체인 만 인쇄합니다.

for i in 1B68 1BZ4 4FUT 
do 
wget -c "http://www.pdb.org/pdb/download/downloadFile.do?fileFormat=pdb&compression=NO&structureId="$i -O $i.pdb 
grep ATOM $i.pdb | grep 'A' > $i\_A.pdb 
done 

답변

10

다음 BioPython 코드는 사용자의 요구에 적합해야합니다.

PDB.Select을 사용하여 원하는 체인 (사용자의 경우 하나의 체인)과 PDBIO() 만 선택하여 체인 만 포함하는 구조를 만듭니다.

import os 
from Bio import PDB 


class ChainSplitter: 
    def __init__(self, out_dir=None): 
     """ Create parsing and writing objects, specify output directory. """ 
     self.parser = PDB.PDBParser() 
     self.writer = PDB.PDBIO() 
     if out_dir is None: 
      out_dir = os.path.join(os.getcwd(), "chain_PDBs") 
     self.out_dir = out_dir 

    def make_pdb(self, pdb_path, chain_letters, overwrite=False, struct=None): 
     """ Create a new PDB file containing only the specified chains. 

     Returns the path to the created file. 

     :param pdb_path: full path to the crystal structure 
     :param chain_letters: iterable of chain characters (case insensitive) 
     :param overwrite: write over the output file if it exists 
     """ 
     chain_letters = [chain.upper() for chain in chain_letters] 

     # Input/output files 
     (pdb_dir, pdb_fn) = os.path.split(pdb_path) 
     pdb_id = pdb_fn[3:7] 
     out_name = "pdb%s_%s.ent" % (pdb_id, "".join(chain_letters)) 
     out_path = os.path.join(self.out_dir, out_name) 
     print "OUT PATH:",out_path 
     plural = "s" if (len(chain_letters) > 1) else "" # for printing 

     # Skip PDB generation if the file already exists 
     if (not overwrite) and (os.path.isfile(out_path)): 
      print("Chain%s %s of '%s' already extracted to '%s'." % 
        (plural, ", ".join(chain_letters), pdb_id, out_name)) 
      return out_path 

     print("Extracting chain%s %s from %s..." % (plural, 
       ", ".join(chain_letters), pdb_fn)) 

     # Get structure, write new file with only given chains 
     if struct is None: 
      struct = self.parser.get_structure(pdb_id, pdb_path) 
     self.writer.set_structure(struct) 
     self.writer.save(out_path, select=SelectChains(chain_letters)) 

     return out_path 


class SelectChains(PDB.Select): 
    """ Only accept the specified chains when saving. """ 
    def __init__(self, chain_letters): 
     self.chain_letters = chain_letters 

    def accept_chain(self, chain): 
     return (chain.get_id() in self.chain_letters) 


if __name__ == "__main__": 
    """ Parses PDB id's desired chains, and creates new PDB structures. """ 
    import sys 
    if not len(sys.argv) == 2: 
     print "Usage: $ python %s 'pdb.txt'" % __file__ 
     sys.exit() 

    pdb_textfn = sys.argv[1] 

    pdbList = PDB.PDBList() 
    splitter = ChainSplitter("/home/steve/chain_pdbs") # Change me. 

    with open(pdb_textfn) as pdb_textfile: 
     for line in pdb_textfile: 
      pdb_id = line[:4].lower() 
      chain = line[4] 
      pdb_fn = pdbList.retrieve_pdb_file(pdb_id) 
      splitter.make_pdb(pdb_fn, chain) 

마지막으로 참고 : 는 PDB 파일에 자체 파서을 쓰지 않는다. 형식 사양은 못생긴 (정말 못생긴)이며, 결함이있는 PDB 파일의 양은 엄청납니다. 당신을 위해 파싱을 처리 할 BioPython과 같은 도구를 사용하십시오!

wget을 사용하는 대신 PDB 데이터베이스와 상호 작용하는 도구를 사용해야합니다. FTP 연결 제한 사항, PDB 데이터베이스의 변화하는 특성 등을 고려합니다. 데이터베이스의 변경 사항을 처리하려면 updated Bio.PDBList을 알아야합니다. =)

+0

코드 및 설명 주셔서 감사합니다. 하지만 코드를 실행하는 방법을 모르겠습니다. 당신이 나를 도울 수? – user1545114

+0

예. 나는 당신의 목표에 특별히 맞는 방법을 추가했습니다. 파일을 이동할 디렉터리로 본체의 줄을 변경하십시오. [Python 설치] (http://www.python.org/getit/) (아마도 이미 $ python으로 실행 해보십시오), [BioPython] (http://biopython.org/wiki/Download #Installation_Instructions). 위의 파일을'.py' 확장자 (예 :'extract.py')로 저장 한 다음'$ python extract.py pdb.txt'를 실행하십시오. 그게 다야! –

+0

더 많은 생물 정보학 관련 작업을 수행하고 있다면 파이썬을 배우는 것이 좋습니다.그것은 현장에서 매우 유명합니다 ([BioPython] (http://biopython.org)와 [PyMOL] (http://pymol.org), 두 가지 좋은 예입니다), 그리고 그것은 좋은 일반 언어입니다. [Python docs] (http://docs.python.org)와 [Think Python] (http://www.greenteapress.com/thinkpython/) 모두 좋은 출발점입니다. –

0

그런 다음 load_pdb.sh

while read name 
do 
    chain=${name:4:1} 
    name=${name:0:4} 
    wget -c "http://www.pdb.org/pdb/download/downloadFile.do?fileFormat=pdb&compression=NO&structureId="$name -O $name.pdb 
    awk -v chain=$chain '$0~/^ATOM/ && substr($0,20,1)==chain {print}' $name.pdb > $name\_$chain.pdb 
    # rm $name.pdb 
done 

주석의 마지막 줄 필요하지 않은 경우 원래 PDB 년대에 코드를 가지고 다음과 같은 파일 pdb_structures

1B68A 
1BZ4B 
4FUTA 

이 있다고 할 수 있습니다.
그것은 아마이 질문을 asnwering 늦었 조금

cat pdb_structures | ./load_pdb.sh 
+0

이것은 간단하고 효과적이지만 체인의 일부인 [HETATM] (http://deposit.rcsb.org/adit/docs/pdb_atom_format.html#HETATM) 레코드는 무시합니다. 이미 기존의 파서가 많을 때 복잡한 파일 형식에 대한 자체 파서를 작성해야하는 이유는 무엇입니까? –

+0

또한 PDB 검색 프로그램을 사용하는 것은 손으로 검색 한 URL로 wget을 사용하는 것보다 훨씬 더 나은 옵션입니다. 압축은 다른 기능들 중에서도 자동으로 처리됩니다. 내 대답의 마지막 단락을보십시오. –

+0

@ zelleke, 답변 해 주셔서 대단히 감사합니다. 코드를 작성했습니다. pdb 파일에서 모든 체인이 필요하지 않습니다. 텍스트 파일에 체인 ID를 언급했습니다. 예를 들어 '1B68'의 'A'체인 만 있으면됩니다. – user1545114

0

실행,하지만 난 내 의견을 줄 것이다. Biopython에는 쉽게 생각할 수있는 몇 가지 유용한 기능이 있습니다. 사용자 정의 선택 클래스와 같은 것을 사용할 수 있으며 원래 pdb 파일을 사용하여 for 루프 내에서 선택하려는 각 체인에 대해 호출 할 수 있습니다.

from Bio.PDB import Select, PDBIO 
    from Bio.PDB.PDBParser import PDBParser 

    class ChainSelect(Select): 
     def __init__(self, chain): 
      self.chain = chain 

     def accept_chain(self, chain): 
      if chain.get_id() == self.chain: 
       return 1 
      else:   
       return 0 

    chains = ['A','B','C'] 
    p = PDBParser(PERMISSIVE=1)  
    structure = p.get_structure(pdb_file, pdb_file) 

    for chain in chains: 
     pdb_chain_file = 'pdb_file_chain_{}.pdb'.format(chain)         
     io_w_no_h = PDBIO()    
     io_w_no_h.set_structure(structure) 
     io_w_no_h.save('{}'.format(pdb_chain_file), ChainSelect(chain)) 
관련 문제