From a3d7f4a51a640f25f223f3ebecaa1ce7ed4bda87 Mon Sep 17 00:00:00 2001 From: Lukas Pravda Date: Sat, 11 Jul 2020 17:22:39 +0200 Subject: [PATCH 1/8] use default bfactor if missing from ModelServer --- arpeggio/core/protein_reader.py | 226 +++++++++++++++++++------------- 1 file changed, 135 insertions(+), 91 deletions(-) diff --git a/arpeggio/core/protein_reader.py b/arpeggio/core/protein_reader.py index 9dc78e9..54f01dd 100644 --- a/arpeggio/core/protein_reader.py +++ b/arpeggio/core/protein_reader.py @@ -16,21 +16,33 @@ def _get_res_id(atom_sites, i): - return int(atom_sites['pdbe_label_seq_id'][i] - if 'pdbe_label_seq_id' in atom_sites - else atom_sites['auth_seq_id'][i]) + return int( + atom_sites["pdbe_label_seq_id"][i] + if "pdbe_label_seq_id" in atom_sites + else atom_sites["auth_seq_id"][i] + ) + + +def _get_b_factor(atom_sites, i): + return float( + atom_sites["B_iso_or_equiv"][i] if "B_iso_or_equiv" in atom_sites else 20.0 + ) def _get_ins_code(atom_sites, i): - return ' ' if atom_sites['pdbx_PDB_ins_code'][i] in ('.', '?') else atom_sites['pdbx_PDB_ins_code'][i] + return ( + " " + if atom_sites["pdbx_PDB_ins_code"][i] in (".", "?") + else atom_sites["pdbx_PDB_ins_code"][i] + ) def _format_formal_charge(atom_sites, i): - if 'pdbx_formal_charge' not in atom_sites: + if "pdbx_formal_charge" not in atom_sites: return 0 - charge = atom_sites['pdbx_formal_charge'][i] - return 0 if charge in ('?', '.') else int(charge) + charge = atom_sites["pdbx_formal_charge"][i] + return 0 if charge in ("?", ".") else int(charge) def _trim_models(atom_site): @@ -44,13 +56,15 @@ def _trim_models(atom_site): dict: first model from the _atom_site """ output = {} - pivot = atom_site['pdbx_PDB_model_num'][0] - length = sum(x == pivot for x in atom_site['pdbx_PDB_model_num']) + pivot = atom_site["pdbx_PDB_model_num"][0] + length = sum(x == pivot for x in atom_site["pdbx_PDB_model_num"]) for k, v in atom_site.items(): output[k] = v[:length] return output + + # endregion common @@ -68,7 +82,7 @@ def read_mmcif_to_openbabel(path): openbabel.OBMol: openbabel structure """ if not os.path.isfile(path): - raise IOError('File {} not found'.format(path)) + raise IOError("File {} not found".format(path)) parsed = MMCIF2Dict().parse(path) mol = _parse_atom_site_openbabel(list(parsed.values())[0]) @@ -85,7 +99,7 @@ def _parse_atom_site_openbabel(parsed): Returns: [OBMol]: openbabel representation of the protein structure. """ - perceived_atom_site = parsed['_atom_site'] + perceived_atom_site = parsed["_atom_site"] atom_site = _trim_models(perceived_atom_site) table = ob.OBElementTable() @@ -99,25 +113,27 @@ def _parse_atom_site_openbabel(parsed): mol.SetChainsPerceived() mol.BeginModify() - for i in range(len(atom_site['id'])): + for i in range(len(atom_site["id"])): current_res_id = _get_res_id(atom_site, i) ins_code = _get_ins_code(atom_site, i) - if last_chain_id != atom_site['auth_asym_id'][i]: + if last_chain_id != atom_site["auth_asym_id"][i]: chain_num += 1 - last_chain_id = atom_site['auth_asym_id'][i] + last_chain_id = atom_site["auth_asym_id"][i] - if current_res_id != last_res_id or \ - atom_site['auth_asym_id'][i] != last_chain_id or \ - atom_site['label_comp_id'][i] != last_res_name: + if ( + current_res_id != last_res_id + or atom_site["auth_asym_id"][i] != last_chain_id + or atom_site["label_comp_id"][i] != last_res_name + ): last_res_id = current_res_id - last_res_name = atom_site['label_comp_id'][i] + last_res_name = atom_site["label_comp_id"][i] res = mol.NewResidue() res.SetChainNum(chain_num) res.SetNum(str(last_res_id)) - res.SetName(atom_site['label_comp_id'][i]) + res.SetName(atom_site["label_comp_id"][i]) res.SetInsertionCode(ins_code) _init_openbabel_atom(table, mol, res, atom_site, i) @@ -127,7 +143,7 @@ def _parse_atom_site_openbabel(parsed): mol.ConnectTheDots() mol.PerceiveBondOrders() - if '_struct_conn' in parsed: + if "_struct_conn" in parsed: parse_struct_conn_bonds(mol, parsed) mol.EndModify() @@ -142,13 +158,15 @@ def parse_struct_conn_bonds(mol, mmcif_dict): mol (ob.OBMol): OpenBabel molecule object mmcif_dict (dict of str): Parsed mmcif file category. """ - pivot = list(mmcif_dict['_struct_conn'].keys())[0] + pivot = list(mmcif_dict["_struct_conn"].keys())[0] - mmcif_dict['_struct_conn'] = (mmcif_dict['_struct_conn'] - if isinstance(mmcif_dict['_struct_conn'][pivot], list) - else {k: [v] for k, v in mmcif_dict['_struct_conn'].items()}) + mmcif_dict["_struct_conn"] = ( + mmcif_dict["_struct_conn"] + if isinstance(mmcif_dict["_struct_conn"][pivot], list) + else {k: [v] for k, v in mmcif_dict["_struct_conn"].items()} + ) - for i in range(len(mmcif_dict['_struct_conn'][pivot])): + for i in range(len(mmcif_dict["_struct_conn"][pivot])): __process_struct_conn(mol, mmcif_dict, i) @@ -165,25 +183,31 @@ def __process_struct_conn(mol, mmcif_dict, index): """ def find_atom_id(atom_site, residue): - for i in range(0, len(atom_site['id'])): - if atom_site['auth_seq_id'][i] == residue[1] and \ - atom_site['auth_asym_id'][i] == residue[0] and \ - atom_site['label_atom_id'][i] == residue[2]: + for i in range(0, len(atom_site["id"])): + if ( + atom_site["auth_seq_id"][i] == residue[1] + and atom_site["auth_asym_id"][i] == residue[0] + and atom_site["label_atom_id"][i] == residue[2] + ): - return int(atom_site['id'][i]) + return int(atom_site["id"][i]) return 0 - struct_conn = mmcif_dict['_struct_conn'] - atom_sites = mmcif_dict['_atom_site'] + struct_conn = mmcif_dict["_struct_conn"] + atom_sites = mmcif_dict["_atom_site"] - res_a = (struct_conn['ptnr1_auth_asym_id'][index], - struct_conn['ptnr1_auth_seq_id'][index], - struct_conn['ptnr1_label_atom_id'][index]) + res_a = ( + struct_conn["ptnr1_auth_asym_id"][index], + struct_conn["ptnr1_auth_seq_id"][index], + struct_conn["ptnr1_label_atom_id"][index], + ) - res_b = (struct_conn['ptnr2_auth_asym_id'][index], - struct_conn['ptnr2_auth_seq_id'][index], - struct_conn['ptnr2_label_atom_id'][index]) + res_b = ( + struct_conn["ptnr2_auth_asym_id"][index], + struct_conn["ptnr2_auth_seq_id"][index], + struct_conn["ptnr2_label_atom_id"][index], + ) atom_id_a = find_atom_id(atom_sites, res_a) atom_id_b = find_atom_id(atom_sites, res_b) @@ -226,22 +250,22 @@ def _init_openbabel_atom(table, mol, res, atom_sites, i): Returns: OBAtom: openbabel Atom representation. """ - atom = mol.NewAtom(int(atom_sites['id'][i])) + atom = mol.NewAtom(int(atom_sites["id"][i])) atom.SetVector( - float(atom_sites['Cartn_x'][i]), - float(atom_sites['Cartn_y'][i]), - float(atom_sites['Cartn_z'][i]) + float(atom_sites["Cartn_x"][i]), + float(atom_sites["Cartn_y"][i]), + float(atom_sites["Cartn_z"][i]), ) - atomic_num = table.GetAtomicNum(atom_sites['type_symbol'][i]) + atomic_num = table.GetAtomicNum(atom_sites["type_symbol"][i]) atom.SetAtomicNum(atomic_num) atom.SetFormalCharge(_format_formal_charge(atom_sites, i)) res.AddAtom(atom) - res.SetHetAtom(atom, atom_sites['group_PDB'][i] == 'HETATM') - res.SetSerialNum(atom, int(atom_sites['id'][i])) + res.SetHetAtom(atom, atom_sites["group_PDB"][i] == "HETATM") + res.SetSerialNum(atom, int(atom_sites["id"][i])) - #_set_ob_occupancy(float(atom_sites['occupancy'][i]), atom) + # _set_ob_occupancy(float(atom_sites['occupancy'][i]), atom) return atom @@ -271,21 +295,21 @@ def read_mmcif_to_biopython(path): Bio.PDB.Structure.Structure: BioPython PDB structure """ if not os.path.isfile(path): - raise IOError('File {} not found'.format(path)) + raise IOError("File {} not found".format(path)) structure_builder = StructureBuilder() parsed = MMCIF2Dict().parse(path) - file_name = os.path.basename(path).split('.')[0] + file_name = os.path.basename(path).split(".")[0] structure_id = next((x for x in parsed), file_name).lower() structure_builder.init_structure(structure_id) try: - perceived_atom_site = list(parsed.values())[0]['_atom_site'] + perceived_atom_site = list(parsed.values())[0]["_atom_site"] _atom_site = _trim_models(perceived_atom_site) _parse_atom_site_biopython(_atom_site, structure_builder) except KeyError: - raise ValueError('The cif file does not contain _atom_site record') + raise ValueError("The cif file does not contain _atom_site record") return structure_builder.get_structure() @@ -300,11 +324,11 @@ def _get_hetero_flag(field, resn): Returns: str: PDB heteroatom flag as defined by BioPython """ - if field == 'HETATM': - if resn in ('HOH', 'WAT'): - return 'W' - return 'H' - return ' ' + if field == "HETATM": + if resn in ("HOH", "WAT"): + return "W" + return "H" + return " " def _init_biopython_atom(builder, atom_sites, i): @@ -316,33 +340,43 @@ def _init_biopython_atom(builder, atom_sites, i): atom_sites (dict of str): _atom_site dictionary of the mmcif file. i (int): Position within the _atom_site record. """ - x = float(atom_sites['Cartn_x'][i]) - y = float(atom_sites['Cartn_y'][i]) - z = float(atom_sites['Cartn_z'][i]) + x = float(atom_sites["Cartn_x"][i]) + y = float(atom_sites["Cartn_y"][i]) + z = float(atom_sites["Cartn_z"][i]) coord = numpy.array((x, y, z), "f") try: - builder.init_atom(atom_sites['label_atom_id'][i], - coord, - float(atom_sites['B_iso_or_equiv'][i]), - float(atom_sites['occupancy'][i]), - ' ' if atom_sites['label_alt_id'][i] == '.' else atom_sites['label_alt_id'][i], - atom_sites['label_atom_id'][i], - int(atom_sites['id'][i]), - atom_sites['type_symbol'][i].upper()) + builder.init_atom( + atom_sites["label_atom_id"][i], + coord, + _get_b_factor(atom_sites, i), + float(atom_sites["occupancy"][i]), + " " + if atom_sites["label_alt_id"][i] == "." + else atom_sites["label_alt_id"][i], + atom_sites["label_atom_id"][i], + int(atom_sites["id"][i]), + atom_sites["type_symbol"][i].upper(), + ) except PDB.PDBExceptions.PDBConstructionException: - builder.init_residue(atom_sites['label_comp_id'][i], - _get_hetero_flag(atom_sites, i), - _get_res_id(atom_sites, i), - _get_ins_code(atom_sites, i)) - builder.init_atom(atom_sites['label_atom_id'][i], - coord, - float(atom_sites['B_iso_or_equiv'][i]), - float(atom_sites['occupancy'][i]), - ' ' if atom_sites['label_alt_id'][i] == '.' else atom_sites['label_alt_id'][i], - atom_sites['label_atom_id'][i], - int(atom_sites['id'][i]), - atom_sites['type_symbol'][i].upper()) + builder.init_residue( + atom_sites["label_comp_id"][i], + _get_hetero_flag(atom_sites, i), + _get_res_id(atom_sites, i), + _get_ins_code(atom_sites, i), + ) + builder.init_atom( + atom_sites["label_atom_id"][i], + coord, + _get_b_factor(atom_sites, i), + float(atom_sites["occupancy"][i]), + " " + if atom_sites["label_alt_id"][i] == "." + else atom_sites["label_alt_id"][i], + atom_sites["label_atom_id"][i], + int(atom_sites["id"][i]), + atom_sites["type_symbol"][i].upper(), + ) def _parse_atom_site_biopython(atom_sites, builder): @@ -359,31 +393,41 @@ def _parse_atom_site_biopython(atom_sites, builder): last_res_name = None last_res_id = None - for i in range(len(atom_sites['id'])): + for i in range(len(atom_sites["id"])): res_id = _get_res_id(atom_sites, i) - hetero_flag = _get_hetero_flag(atom_sites['group_PDB'][i], atom_sites['label_comp_id'][i]) + hetero_flag = _get_hetero_flag( + atom_sites["group_PDB"][i], atom_sites["label_comp_id"][i] + ) ins_code = _get_ins_code(atom_sites, i) - if last_model != atom_sites['pdbx_PDB_model_num'][i]: # init model - last_model = atom_sites['pdbx_PDB_model_num'][i] + if last_model != atom_sites["pdbx_PDB_model_num"][i]: # init model + last_model = atom_sites["pdbx_PDB_model_num"][i] builder.init_model(int(last_model) - 1) if i == 0: - builder.init_seg(' ') # some biopython magic. https://github.com/biopython/biopython/blob/master/Bio/PDB/PDBParser.py#L211 + builder.init_seg( + " " + ) # some biopython magic. https://github.com/biopython/biopython/blob/master/Bio/PDB/PDBParser.py#L211 - if last_chain_id != atom_sites['auth_asym_id'][i]: # init chain - last_chain_id = atom_sites['auth_asym_id'][i] + if last_chain_id != atom_sites["auth_asym_id"][i]: # init chain + last_chain_id = atom_sites["auth_asym_id"][i] builder.init_chain(last_chain_id) - if last_res_id != res_id or last_chain_id != atom_sites['auth_asym_id'][i] or last_res_name != atom_sites['label_comp_id'][i] or last_ins_code != ins_code: + if ( + last_res_id != res_id + or last_chain_id != atom_sites["auth_asym_id"][i] + or last_res_name != atom_sites["label_comp_id"][i] + or last_ins_code != ins_code + ): last_res_id = res_id - last_res_name = atom_sites['label_comp_id'][i] + last_res_name = atom_sites["label_comp_id"][i] last_ins_code = ins_code - builder.init_residue(atom_sites['label_comp_id'][i], - hetero_flag, - res_id, - ins_code) + builder.init_residue( + atom_sites["label_comp_id"][i], hetero_flag, res_id, ins_code + ) _init_biopython_atom(builder, atom_sites, i) + + # endregion From 6e149963012644acf7c76d231d56b39e5ec2467d Mon Sep 17 00:00:00 2001 From: Lukas Pravda Date: Mon, 13 Jul 2020 12:47:51 +0200 Subject: [PATCH 2/8] make arpeggio openbabel 3.x compatible addresses #3 --- README.md | 4 ++-- arpeggio/core/interactions.py | 20 +++++++++++--------- arpeggio/core/protein_reader.py | 18 +++++++++--------- arpeggio/scripts/process_protein_cli.py | 2 +- setup.py | 2 +- 5 files changed, 24 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 2f27706..55f5475 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ If you need to use Arpeggio programmatically or to run for many structures: The easiest way to set up with Arpeggio is using [Conda](https://docs.conda.io/en/latest/). In your conda environment run the two following commands: ```bash -conda install -c openbabel openbabel +conda install -c conda-forge openbabel pip install git+https://github.com/PDBeurope/arpeggio.git@master#egg=arpeggio ``` @@ -63,7 +63,7 @@ conda activate arpeggio-env `arpeggio 1tqn_h.cif [options]` -e.g. +e.g. `arpeggio -s /A/508/ -o out/ 1tqn_h.cif` diff --git a/arpeggio/core/interactions.py b/arpeggio/core/interactions.py index 8cce33a..2e227d1 100644 --- a/arpeggio/core/interactions.py +++ b/arpeggio/core/interactions.py @@ -6,7 +6,7 @@ from functools import reduce import numpy as np -import openbabel as ob +from openbabel import openbabel as ob from Bio.PDB import NeighborSearch from Bio.PDB.Atom import DisorderedAtom from Bio.PDB.PDBParser import PDBParser @@ -226,7 +226,7 @@ def minimize_hydrogens(self, minimisation_forcefield, minimisation_method, minim for ob_atom in ob.OBMolAtomIter(self.ob_mol): - if not ob_atom.IsHydrogen(): + if not ob_atom.GetAtomicNum() == ob.Hydrogen: constraints.AddAtomConstraint(ob_atom.GetIdx()) logging.debug('Constrained non-hydrogen atoms.') @@ -1493,14 +1493,14 @@ def _add_atomic_radii(self): # ADD VDW RADII TO ENTITY ATOMS # USING OPENBABEL VDW RADII for atom in self.s_atoms: - atom.vdw_radius = ob.etab.GetVdwRad(self.ob_mol.GetAtomById(self.bio_to_ob[atom]).GetAtomicNum()) + atom.vdw_radius = ob.GetVdwRad(self.ob_mol.GetAtomById(self.bio_to_ob[atom]).GetAtomicNum()) logging.debug('Added VdW radii.') # ADD COVALENT RADII TO ENTITY ATOMS # USING OPENBABEL VDW RADII for atom in self.s_atoms: - atom.cov_radius = ob.etab.GetCovalentRad(self.ob_mol.GetAtomById(self.bio_to_ob[atom]).GetAtomicNum()) + atom.cov_radius = ob.GetCovalentRad(self.ob_mol.GetAtomById(self.bio_to_ob[atom]).GetAtomicNum()) logging.debug('Added covalent radii.') @@ -1516,7 +1516,7 @@ def _add_hydrogens_to_biopython(self): # GET THE BONDED ATOMS OF THE OBATOM for atom_neighbour in ob.OBAtomAtomIter(atom): - if atom_neighbour.IsHydrogen(): + if atom_neighbour.GetAtomicNum() == ob.Hydrogen: # APPEND THE HYDROGEN COORDINATES TO THE BIOPYTHON ATOM 'h_coords' ATTRIBUTE biopython_atom.h_coords.append(np.array([atom_neighbour.GetX(), atom_neighbour.GetY(), atom_neighbour.GetZ()])) @@ -1877,21 +1877,23 @@ def _initialize_residue_sift(self): def _handle_hydrogens(self): """Determine atom valences and explicit hydrogen counts. + Methods renamed according to the: https://open-babel.readthedocs.io/en/latest/UseTheLibrary/migration.html + """ for ob_atom in ob.OBMolAtomIter(self.ob_mol): if not self.input_has_hydrogens: - if ob_atom.IsHydrogen(): + if ob_atom.GetAtomicNum() == ob.Hydrogen: continue # `http://openbabel.org/api/2.3/classOpenBabel_1_1OBAtom.shtml` # CURRENT NUMBER OF EXPLICIT CONNECTIONS - valence = ob_atom.GetValence() + valence = ob_atom.GetExplicitDegree() # MAXIMUM NUMBER OF CONNECTIONS EXPECTED - implicit_valence = ob_atom.GetImplicitValence() + implicit_valence = ob_atom.GetImplicitHCount() # BOND ORDER - bond_order = ob_atom.BOSum() + bond_order = ob_atom.GetExplicitValence() # NUMBER OF BOUND HYDROGENS num_hydrogens = ob_atom.ExplicitHydrogenCount() diff --git a/arpeggio/core/protein_reader.py b/arpeggio/core/protein_reader.py index 54f01dd..e17787b 100644 --- a/arpeggio/core/protein_reader.py +++ b/arpeggio/core/protein_reader.py @@ -9,8 +9,7 @@ from Bio import PDB from Bio.PDB.StructureBuilder import StructureBuilder from mmCif.mmcifIO import MMCIF2Dict -import openbabel as ob - +from openbabel import openbabel as ob # region common @@ -102,7 +101,6 @@ def _parse_atom_site_openbabel(parsed): perceived_atom_site = parsed["_atom_site"] atom_site = _trim_models(perceived_atom_site) - table = ob.OBElementTable() last_res_id = None last_res_name = None last_chain_id = None @@ -136,10 +134,10 @@ def _parse_atom_site_openbabel(parsed): res.SetName(atom_site["label_comp_id"][i]) res.SetInsertionCode(ins_code) - _init_openbabel_atom(table, mol, res, atom_site, i) + _init_openbabel_atom(mol, res, atom_site, i) resdat = ob.OBResidueData() - resdat.AssignBonds(mol, ob.OBBitVec()) + resdat.AssignBonds(mol) mol.ConnectTheDots() mol.PerceiveBondOrders() @@ -236,12 +234,10 @@ def __add_bond_to_openbabel(mol, atom_id_a, atom_id_b): b.SetBondOrder(1) -def _init_openbabel_atom(table, mol, res, atom_sites, i): +def _init_openbabel_atom(mol, res, atom_sites, i): """Initialize openbabel atom Args: - table (OBElementTable): Element table to translate element type - to element numbers. mol (ob.OBMol): Molecule the atom will be added to. res (OBResidue): Residue the atom will be added to. atom_sites (dict of str): Parsed mmcif structure of the input file. @@ -257,7 +253,11 @@ def _init_openbabel_atom(table, mol, res, atom_sites, i): float(atom_sites["Cartn_y"][i]), float(atom_sites["Cartn_z"][i]), ) - atomic_num = table.GetAtomicNum(atom_sites["type_symbol"][i]) + + type_symbol = atom_sites["type_symbol"][i] + element = f'{type_symbol[0]}{type_symbol[1].lower()}' if len(type_symbol) == 2 else type_symbol + + atomic_num = ob.GetAtomicNum(element) atom.SetAtomicNum(atomic_num) atom.SetFormalCharge(_format_formal_charge(atom_sites, i)) diff --git a/arpeggio/scripts/process_protein_cli.py b/arpeggio/scripts/process_protein_cli.py index 051588b..cf2a43c 100644 --- a/arpeggio/scripts/process_protein_cli.py +++ b/arpeggio/scripts/process_protein_cli.py @@ -29,7 +29,7 @@ def create_parser(): - Python (v3.6) - Numpy - BioPython (>= v1.60) - - OpenBabel (with Python bindings) + - OpenBabel (>= 3.0) ''', formatter_class=argparse.RawTextHelpFormatter) diff --git a/setup.py b/setup.py index 59b131e..c221f35 100644 --- a/setup.py +++ b/setup.py @@ -31,7 +31,7 @@ ], zip_safe=False, include_package_data=True, - install_requires=["pdbecif", "numpy", "biopython"], + install_requires=["pdbecif>2.0", "numpy", "biopython"], tests_require=["pytest"], entry_points={ "console_scripts": ["arpeggio=arpeggio.scripts.process_protein_cli:main"] From 0bc87000062dc01dac64b2a889f676cbfbf488fd Mon Sep 17 00:00:00 2001 From: Lukas Pravda Date: Mon, 13 Jul 2020 13:16:13 +0200 Subject: [PATCH 3/8] change condition for pdbecif install --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index c221f35..0a38ef8 100644 --- a/setup.py +++ b/setup.py @@ -31,7 +31,7 @@ ], zip_safe=False, include_package_data=True, - install_requires=["pdbecif>2.0", "numpy", "biopython"], + install_requires=["pdbecif<2.0", "numpy", "biopython"], tests_require=["pytest"], entry_points={ "console_scripts": ["arpeggio=arpeggio.scripts.process_protein_cli:main"] From ea17dfe0ba3fd0f1b00cb15cf70cfc22fa0326f5 Mon Sep 17 00:00:00 2001 From: Lukas Pravda Date: Mon, 13 Jul 2020 13:16:50 +0200 Subject: [PATCH 4/8] improve readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 55f5475..b34e4dc 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ Arpeggio is written in Python and currently has the following dependencies: * Python (v3.6) * Numpy * BioPython (>= v1.60) -* OpenBabel (with Python bindings) +* OpenBabel (>=3.0) * PDBeCIF If you need to use Arpeggio programmatically or to run for many structures: From 3f47508aebb1978aec4d419c98566ea1fbf9821d Mon Sep 17 00:00:00 2001 From: Lukas Pravda Date: Tue, 14 Jul 2020 10:00:13 +0200 Subject: [PATCH 5/8] get rid of testing bit --- arpeggio/core/interactions.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/arpeggio/core/interactions.py b/arpeggio/core/interactions.py index 2e227d1..f2a2d20 100644 --- a/arpeggio/core/interactions.py +++ b/arpeggio/core/interactions.py @@ -1226,9 +1226,6 @@ def __calculate_group_group_contacts(self): if amide_key == amide_key2: continue - if amide_key == 441 and amide2 == 442: - print('foo') - # CHECK RING IS INVOLVED WITH THE SELECTION OR BINDING SITE if amide_key2 not in self.selection_plus_amide_ids: continue From 043b2426aa5f2098835b4f22fa8649517380d1bb Mon Sep 17 00:00:00 2001 From: Lukas Pravda Date: Tue, 14 Jul 2020 10:00:52 +0200 Subject: [PATCH 6/8] make process_protein_cli directly executable --- arpeggio/scripts/process_protein_cli.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arpeggio/scripts/process_protein_cli.py b/arpeggio/scripts/process_protein_cli.py index cf2a43c..ca1ef64 100644 --- a/arpeggio/scripts/process_protein_cli.py +++ b/arpeggio/scripts/process_protein_cli.py @@ -144,3 +144,7 @@ def _parse_selection(args): else: logger.warning(f'No selection was perceived. Defaults into full structure!!') return selection + + +if __name__ == "__main__": + main() From 3cfe9450acded0f5ec98ed6bfa70877d9a58a319 Mon Sep 17 00:00:00 2001 From: Lukas Pravda Date: Tue, 14 Jul 2020 10:01:26 +0200 Subject: [PATCH 7/8] modify gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index f835516..b8e03b1 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ examples/* .vscode/* .pytest_cache/* .mypy_cache +arpeggio.egg-info From a54c52d182e3bbc6620e5f2958f7f3dcb21b2bbc Mon Sep 17 00:00:00 2001 From: Lukas Pravda Date: Sun, 19 Jul 2020 16:11:52 +0200 Subject: [PATCH 8/8] user pdbecif 1.5+ --- arpeggio/core/protein_reader.py | 2 +- setup.py | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/arpeggio/core/protein_reader.py b/arpeggio/core/protein_reader.py index e17787b..717d688 100644 --- a/arpeggio/core/protein_reader.py +++ b/arpeggio/core/protein_reader.py @@ -8,7 +8,7 @@ import numpy from Bio import PDB from Bio.PDB.StructureBuilder import StructureBuilder -from mmCif.mmcifIO import MMCIF2Dict +from pdbecif.mmcif_io import MMCIF2Dict from openbabel import openbabel as ob # region common diff --git a/setup.py b/setup.py index 0a38ef8..8ca9816 100644 --- a/setup.py +++ b/setup.py @@ -31,7 +31,11 @@ ], zip_safe=False, include_package_data=True, - install_requires=["pdbecif<2.0", "numpy", "biopython"], + install_requires=[ + "numpy", + "biopython", + "pdbecif @ git+https://github.com/PDBeurope/pdbecif.git@master#egg=pdbecif", + ], tests_require=["pytest"], entry_points={ "console_scripts": ["arpeggio=arpeggio.scripts.process_protein_cli:main"]