Skip to content

Commit

Permalink
[FEATURE] Merge pull request #107
Browse files Browse the repository at this point in the history
Facilitates use of pdb-tools as a Python library
  • Loading branch information
joaomcteixeira authored Jul 20, 2021
2 parents 4cbefcc + 42c627d commit 321c88c
Show file tree
Hide file tree
Showing 47 changed files with 1,091 additions and 221 deletions.
116 changes: 107 additions & 9 deletions pdbtools/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,110 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
#
#
# Nothing to see here
# Just a placeholder to allow setuptools:entry_points to work.
#
#
#
"""The pdb-tools library.
A Swiss army knife for manipulating and editing PDB files.
You can use pdb-tools as a library or as a series of convenient
command-line applications. The complete documentation is available at:
http://www.bonvinlab.org/pdb-tools/
Examples at the command-line
----------------------------
$ pdb_fetch 1brs > 1brs.pdb
$ pdb_reres -1 1ctf.pdb > 1ctf_renumbered.pdb
$ pdb_selchain -A,D 1brs.pdb | pdb_delhetatm | pdb_tidy > 1brs_AD_noHET.pdb
Examples using pdb-tools as library
-----------------------------------
You can import according to your needs:
>>> import pdbtools
>>> from pdbtools import *
>>> from pdbtools import MODULE
>>> from pdbtools import pdb_selchain
Chain the different functionalities conveniently:
>>> from pdbtools import pdb_selchain, pdb_selatom, pdb_keepcoord
>>> with open('dummy.pdb') as fh:
>>> chain_a = pdb_selchain.run(fh, ['A'])
>>> only_N = pdb_selatom.run(chain_a, ['N'])
>>> coords = pdb_keepcoord.run(only_N)
>>> final = pdb_reres.run(coords, 5)
>>> print(''.join(final))
The list of MODULEs is specified bellow.
All packages have three functions: `check_input`, `main`, and `run`.
The latter executes the logic of each package. `check_input` checks and
prepares potential input parameters to feed `run`. Use `check_input` in
case you are not sure the received input is correct. You can chain both
functions:
>>> MODULE.run(**MODULE.check_input(*args))
If you control the input parameters use `run` directly. In general,
`run` functions are generators yielding the modified PDB data
line-by-line. `main` is used solely in the context of the command-line
interface.
All MODULEs and `run` functions provide comprehensive documentation.
>>> help(MODULE)
>>> help(MODULE.run)
"""

__all__ = [
'pdb_b',
'pdb_chainbows',
'pdb_chain',
'pdb_chainxseg',
'pdb_chkensemble',
'pdb_delchain',
'pdb_delelem',
'pdb_delhetatm',
'pdb_delinsertion',
'pdb_delresname',
'pdb_delres',
'pdb_element',
'pdb_fetch',
'pdb_fixinsert',
'pdb_fromcif',
'pdb_gap',
'pdb_head',
'pdb_intersect',
'pdb_keepcoord',
'pdb_merge',
'pdb_mkensemble',
'pdb_occ',
'pdb_reatom',
'pdb_reres',
'pdb_rplchain',
'pdb_rplresname',
'pdb_seg',
'pdb_segxchain',
'pdb_selaltloc',
'pdb_selatom',
'pdb_selchain',
'pdb_selelem',
'pdb_selhetatm',
'pdb_selresname',
'pdb_selres',
'pdb_selseg',
'pdb_shiftres',
'pdb_sort',
'pdb_splitchain',
'pdb_splitmodel',
'pdb_splitseg',
'pdb_tidy',
'pdb_tocif',
'pdb_tofasta',
'pdb_uniqname',
'pdb_validate',
'pdb_wc',
]
29 changes: 23 additions & 6 deletions pdbtools/pdb_b.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,22 +100,36 @@ def check_input(args):
sys.stderr.write(emsg.format(option))
sys.exit(1)

return (option, fh)
return (fh, option)


def pad_line(line):
"""Helper function to pad line to 80 characters in case it is shorter"""
"""Pad line to 80 characters in case it is shorter."""
size_of_line = len(line)
if size_of_line < 80:
padding = 80 - size_of_line + 1
line = line.strip('\n') + ' ' * padding + '\n'
return line[:81] # 80 + newline character


