33import os
44import tempfile
55import unittest
6+ import pytest
67
78import numpy as np
89import openmm
@@ -532,12 +533,6 @@ def test_parameterize(self):
532533 """Test parameterizing molecules with template generator for all supported force fields"""
533534 # Test all supported small molecule force fields
534535 for small_molecule_forcefield in self .TEMPLATE_GENERATOR .INSTALLED_FORCEFIELDS :
535- if "ff14sb" in small_molecule_forcefield :
536- continue
537- if "tip" in small_molecule_forcefield :
538- continue
539- if "opc" in small_molecule_forcefield :
540- continue
541536
542537 print (f'Testing { small_molecule_forcefield } ' )
543538 # Create a generator that knows about a few molecules
@@ -712,6 +707,19 @@ def relative_deviation(x, y):
712707 write_xml ('openmm-smirnoff.xml' , template_generated_system )
713708 raise Exception (f'Relative force deviation for { molecule .to_smiles ()} ({ relative_force_deviation } ) exceeds threshold ({ RELATIVE_FORCE_DEVIATION_TOLERANCE } )' )
714709
710+ def smirnoff_small_molecule_forcefields ():
711+ force_fields = list ()
712+ for small_molecule_forcefield in SMIRNOFFTemplateGenerator .INSTALLED_FORCEFIELDS :
713+ if 'tip' in small_molecule_forcefield :
714+ continue
715+ if 'opc' in small_molecule_forcefield :
716+ continue
717+ if small_molecule_forcefield .startswith ('ff14sb' ):
718+ continue
719+ force_fields .append (small_molecule_forcefield )
720+
721+ return force_fields
722+
715723class TestSMIRNOFFTemplateGenerator (TestGAFFTemplateGenerator ):
716724 TEMPLATE_GENERATOR = SMIRNOFFTemplateGenerator
717725
@@ -778,71 +786,55 @@ def test_INSTALLED_FORCEFIELDS(self):
778786 for forbidden in forbidden_force_fields :
779787 assert forbidden not in SMIRNOFFTemplateGenerator .INSTALLED_FORCEFIELDS
780788
781- def test_energies (self ):
789+ @pytest .mark .parametrize ("small_molecule_forcefield" , smirnoff_small_molecule_forcefields ())
790+ def test_energies (self , small_molecule_forcefield ):
782791 """Test potential energies match between openff-toolkit and OpenMM ForceField"""
783792
784- # Test all supported SMIRNOFF force fields
785- for small_molecule_forcefield in SMIRNOFFTemplateGenerator .INSTALLED_FORCEFIELDS :
786- if "ff14sb" in small_molecule_forcefield :
787- continue
788- if "tip" in small_molecule_forcefield :
789- continue
790- if "opc" in small_molecule_forcefield :
791- continue
792-
793- print (f'Testing energies for { small_molecule_forcefield } ...' )
794- # Create a generator that knows about a few molecules
795- # TODO: Should the generator also load the appropriate force field files into the ForceField object?
796- generator = SMIRNOFFTemplateGenerator (molecules = self .molecules , forcefield = small_molecule_forcefield )
797- # Create a ForceField
798- openmm_forcefield = openmm .app .ForceField ()
799- # Register the template generator
800- openmm_forcefield .registerTemplateGenerator (generator .generator )
801- # Parameterize some molecules
802- for molecule in self .molecules :
803- # Create OpenMM System using OpenMM app
804- openmm_system = openmm_forcefield .createSystem (molecule .to_topology ().to_openmm (), removeCMMotion = False , nonbondedMethod = NoCutoff )
805-
806- # Retrieve System generated by the SMIRNOFF typing engine
807- smirnoff_system = generator .get_openmm_system (molecule )
793+ print (f'Testing energies for { small_molecule_forcefield } ...' )
794+ # Create a generator that knows about a few molecules
795+ # TODO: Should the generator also load the appropriate force field files into the ForceField object?
796+ generator = SMIRNOFFTemplateGenerator (molecules = self .molecules , forcefield = small_molecule_forcefield )
797+ # Create a ForceField
798+ openmm_forcefield = openmm .app .ForceField ()
799+ # Register the template generator
800+ openmm_forcefield .registerTemplateGenerator (generator .generator )
801+ # Parameterize some molecules
802+ for molecule in self .molecules :
803+ # Create OpenMM System using OpenMM app
804+ openmm_system = openmm_forcefield .createSystem (molecule .to_topology ().to_openmm (), removeCMMotion = False , nonbondedMethod = NoCutoff )
808805
809- # Compare energies and forces
810- self . compare_energies (molecule , openmm_system , smirnoff_system )
806+ # Retrieve System generated by the SMIRNOFF typing engine
807+ smirnoff_system = generator . get_openmm_system (molecule )
811808
812- # Run some dynamics
813- molecule = self .propagate_dynamics (molecule , smirnoff_system )
809+ # Compare energies and forces
810+ self .compare_energies (molecule , openmm_system , smirnoff_system )
814811
815- # Compare energies again
816- self .compare_energies (molecule , openmm_system , smirnoff_system )
812+ # Run some dynamics
813+ molecule = self .propagate_dynamics (molecule , smirnoff_system )
817814
815+ # Compare energies again
816+ self .compare_energies (molecule , openmm_system , smirnoff_system )
818817
819- def test_partial_charges_are_none (self ):
818+ @pytest .mark .parametrize ("small_molecule_forcefield" , smirnoff_small_molecule_forcefields ())
819+ def test_partial_charges_are_none (self , small_molecule_forcefield ):
820820 """Test parameterizing a small molecule with `partial_charges=None` instead
821821 of zeros (happens frequently in OFFTK>=0.7.0)"""
822822 molecule = Molecule .from_smiles ('C=O' )
823823 molecule .generate_conformers (n_conformers = 1 )
824824 #molecule._partial_charges = None
825825 assert (molecule .partial_charges is None ) or np .all (molecule .partial_charges / unit .elementary_charge == 0 )
826- # Test all supported SMIRNOFF force fields
827- for small_molecule_forcefield in SMIRNOFFTemplateGenerator .INSTALLED_FORCEFIELDS :
828- if "ff14sb" in small_molecule_forcefield :
829- continue
830- if "tip" in small_molecule_forcefield :
831- continue
832- if "opc" in small_molecule_forcefield :
833- continue
834826
835- print (f'Testing energies for { small_molecule_forcefield } ...' )
836- # Create a generator that knows about a few molecules
837- # TODO: Should the generator also load the appropriate force field files into the ForceField object?
838- generator = SMIRNOFFTemplateGenerator (molecules = [molecule ], forcefield = small_molecule_forcefield )
839- # Create a ForceField
840- openmm_forcefield = openmm .app .ForceField ()
841- # Register the template generator
842- openmm_forcefield .registerTemplateGenerator (generator .generator )
843- # Create OpenMM System using OpenMM app
844- openmm_system = openmm_forcefield .createSystem (molecule .to_topology ().to_openmm (), removeCMMotion = False , nonbondedMethod = NoCutoff )
845- smirnoff_system = generator .get_openmm_system (molecule )
827+ print (f'Testing energies for { small_molecule_forcefield } ...' )
828+ # Create a generator that knows about a few molecules
829+ # TODO: Should the generator also load the appropriate force field files into the ForceField object?
830+ generator = SMIRNOFFTemplateGenerator (molecules = [molecule ], forcefield = small_molecule_forcefield )
831+ # Create a ForceField
832+ openmm_forcefield = openmm .app .ForceField ()
833+ # Register the template generator
834+ openmm_forcefield .registerTemplateGenerator (generator .generator )
835+ # Create OpenMM System using OpenMM app
836+ openmm_system = openmm_forcefield .createSystem (molecule .to_topology ().to_openmm (), removeCMMotion = False , nonbondedMethod = NoCutoff )
837+ smirnoff_system = generator .get_openmm_system (molecule )
846838
847839 def test_version (self ):
848840 """Test version"""
@@ -852,6 +844,9 @@ def test_version(self):
852844 assert generator .smirnoff_filename .endswith (forcefield + '.offxml' )
853845 assert os .path .exists (generator .smirnoff_filename )
854846
847+ @pytest .mark .skip
848+ def test_parameterize (self , small_molecule_forcefield ):
849+ """Redundant inherited test."""
855850
856851class TestEspalomaTemplateGenerator (TestGAFFTemplateGenerator ):
857852 TEMPLATE_GENERATOR = EspalomaTemplateGenerator
0 commit comments