def setUpClass(cls): """ A method that is run before each unit test in this class. """ test_family = 'H_Abstraction' # set-up RMG object rmg = RMG() # load kinetic database and forbidden structures rmg.database = RMGDatabase() path = os.path.join(settings['test_data.directory'], 'testing_database') # kinetics family loading rmg.database.load_kinetics(os.path.join(path, 'kinetics'), kinetics_families=[test_family], reaction_libraries=[]) # load empty forbidden structures to avoid any dependence on forbidden structures # for these tests for family in rmg.database.kinetics.families.values(): family.forbidden = ForbiddenStructures() rmg.database.forbidden_structures = ForbiddenStructures()
def setUpClass(self): """ A method that is run before all unit tests in this class. """ # set-up RMG object self.rmg = RMG() self.rmg.reaction_model = CoreEdgeReactionModel() # load kinetic database and forbidden structures self.rmg.database = RMGDatabase() path = os.path.join(settings['test_data.directory'], 'testing_database') # kinetics family Disproportionation loading self.rmg.database.load_kinetics( os.path.join(path, 'kinetics'), kinetics_families=['H_Abstraction', 'R_Addition_MultipleBond'], reaction_libraries=[]) # load empty forbidden structures for family in self.rmg.database.kinetics.families.values(): family.forbidden = ForbiddenStructures() self.rmg.database.forbidden_structures = ForbiddenStructures()
def setUp(self): self.database = ForbiddenStructures()
class TestForbiddenStructures(unittest.TestCase): def setUp(self): self.database = ForbiddenStructures() def test_forbidden_group(self): """Test that we can load and check a forbidden group.""" test = """ 1 C u2 p0 {2,D} 2 C u0 {1,D} """ self.database.loadEntry( label='test', group=test, ) molecule = Molecule().fromAdjacencyList(""" multiplicity 3 1 C u2 p0 c0 {2,D} 2 C u0 p0 c0 {1,D} {3,S} {4,S} 3 H u0 p0 c0 {2,S} 4 H u0 p0 c0 {2,S} """) self.assertTrue(self.database.isMoleculeForbidden(molecule)) def test_forbidden_molecule(self): """Test that we can load and check a forbidden molecule.""" test = """ 1 C u4 p0 c0 """ self.database.loadEntry( label='test', molecule=test, ) molecule = Molecule().fromAdjacencyList(""" 1 C u4 p0 c0 """) self.assertTrue(self.database.isMoleculeForbidden(molecule)) def test_forbidden_species(self): """Test that we can load and check a forbidden species. This is a hypothetical test, we don't actually forbid benzene.""" test = """ 1 C u0 p0 c0 {2,D} {6,S} {7,S} 2 C u0 p0 c0 {1,D} {3,S} {8,S} 3 C u0 p0 c0 {2,S} {4,D} {9,S} 4 C u0 p0 c0 {3,D} {5,S} {10,S} 5 C u0 p0 c0 {4,S} {6,D} {11,S} 6 C u0 p0 c0 {1,S} {5,D} {12,S} 7 H u0 p0 c0 {1,S} 8 H u0 p0 c0 {2,S} 9 H u0 p0 c0 {3,S} 10 H u0 p0 c0 {4,S} 11 H u0 p0 c0 {5,S} 12 H u0 p0 c0 {6,S} """ self.database.loadEntry( label='test', species=test, ) molecule1 = Molecule().fromAdjacencyList(""" 1 C u0 p0 c0 {2,D} {6,S} {7,S} 2 C u0 p0 c0 {1,D} {3,S} {8,S} 3 C u0 p0 c0 {2,S} {4,D} {9,S} 4 C u0 p0 c0 {3,D} {5,S} {10,S} 5 C u0 p0 c0 {4,S} {6,D} {11,S} 6 C u0 p0 c0 {1,S} {5,D} {12,S} 7 H u0 p0 c0 {1,S} 8 H u0 p0 c0 {2,S} 9 H u0 p0 c0 {3,S} 10 H u0 p0 c0 {4,S} 11 H u0 p0 c0 {5,S} 12 H u0 p0 c0 {6,S} """) molecule2 = Molecule().fromAdjacencyList(""" 1 C u0 p0 c0 {2,B} {6,B} {7,S} 2 C u0 p0 c0 {1,B} {3,B} {8,S} 3 C u0 p0 c0 {2,B} {4,B} {9,S} 4 C u0 p0 c0 {3,B} {5,B} {10,S} 5 C u0 p0 c0 {4,B} {6,B} {11,S} 6 C u0 p0 c0 {1,B} {5,B} {12,S} 7 H u0 p0 c0 {1,S} 8 H u0 p0 c0 {2,S} 9 H u0 p0 c0 {3,S} 10 H u0 p0 c0 {4,S} 11 H u0 p0 c0 {5,S} 12 H u0 p0 c0 {6,S} """) self.assertTrue(self.database.isMoleculeForbidden(molecule1)) self.assertTrue(self.database.isMoleculeForbidden(molecule2))
class RMGDatabase(object): """ The primary class for working with the RMG database. """ def __init__(self): self.thermo = None self.transport = None self.forbidden_structures = None self.kinetics = None self.statmech = None self.solvation = None self.surface = None # Store the newly created database in the module. global database if database is not None: logging.warning( 'An instance of RMGDatabase already exists. Re-initializing it.' ) database = self def load( self, path, thermo_libraries=None, transport_libraries=None, reaction_libraries=None, seed_mechanisms=None, kinetics_families=None, kinetics_depositories=None, statmech_libraries=None, depository=True, solvation=True, surface=True, # on by default, because solvation is also on by default testing=False): """ Load the RMG database from the given `path` on disk, where `path` points to the top-level folder of the RMG database. If none of the optional arguments are provided, then the entire database will be loaded. You can use the optional arguments to specify that only certain components of the database be loaded. Argument testing will load a lighter version of the database used for unit-tests """ if not testing: self.load_transport(os.path.join(path, 'transport'), transport_libraries) self.load_forbidden_structures( os.path.join(path, 'forbiddenStructures.py')) self.load_kinetics(os.path.join(path, 'kinetics'), reaction_libraries, seed_mechanisms, kinetics_families, kinetics_depositories) if not testing: self.load_statmech(os.path.join(path, 'statmech'), statmech_libraries, depository) if solvation: self.load_solvation(os.path.join(path, 'solvation')) if surface: self.load_thermo(os.path.join(path, 'thermo'), thermo_libraries, depository, surface) def load_thermo(self, path, thermo_libraries=None, depository=True, surface=False): """ Load the RMG thermo database from the given `path` on disk, where `path` points to the top-level folder of the RMG thermo database. """ self.thermo = ThermoDatabase() self.thermo.load(path, thermo_libraries, depository, surface) def load_transport(self, path, transport_libraries=None): """ Load the RMG transport database from the given 'path' on disk, where 'path' points to the top-level folder of the RMG transport database. """ self.transport = TransportDatabase() self.transport.load(path, transport_libraries) def load_forbidden_structures(self, path=None): """ Load the RMG forbidden structures from the given `path` on disk, where `path` points to the forbidden structures file. If no path is given, a blank forbidden structures object is created. """ self.forbidden_structures = ForbiddenStructures() if path is not None: self.forbidden_structures.load(path) def load_kinetics(self, path, reaction_libraries=None, seed_mechanisms=None, kinetics_families=None, kinetics_depositories=None): """ Load the RMG kinetics database from the given `path` on disk, where `path` points to the top-level folder of the RMG kinetics database. """ kinetics_libraries = [] library_order = [] if seed_mechanisms is None and reaction_libraries is None: kinetics_libraries = None if seed_mechanisms is not None: for library in seed_mechanisms: kinetics_libraries.append(library) library_order.append((library, 'Seed')) if reaction_libraries is not None: for library in reaction_libraries: kinetics_libraries.append(library) library_order.append((library, 'Reaction Library')) self.kinetics = KineticsDatabase() self.kinetics.library_order = library_order self.kinetics.load(path, families=kinetics_families, libraries=kinetics_libraries, depositories=kinetics_depositories) def load_solvation(self, path): """ Load the RMG solvation database from the given `path` on disk, where `path` points to the top-level folder of the RMG solvation database. """ self.solvation = SolvationDatabase() self.solvation.load(path) def load_surface(self, path): """ Load the RMG metal database from the given `path` on disk, where `path` points to the top-level folder of the RMG surface database. """ self.surface = MetalDatabase() self.surface.load(path) def load_statmech(self, path, statmech_libraries=None, depository=True): """ Load the RMG statmech database from the given `path` on disk, where `path` points to the top-level folder of the RMG statmech database. """ self.statmech = StatmechDatabase() self.statmech.load(path, statmech_libraries, depository) def load_old(self, path): """ Load the old RMG database from the given `path` on disk, where `path` points to the top-level folder of the old RMG database. """ self.thermo = ThermoDatabase() self.thermo.load_old(path) self.transport = TransportDatabase() # self.transport.load_old(path) # Currently no load_old import function available for transport groups self.forbidden_structures = ForbiddenStructures() self.forbidden_structures.load_old( os.path.join(path, 'ForbiddenStructures.txt')) self.kinetics = KineticsDatabase() self.kinetics.load_old(path) self.statmech = StatmechDatabase() self.statmech.load_old(path) self.solvation = SolvationDatabase() # Not completely implemented # self.solvation.load_old(path) def save(self, path): """ Save the RMG database to the given `path` on disk. """ if not os.path.exists(path): os.makedirs(path) self.forbidden_structures.save( os.path.join(path, 'forbiddenStructures.py')) self.thermo.save(os.path.join(path, 'thermo')) # self.transport.save(os.path.join(path, 'transport')) #Currently no function for saving transport groups self.kinetics.save(os.path.join(path, 'kinetics')) self.statmech.save(os.path.join(path, 'statmech')) self.solvation.save(os.path.join(path, 'solvation')) self.transport.save(os.path.join(path, 'transport')) def save_old(self, path): """ Save the old RMG database to the given `path` on disk. """ if not os.path.exists(path): os.makedirs(path) self.thermo.save_old(path) self.transport.save_old(path) self.forbidden_structures.save_old( os.path.join(path, 'ForbiddenStructures.txt')) self.kinetics.save_old(path) self.statmech.save_old(path)