def alter_bfactor(fhandle, bfactor):
"""Sets the temperature column in all ATOM/HETATM records to a given value.
def run(fhandle, bfactor):
"""
Set the temperature column in all ATOM/HETATM records to a given value.
This function is a generator.
Parameters
----------
fhandle : a line-by-line iterator of the original PDB file.
bfactor : float
The desired bfactor.
Yields
------
str (line-by-line)
The modified (or not) PDB line.
"""
_pad_line = pad_line
records = ('ATOM', 'HETATM')
bfactor = "{0:>6.2f}".format(bfactor)
Expand All @@ -127,13 +141,16 @@ def alter_bfactor(fhandle, bfactor):
yield line


alter_bfactor = run


def main():

# Check Input
bfactor, pdbfh = check_input(sys.argv[1:])
pdbfh, bfactor = check_input(sys.argv[1:])

# Do the job
new_pdb = alter_bfactor(pdbfh, bfactor)
new_pdb = run(pdbfh, bfactor)

# Output results
try:
Expand Down
28 changes: 23 additions & 5 deletions pdbtools/pdb_chain.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ def check_input(args):
sys.stderr.write(emsg.format(option))
sys.exit(1)

return (option, fh)
return (fh, option)


def pad_line(line):
Expand All @@ -110,8 +110,23 @@ def pad_line(line):
return line[:81] # 80 + newline character


def alter_chain(fhandle, chain_id):
"""Sets the chain identifier column in all ATOM/HETATM records to a value.
def run(fhandle, chain_id):
"""
Set the chain identifier column in all ATOM/HETATM records to a value.
This function is a generator.
Parameters
----------
fhandle : a line-by-line iterator of the original PDB file.
chain_id : str
The new chain ID.
Yields
------
str (line-by-line)
The modified (or not) PDB line.
"""

_pad_line = pad_line
Expand All @@ -124,12 +139,15 @@ def alter_chain(fhandle, chain_id):
yield line


alter_chain = run


def main():
# Check Input
chain, pdbfh = check_input(sys.argv[1:])
pdbfh, chain = check_input(sys.argv[1:])

# Do the job
new_pdb = alter_chain(pdbfh, chain)
new_pdb = run(pdbfh, chain)

try:
_buffer = []
Expand Down
23 changes: 20 additions & 3 deletions pdbtools/pdb_chainbows.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,23 @@ def check_input(args):
return fh


def set_chain_sequence(fhandle):
"""Sets chains sequentially based on existing TER records."""
def run(fhandle):
"""
Set chains sequentially based on existing TER records.
Follow sequence [ABC...abc...012...].
This function is a generator.
Parameters
----------
fhandle : an iterable giving the PDB file line-by-line
Yields
------
str (line-by-line)
The modified (or not) PDB line.
"""
chainlist = list(
string.digits[::-1] + string.ascii_lowercase[::-1] + string.ascii_uppercase[::-1]
) # 987...zyx...cbaZYX...BCA.
Expand Down Expand Up @@ -108,12 +122,15 @@ def set_chain_sequence(fhandle):
yield line


set_chain_sequence = run


def main():
# Check Input
pdbfh = check_input(sys.argv[1:])

# Do the job
new_pdb = set_chain_sequence(pdbfh)
new_pdb = run(pdbfh)

try:
_buffer = []
Expand Down
23 changes: 20 additions & 3 deletions pdbtools/pdb_chainxseg.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,22 @@ def pad_line(line):
return line[:81] # 80 + newline character


def place_chain_on_seg(fhandle):
"""Replaces the segment identifier with the contents of the chain identifier.
def run(fhandle):
"""
Replace the segment identifier with the contents of the chain identifier.
Acts on ATOM/HETATM/ANISOU.
This function is a generator.
Parameters
----------
fhandle : a line-by-line iterator of the original PDB file.
Yields
------
str (line-by-line)
The modified (or not) PDB line.
"""

_pad_line = pad_line
Expand All @@ -94,12 +108,15 @@ def place_chain_on_seg(fhandle):
yield line


place_chain_on_seg = run


def main():
# Check Input
pdbfh = check_input(sys.argv[1:])

# Do the job
new_pdb = place_chain_on_seg(pdbfh)
new_pdb = run(pdbfh)

try:
_buffer = []
Expand Down
18 changes: 15 additions & 3 deletions pdbtools/pdb_chkensemble.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,22 @@ def check_input(args):
return fh


def check_ensemble(fhandle):
"""Checks if the ensemble is valid.
def run(fhandle):
"""
Check if the ensemble is valid.
- Same atoms in each model
- Paired MODEL/ENDMDL tags
"""
Parameters
----------
fhandle : a line-by-line iterator of the original PDB file.
Returns
-------
int
1 if an error was found. 0 if no errors are found.
"""
model_open = False
model_no = None
model_data = {} # list of sets
Expand Down Expand Up @@ -153,6 +162,9 @@ def check_ensemble(fhandle):
return 1


check_ensemble = run


def main():
# Check Input
pdbfh = check_input(sys.argv[1:])
Expand Down
Loading

0 comments on commit 321c88c

Please sign in to comment.