diff --git a/DockerMakefiles/CLI.yml b/DockerMakefiles/CLI.yml index 4bb2380..6db3176 100644 --- a/DockerMakefiles/CLI.yml +++ b/DockerMakefiles/CLI.yml @@ -11,19 +11,13 @@ ambertools: - miniconda build: | RUN apt-get update \ - && apt-get install --no-install-recommends -y libgfortran3 \ - && apt-get -y clean && apt-get autoremove -y --purge && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + && apt-get install --no-install-recommends -y \ + libgfortran3 gcc gfortran libfftw3-dev libnetcdf-dev \ + && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* RUN python -c "print('name = molecular-design-toolkit-builder\ninstitution = Autodesk\ncity = San Francisco\nstate or province = CA\ncountry = USA')" > /root/.amberrc RUN conda install -qy -c ambermd ambertools=16.21.1 ENV AMBERHOME=/opt/conda/ -nucleic_acid_builder: - requires: - - ambertools - build: | - RUN apt-get update \ - && apt-get install --no-install-recommends -y gcc gfortran libfftw3-dev libnetcdf-dev \ - && apt-get -y clean && apt-get autoremove -y --purge && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* dssp: diff --git a/DockerMakefiles/DockerMake.yml b/DockerMakefiles/DockerMake.yml index 16a6327..703ee8f 100644 --- a/DockerMakefiles/DockerMake.yml +++ b/DockerMakefiles/DockerMake.yml @@ -18,7 +18,6 @@ _ALL_: - moldesign_minimal - moldesign_minimal_py2 - moldesign_notebook - - nucleic_acid_builder - nwchem_build - openblas - pyscf_build diff --git a/DockerMakefiles/Dockerfile.build_environment b/DockerMakefiles/Dockerfile.build_environment deleted file mode 100644 index 851d774..0000000 --- a/DockerMakefiles/Dockerfile.build_environment +++ /dev/null @@ -1,22 +0,0 @@ -FROM python:2.7-slim - -# Installing docker CLI -RUN apt-get update \ - && apt-get install -y --no-install-recommends \ - apt-transport-https \ - ca-certificates \ - curl \ - gnupg2 \ - software-properties-common \ - && curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add - \ - && add-apt-repository \ - "deb [arch=amd64] https://download.docker.com/linux/debian \ - $(lsb_release -cs) \ - stable" \ - && apt-get update \ - && apt-get install -y docker-ce - -ADD . /opt/molecular-design-toolkit -RUN pip install -r /opt/molecular-design-toolkit/DockerMakefiles/requirements.txt -WORKDIR /opt/molecular-design-toolkit/DockerMakefiles - diff --git a/DockerMakefiles/Moldesign.yml b/DockerMakefiles/Moldesign.yml index 73e9da7..61da0e9 100644 --- a/DockerMakefiles/Moldesign.yml +++ b/DockerMakefiles/Moldesign.yml @@ -60,17 +60,19 @@ moldesign_notebook: RUN python -m nbmolviz activate --user USER root RUN python -m moldesign copyexamples + RUN chmod -R a+rw . + moldesign_stack: description: An extra-large image with everything needed to run the example notebooks build_directory: buildfiles/moldesign requires: - - moldesign_notebook - opsin - symmol_base - - nucleic_acid_builder + - ambertools + - moldesign_notebook build: | USER nbuser - RUN mkdir -p ~/.moldesign - ADD moldesign.yml ~/.moldesign/moldesign.yml + RUN mkdir -p /home/nbuser/.moldesign + ADD moldesign.yml /home/nbuser/.moldesign/moldesign.yml diff --git a/DockerMakefiles/PythonTools.yml b/DockerMakefiles/PythonTools.yml index bdd2375..c57f7d6 100644 --- a/DockerMakefiles/PythonTools.yml +++ b/DockerMakefiles/PythonTools.yml @@ -22,6 +22,9 @@ chem_python_conda: - deploy_requirements description: All of the external python chemistry libraries in one place build: | + RUN apt-get update \ + && apt-get install -y libpng12-dev \ + && cleanapt RUN conda install -qy -c openbabel openbabel=2.4.1 RUN conda install -qy -c omnia \ biopython=1.68 \ diff --git a/DockerMakefiles/buildfiles/moldesign/moldesign.yml b/DockerMakefiles/buildfiles/moldesign/moldesign.yml index a4647c9..e29ecf4 100644 --- a/DockerMakefiles/buildfiles/moldesign/moldesign.yml +++ b/DockerMakefiles/buildfiles/moldesign/moldesign.yml @@ -1,4 +1,4 @@ run_local: - nab.exe: true + nab: true opsin: true symmol: true diff --git a/DockerMakefiles/requirements.txt b/DockerMakefiles/requirements.txt index 6bc8298..676d81f 100644 --- a/DockerMakefiles/requirements.txt +++ b/DockerMakefiles/requirements.txt @@ -1 +1,2 @@ -DockerMake >= 0.5.6 +DockerMake >= 0.6.0rc2 + diff --git a/codeship-services.yml b/codeship-services.yml index 4f38acf..47c58dd 100644 --- a/codeship-services.yml +++ b/codeship-services.yml @@ -10,8 +10,8 @@ docker_make: publisher: encrypted_env_file: deployment/tokens.crypt build: - context: ./deployment - dockerfile: ./moldesign-complete-cache.dockerfile + context: . # this one builds at the root of the repository + dockerfile: ./deployment/moldesign-complete-cache.dockerfile add_docker: true working_dir: /opt/molecular-design-toolkit volumes: @@ -50,8 +50,8 @@ test_moldesign_minimal_py2: test_moldesign_complete: encrypted_env_file: deployment/tokens.crypt build: - context: ./deployment - dockerfile: moldesign-complete-cache.dockerfile + context: ./ # this one builds at the root of the repository + dockerfile: ./deployment/moldesign-complete-cache.dockerfile cached: false # do not cache this! It gets built before the cache is triggered working_dir: /opt/molecular-design-toolkit/ add_docker: true diff --git a/codeship-steps.yml b/codeship-steps.yml index 895e935..35e6559 100644 --- a/codeship-steps.yml +++ b/codeship-steps.yml @@ -2,13 +2,7 @@ service: docker_make type: serial steps: - - command: - docker-make -p -n --dockerfile-dir /makefiles - nwchem_build - pyscf_build - deploybase - python_deploy_base - python_deploy_base_py2 + - command: docker-make -p -n --dockerfile-dir /makefiles nwchem_build pyscf_build deploybase python_deploy_base python_deploy_base_py2 name: write_dockerfiles - command: cp buildfiles/deploybase/cleanapt buildfiles/notebook/run_notebook.sh /makefiles name: copy_contexts @@ -70,15 +64,22 @@ steps: - command: deployment/print_environment.sh -- type: serial - name: complete_tests - services: - - test_moldesign_complete - - test_moldesign_complete_py2 - - test_moldesign_minimal - - test_moldesign_minimal_py2 - steps: - - command: deployment/codeship_runtests.sh +- service: test_moldesign_complete + name: test_moldesign_complete + command: deployment/codeship_runtests.sh + +- service: test_moldesign_complete_py2 + name: test_moldesign_complete_py2 + command: deployment/codeship_runtests.sh + +- service: test_moldesign_minimal + name: test_moldesign_minimal + command: deployment/codeship_runtests.sh + +- service: test_moldesign_minimal_py2 + name: test_moldesign_minimal_py2 + command: deployment/codeship_runtests.sh + - name: publish service: publisher diff --git a/deployment/moldesign-complete-cache.dockerfile b/deployment/moldesign-complete-cache.dockerfile index 102710a..fe1b2c0 100644 --- a/deployment/moldesign-complete-cache.dockerfile +++ b/deployment/moldesign-complete-cache.dockerfile @@ -1,5 +1,8 @@ +# this is meant to built at the ROOT of the repository + FROM moldesign_complete:dev -ADD requirements.txt provision_testrunner_image.sh /tmp/ +ADD DockerMakefiles /opt/molecular-design-toolkit/DockerMakefiles +ADD deployment/requirements.txt deployment/provision_testrunner_image.sh /tmp/ RUN cd /tmp && ./provision_testrunner_image.sh RUN pip install twine WORKDIR /opt/molecular-design-toolkit diff --git a/moldesign/_tests/test_pdbfixer_xface.py b/moldesign/_tests/test_pdbfixer_xface.py index ec5dd5a..82ad69f 100644 --- a/moldesign/_tests/test_pdbfixer_xface.py +++ b/moldesign/_tests/test_pdbfixer_xface.py @@ -22,6 +22,7 @@ import moldesign as mdt from moldesign import units as u +from .helpers import get_data_path import pytest @@ -91,6 +92,23 @@ def test_mutation_nomenclature_string_only(pdb3aid): assert len(mut25) == 2 assert [r.resname for r in mut25] == ['MET', 'MET'] +def test_mutation_topology(pdb1yu8): + """ Test the topology of the backbone atoms for a mutated molecule. """ + molecule = pdb1yu8 + mutation_residues = ["X.13G"] + mutated_molecule = mdt.mutate_residues(molecule, mutation_residues) + # Check that the number of bonds for backbone atoms match. + for res, mut_res in zip(molecule.residues, mutated_molecule.residues): + if not res.backbone: + continue + for atom in res.backbone: + bonds = [bond for bond in molecule.bond_graph[atom] if bond.name in res.backbone] + mut_atom = mutated_molecule.chains["X"].residues[mut_res.name].atoms[atom.name] + mut_bonds = mutated_molecule.bond_graph[mut_atom] + mut_bonds = [bond for bond in mutated_molecule.bond_graph[mut_atom] \ + if bond.name in mut_res.backbone] + assert len(bonds) == len(mut_bonds) + @pytest.mark.screening def test_multiple_mutations(pdb3aid): diff --git a/moldesign/compute/configuration.py b/moldesign/compute/configuration.py index 7c971f8..8a67c1a 100644 --- a/moldesign/compute/configuration.py +++ b/moldesign/compute/configuration.py @@ -190,11 +190,19 @@ def init_config(): for pkg, do_remote in list(config.run_remote.items()): if do_remote: - getattr(packages, pkg).force_remote = True + try: + getattr(packages, pkg).force_remote = True + except AttributeError: + print('WARNING: unknown key "%s" in %s' % (pkg, path), + file=sys.stderr) for pkg, do_local in list(config.run_local.items()): if do_local: - getattr(packages, pkg).run_local = True + try: + getattr(packages, pkg).run_local = True + except AttributeError: + print('WARNING: unknown key "%s" in %s' % (pkg, path), + file=sys.stderr) def _check_override(tagname, expected, path): diff --git a/moldesign/compute/packages.py b/moldesign/compute/packages.py index 1c53172..8878afb 100644 --- a/moldesign/compute/packages.py +++ b/moldesign/compute/packages.py @@ -256,7 +256,7 @@ def make_job(self, **kwargs): nwchem = InterfacedExecutable('nwchem.exe', None, 'nwchem', version_flag=None) opsin = InterfacedExecutable('opsin', None, 'opsin', version_flag=None) -nab = InterfacedExecutable('nab', '16', 'nucleic_acid_builder', version_flag=None) +nab = InterfacedExecutable('nab', '16', 'ambertools', version_flag=None) symmol = InterfacedExecutable('symmol', None, 'symmol', version_flag=None) tleap = InterfacedExecutable('tleap', '16', 'ambertools', version_flag=None) antechamber = InterfacedExecutable('antechamber', '16', 'ambertools', version_flag=None) diff --git a/moldesign/interfaces/pdbfixer_interface.py b/moldesign/interfaces/pdbfixer_interface.py index bf41bd2..eb64a16 100644 --- a/moldesign/interfaces/pdbfixer_interface.py +++ b/moldesign/interfaces/pdbfixer_interface.py @@ -97,21 +97,48 @@ def mutate_residues(mol, residue_map): # into an MDT structure assert temp_mutant.num_residues == mol.num_residues # shouldn't change number of residues residues_to_copy = [] + old_residue_map = {} for oldres, mutant_res in zip(mol.residues, temp_mutant.residues): if oldres in residue_map: residues_to_copy.append(mutant_res) mutant_res.mol = None mutant_res.chain = oldres.chain + old_residue_map[oldres] = mutant_res else: residues_to_copy.append(oldres) + # Bonds between original and mutated backbone atoms will be removed when + # creating the new mutant molecule because the original and mutated atoms + # reference different molecules. + # + # Make a list of bonds referencing atoms in the original molecule that + # is used later to recreate bonds between original and mutated backbone + # atoms. + orig_bonds = [] + for res in residues_to_copy: + if not res.backbone: + continue + for atom in res.backbone: + for bond_atom in atom.bond_graph: + if bond_atom.residue in residue_map: + mutant_res = old_residue_map[bond_atom.residue] + mutant_atom = mutant_res.atoms[bond_atom.name] + orig_bonds.append((atom,mutant_atom,atom.bond_graph[bond_atom])) + metadata = {'origin': mol.metadata.copy(), 'mutations': mutation_strs} - return mdt.Molecule(residues_to_copy, - name='Mutant of "%s"' % mol, - metadata=metadata) + mutant_mol = mdt.Molecule(residues_to_copy, name='Mutant of "%s"' % mol, metadata=metadata) + + # Add bonds between the original and mutated backbone atoms. + for atom,mut_atom,order in orig_bonds: + chainID = atom.chain.name + residues = mutant_mol.chains[chainID].residues + new_atom = residues[atom.residue.name].atoms[atom.name] + new_mut_atom = residues[mut_atom.residue.name].atoms[mut_atom.name] + new_atom.bond_to(new_mut_atom, order) + return mutant_mol def _pdbfixer_chainnames_to_letter(pdbfixermol): for chain in pdbfixermol.chains: