Skip to content

Commit

Permalink
fix flake8 warnings
Browse files Browse the repository at this point in the history
  • Loading branch information
ale94mleon committed Nov 26, 2023
1 parent 43a30f9 commit 0810264
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 51 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ on:
branches: [ "main" ]

jobs:
build_ubuntu:
build:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
Expand Down
7 changes: 4 additions & 3 deletions src/toff/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
Docs: https://TOFF.readthedocs.io/en/latest/
Source Code: https://github.com/ale94mleon/TOFF
"""
from ._version import __version__
from .utils import *
from toff._version import __version__
from toff.utils import *

__author__ = "Alejandro Martínez León"
__email__ = "[email protected]"
__email__ = "[email protected]"
15 changes: 10 additions & 5 deletions src/toff/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,13 @@
Source Code: https://github.com/ale94mleon/TOFF
"""

from toff import __version__, Parameterize
import yaml, argparse, warnings
import argparse
import warnings

import yaml

from toff import Parameterize, __version__


def __parameterize_cmd():
parser = argparse.ArgumentParser(description=__doc__,
Expand All @@ -25,8 +30,8 @@ def __parameterize_cmd():
print(f"You are using toff:{__version__}")
with open(args.yaml_file, 'r') as c:
Config = yaml.safe_load(c)
InitKwargs = ['force_field_code','ext_types','hmr_factor','overwrite', 'safe_naming_prefix', 'out_dir']
CallKwargs = ['input_mol','mol_resi_name']
InitKwargs = ['force_field_code', 'ext_types', 'hmr_factor', 'overwrite', 'safe_naming_prefix', 'out_dir']
CallKwargs = ['input_mol', 'mol_resi_name']

UserExtraNonValidKwargs = set(Config.keys()) - set(InitKwargs + CallKwargs)
if 'input_mol' not in Config:
Expand All @@ -38,4 +43,4 @@ def __parameterize_cmd():
UserCallKwargs = {kwarg: Config[kwarg] for kwarg in Config if kwarg in CallKwargs}
parameterizer = Parameterize(**UserInitKwargs)
print(parameterizer)
parameterizer(**UserCallKwargs)
parameterizer(**UserCallKwargs)
96 changes: 54 additions & 42 deletions src/toff/utils.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import numpy as np
import os, warnings, tempfile
import os
import tempfile
import warnings
from copy import deepcopy
from rdkit import Chem
from rdkit.Chem import AllChem
from openff.toolkit.typing.engines import smirnoff
from typing import Iterable, List

import numpy as np
import parmed
from openff.toolkit.topology import Molecule
from openff.toolkit.typing.engines import smirnoff
from openmm import app
import parmed
from typing import List, Iterable
from rdkit import Chem
from rdkit.Chem import AllChem

# This module was strongly inspired in https://github.com/aniketsh/OpenFF/blob/82a2b5803e36b72f3525e3b8631cf256fbd8e35a/openff_topology.py

#This module was strongly inspired in https://github.com/aniketsh/OpenFF/blob/82a2b5803e36b72f3525e3b8631cf256fbd8e35a/openff_topology.py

def confgen(mol: Chem.rdchem.Mol):
"""Create a 3D model for the molecule only
Expand Down Expand Up @@ -40,7 +43,8 @@ def confgen(mol: Chem.rdchem.Mol):

return mol

def get_rdkit_mol(input_path_mol:str):

def get_rdkit_mol(input_path_mol: str):
"""Get a file with a definition of a molecule and return the corresponded RDKit molecule object
with a conformation if there not present.
Expand Down Expand Up @@ -92,7 +96,8 @@ def get_rdkit_mol(input_path_mol:str):
warnings.warn("Molecule was not converted. Check the input")
return mol

def topology_writer(ligand_structure:parmed.structure.Structure, ext_types:List[str] = None, overwrite = False, out_dir:str = '.') -> None:

def topology_writer(ligand_structure: parmed.structure.Structure, ext_types: List[str] = None, overwrite: bool = False, out_dir: str = '.') -> None:
"""A toff wrapper around the `save` method of :meth:`parmed.structure.Structure`
Parameters
Expand All @@ -113,7 +118,7 @@ def topology_writer(ligand_structure:parmed.structure.Structure, ext_types:List[
"""

valid_ext_types = [
'pdb', 'pqr', 'cif','pdbx',
'pdb', 'pqr', 'cif', 'pdbx',
'parm7', 'prmtop', 'psf', 'top',
'gro', 'mol2', 'mol3', 'crd',
'rst7', 'inpcrd', 'restrt', 'ncrst',
Expand All @@ -125,11 +130,12 @@ def topology_writer(ligand_structure:parmed.structure.Structure, ext_types:List[
ext_type = ext_type.lower()
if ext_type in valid_ext_types:
path = os.path.join(out_dir, f"{ligand_structure.atoms[0].residue.name}.{ext_type}")
ligand_structure.save(path, overwrite = overwrite)
ligand_structure.save(path, overwrite=overwrite)
else:
warnings.warn(f"{ext_type} is not a valid extension type. Only: {valid_ext_types}")

def get_partial_charges(ligand_structure:parmed.structure.Structure):

def get_partial_charges(ligand_structure: parmed.structure.Structure):
"""get the partial charges from a :meth:`parmed.structure.Structure` object.
Parameters
Expand All @@ -144,7 +150,8 @@ def get_partial_charges(ligand_structure:parmed.structure.Structure):
"""
return np.array([atom.charge for atom in ligand_structure])

def set_partial_charges(ligand_structure:Chem.rdchem.Mol, partial_charges:Iterable):

def set_partial_charges(ligand_structure: Chem.rdchem.Mol, partial_charges: Iterable):
"""Set new partial charges to a :meth:`parmed.structure.Structure` object
Parameters
Expand All @@ -163,7 +170,8 @@ def set_partial_charges(ligand_structure:Chem.rdchem.Mol, partial_charges:Iterab
atom.charge = charge
return ligand_structure

def charge_sanitizer(rdkit_mol:Chem.rdchem.Mol, ligand_structure:parmed.structure.Structure, max_iter:int = 100):

def charge_sanitizer(rdkit_mol: Chem.rdchem.Mol, ligand_structure: parmed.structure.Structure, max_iter: int = 100):
"""Check and correct (if needed) if the formal charge from the rdkit_mol is not the same as the sum of
of the partial charges of the ligand_structure.
Expand All @@ -190,7 +198,7 @@ def charge_sanitizer(rdkit_mol:Chem.rdchem.Mol, ligand_structure:parmed.structur

# Round up the formal charge
for atom in ligand_structure:
atom.charge = round(atom.charge,7)
atom.charge = round(atom.charge, 7)

partial_charges = get_partial_charges(ligand_structure)
diff = round(partial_charges.sum() - formal_charge, 6)
Expand All @@ -215,7 +223,8 @@ def charge_sanitizer(rdkit_mol:Chem.rdchem.Mol, ligand_structure:parmed.structur
# print("No charge correction needed.")
return ligand_structure

def safe_naming(ligand_structure:parmed.structure.Structure, prefix:str = 'z', inplace:bool = True):

def safe_naming(ligand_structure: parmed.structure.Structure, prefix: str = 'z', inplace: bool = True):
"""Add a prefix to the atom types in order to avoid
incompatibilities with other force fields
Expand Down Expand Up @@ -244,7 +253,8 @@ def safe_naming(ligand_structure:parmed.structure.Structure, prefix:str = 'z', i
else:
return ligand_structure

def generate_structure(rdkit_mol:Chem.rdchem.Mol, force_field_type:str = 'openff', force_field_code:str = None) -> parmed.structure.Structure:

def generate_structure(rdkit_mol: Chem.rdchem.Mol, force_field_type: str = 'openff', force_field_code: str = None) -> parmed.structure.Structure:
"""Generate a Structure object with the topology information from the specified force field.
OpenFF, GAFF and Espaloma flavors are supported
Expand Down Expand Up @@ -301,32 +311,33 @@ def generate_structure(rdkit_mol:Chem.rdchem.Mol, force_field_type:str = 'openff
if force_field_type == 'gaff':
# Create the GAFF template generator
from openmmforcefields.generators import GAFFTemplateGenerator
template_generator = GAFFTemplateGenerator(molecules=molecule, forcefield = force_field_code_default[force_field_type])
template_generator = GAFFTemplateGenerator(molecules=molecule, forcefield=force_field_code_default[force_field_type])
elif force_field_type == 'espaloma':
# Create the Espaloma template generator
from openmmforcefields.generators import EspalomaTemplateGenerator
template_generator = EspalomaTemplateGenerator(molecules=molecule, forcefield = force_field_code_default[force_field_type])
template_generator = EspalomaTemplateGenerator(molecules=molecule, forcefield=force_field_code_default[force_field_type])

forcefield_obj.registerTemplateGenerator(template_generator.generator)
system = forcefield_obj.createSystem(pdb_obj.topology)
structure = parmed.openmm.load_topology(pdb_obj.topology, system = system, xyz = pdb_obj.positions)

structure = parmed.openmm.load_topology(pdb_obj.topology, system=system, xyz=pdb_obj.positions)
tmp_pdb.close()
return structure


class Parameterize:
"""This is the main class for the parameterization
"""

def __init__(
self,
force_field_type:str = 'openff',
force_field_code:str = None,
ext_types:List[str] = None,
hmr_factor:float = None,
overwrite:bool = False,
safe_naming_prefix:str = None,
out_dir:str = '.',
force_field_type: str = 'openff',
force_field_code: str = None,
ext_types: List[str] = None,
hmr_factor: float = None,
overwrite: bool = False,
safe_naming_prefix: str = None,
out_dir: str = '.',
) -> None:
"""This is the constructor of the class.
GAFF and Espaloma capabilities came on version toff:0.1.0
Expand Down Expand Up @@ -382,7 +393,7 @@ def __repr__(self) -> str:
f"overwrite = {self.overwrite}, safe_naming_prefix = {self.safe_naming_prefix}, "\
f"out_dir = {self.out_dir})"

def __call__(self, input_mol, mol_resi_name:str = "MOL"):
def __call__(self, input_mol, mol_resi_name: str = "MOL"):
"""This class is callable. And this is its implementation.
it will return the specified files (ext_types in __init__) in the directory out_dir.
Expand All @@ -406,22 +417,23 @@ def __call__(self, input_mol, mol_resi_name:str = "MOL"):
if isinstance(input_mol, Chem.rdchem.Mol):
rdkit_mol = confgen(input_mol)
elif isinstance(input_mol, str):
rdkit_mol = get_rdkit_mol(input_path_mol = input_mol)
rdkit_mol = get_rdkit_mol(input_path_mol=input_mol)
else:
raise Exception(f'input_mol must be an instance of Chem.rdchem.Mol or str. But it is {type(input_mol)}')

if len(mol_resi_name) > 4:
warnings.warn(f"mol_resi_name = {mol_resi_name} is to large. consider to use a code with no more than 4 characters.")

# Create if needed the output directory
if not os.path.isdir(self.out_dir): os.makedirs(self.out_dir)
if not os.path.isdir(self.out_dir):
os.makedirs(self.out_dir)

ligand_structure = generate_structure(
rdkit_mol = rdkit_mol,
force_field_type = self.force_field_type,
force_field_code = self.force_field_code
rdkit_mol=rdkit_mol,
force_field_type=self.force_field_type,
force_field_code=self.force_field_code
)

# Make Hydrogens Heavy for 4fs timestep
if self.hmr_factor:
parmed.tools.HMassRepartition(ligand_structure, self.hmr_factor).execute()
Expand All @@ -431,16 +443,16 @@ def __call__(self, input_mol, mol_resi_name:str = "MOL"):
atom.residue.name = mol_resi_name

# Correct charges if needed
ligand_structure = charge_sanitizer(rdkit_mol = rdkit_mol, ligand_structure = ligand_structure)
ligand_structure = charge_sanitizer(rdkit_mol=rdkit_mol, ligand_structure=ligand_structure)

# Write the output topologies
if self.safe_naming_prefix:
safe_naming(ligand_structure, prefix=self.safe_naming_prefix, inplace=True)
topology_writer(
ligand_structure = ligand_structure,
ext_types = self.ext_types,
out_dir = self.out_dir,
overwrite = self.overwrite,
ligand_structure=ligand_structure,
ext_types=self.ext_types,
out_dir=self.out_dir,
overwrite=self.overwrite,
)


Expand Down

0 comments on commit 0810264

Please sign in to comment.