Ejemplo n.º 1
0
 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)
Ejemplo n.º 2
0
class TestTransportDatabase(unittest.TestCase):
    """
    Contains unit test of the :class: 'TransportDatabase' class
    """

    def setUp(self):
        """
        a function run before each unit test in this class
        """
        self.libraries = ['GRI-Mech', 'PrimaryTransportLibrary']
        self.groups = ['ring', 'nonring']
        self.libraryOrder = []

        path = os.path.join(settings['database.directory'], 'transport')
        self.transportdb = TransportDatabase()
        self.transportdb.load(path, self.libraries)

    def testJoback(self):
        #values calculate from joback's estimations
        self.testCases = [
            ['acetone', 'CC(=O)C', Length(5.36421, 'angstroms'), Energy(3.20446, 'kJ/mol'), "Epsilon & sigma estimated with Tc=500.53 K, Pc=47.11 bar (from Joback method)"],
            ['cyclopenta-1,2-diene', 'C1=C=CCC1', None, None, None],  # not sure what to expect, we just want to make sure it doesn't crash
            ['benzene', 'c1ccccc1', None, None, None],
            ]
        for name, smiles, sigma, epsilon, comment in self.testCases:
            molecule=Molecule(SMILES=smiles)
            species = Species(molecule=[molecule])
            transportData, blank, blank2 = self.transportdb.getTransportPropertiesViaGroupEstimates(species)
            # check Joback worked.
            # If we don't know what to expect, don't check (just make sure we didn't crash)
            if comment:
                self.assertTrue(transportData.comment == comment)
            if sigma:
                self.assertAlmostEqual(transportData.sigma.value_si * 1e10, sigma.value_si * 1e10, 4)
            if epsilon:
                self.assertAlmostEqual(transportData.epsilon.value_si, epsilon.value_si, 1)

    def testJobackOnBenzeneBonds(self):
        "Test Joback doesn't crash on Cb desription of beneze"
        adjlist = """
                    1  C u0 p0 {2,D} {6,S} {7,S}
                    2  C u0 p0 {1,D} {3,S} {8,S}
                    3  C u0 p0 {2,S} {4,D} {9,S}
                    4  C u0 p0 {3,D} {5,S} {10,S}
                    5  C u0 p0 {4,S} {6,D} {11,S}
                    6  C u0 p0 {1,S} {5,D} {12,S}
                    7  H u0 p0 {1,S}
                    8  H u0 p0 {2,S}
                    9  H u0 p0 {3,S}
                    10 H u0 p0 {4,S}
                    11 H u0 p0 {5,S}
                    12 H u0 p0 {6,S}
                    """
        m = Molecule().fromAdjacencyList(adjlist)
        species = Species(molecule=[m])
        transportData, blank, blank2 = self.transportdb.getTransportPropertiesViaGroupEstimates(species)
        self.assertIsNotNone(transportData)
Ejemplo n.º 3
0
    def setUp(self):
        """
        a function run before each unit test in this class
        """
        self.libraries = ['GRI-Mech', 'PrimaryTransportLibrary']
        self.groups = ['ring', 'nonring']
        self.libraryOrder = []

        path = os.path.join(settings['database.directory'], 'transport')
        self.transportdb = TransportDatabase()
        self.transportdb.load(path, self.libraries)
Ejemplo n.º 4
0
    def setUpClass(self):
        """A function that is run ONCE before all unit tests in this class."""
        self.database = TransportDatabase()
        self.database.load(os.path.join(settings['database.directory'], 'transport'),
                           ['GRI-Mech', 'PrimaryTransportLibrary'])

        self.speciesList = [
            Species().from_smiles('C'),
            Species().from_smiles('CCCC'),
            Species().from_smiles('O'),
            Species().from_smiles('[CH3]'),
            Species().from_smiles('[OH]'),
            Species().from_smiles('c1ccccc1'),
        ]
Ejemplo n.º 5
0
 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()
def main(dictionary):

    database = TransportDatabase()
    database.load(path=os.path.join(settings['database.directory'],
                                    'transport'),
                  libraries=None)

    speciesDict = loadSpeciesDictionary(dictionary)

    path = 'tran.dat'

    with open(path, 'w') as f:
        f.write("! {0:15} {1:8} {2:9} {3:9} {4:9} {5:9} {6:9} {7:9}\n".format(
            'Species', 'Shape', 'LJ-depth', 'LJ-diam', 'DiplMom', 'Polzblty',
            'RotRelaxNum', 'Data'))
        f.write("! {0:15} {1:8} {2:9} {3:9} {4:9} {5:9} {6:9} {7:9}\n".format(
            'Name', 'Index', 'epsilon/k_B', 'sigma', 'mu', 'alpha', 'Zrot',
            'Source'))
        for label, spec in speciesDict.iteritems():
            transportDataList = database.getAllTransportProperties(spec)
            for transportData, _, _ in transportDataList:
                if (not transportData):
                    missingData = True
                else:
                    missingData = False

                if missingData:
                    f.write('! {0:19s} {1!r}\n'.format(label, transportData))
                else:
                    f.write(
                        '{0:19} {1:d}   {2:9.3f} {3:9.3f} {4:9.3f} {5:9.3f} {6:9.3f}    ! {7:s}\n'
                        .format(
                            label,
                            transportData.shapeIndex,
                            transportData.epsilon.value_si / constants.R,
                            transportData.sigma.value_si * 1e10,
                            (transportData.dipoleMoment.value_si *
                             constants.c *
                             1e21 if transportData.dipoleMoment else 0),
                            (transportData.polarizability.value_si *
                             1e30 if transportData.polarizability else 0),
                            (transportData.rotrelaxcollnum
                             if transportData.rotrelaxcollnum else 0),
                            transportData.comment,
                        ))
Ejemplo n.º 7
0
 def __init__(self):
     self.database = RMGDatabase()
     self.database.kinetics = KineticsDatabase()
     self.database.thermo = ThermoDatabase()
     self.database.transport = TransportDatabase()
     self.database.statmech = StatmechDatabase()
     self.database.solvation = SolvationDatabase()
     self.database.load_forbidden_structures(
         os.path.join(rmgweb.settings.DATABASE_PATH,
                      'forbiddenStructures.py'))
     self.timestamps = {}
Ejemplo n.º 8
0
    def setUpClass(self):
        """A function that is run ONCE before all unit tests in this class."""
        self.database = TransportDatabase()
        self.database.load(os.path.join(settings['database.directory'], 'transport'),
                           ['GRI-Mech', 'PrimaryTransportLibrary'])

        self.speciesList = [
            Species().fromSMILES('C'),
            Species().fromSMILES('CCCC'),
            Species().fromSMILES('O'),
            Species().fromSMILES('[CH3]'),
            Species().fromSMILES('[OH]'),
            Species().fromSMILES('c1ccccc1'),
        ]
Ejemplo n.º 9
0
def loadNecessaryDatabases():
    """
    loads transport and statmech databases
    """
    from rmgpy.data.statmech import StatmechDatabase
    from rmgpy.data.transport import TransportDatabase

    #only load if they are not there already.
    try:
        getDB('transport')
        getDB('statmech')
    except DatabaseError:
        logging.info("Databases not found. Making databases")
        db = RMGDatabase()
        db.statmech = StatmechDatabase()
        db.statmech.load(os.path.join(settings['database.directory'],'statmech'))

        db.transport = TransportDatabase()
        db.transport.load(os.path.join(settings['database.directory'],'transport'))
Ejemplo n.º 10
0
class TestTransportDatabase(unittest.TestCase):
    """
    Contains unit tests of the :class:`TransportDatabase` class.
    """
    @classmethod
    def setUpClass(self):
        """A function that is run ONCE before all unit tests in this class."""
        self.database = TransportDatabase()
        self.database.load(os.path.join(settings['database.directory'], 'transport'),
                           ['GRI-Mech', 'PrimaryTransportLibrary'])

        self.speciesList = [
            Species().fromSMILES('C'),
            Species().fromSMILES('CCCC'),
            Species().fromSMILES('O'),
            Species().fromSMILES('[CH3]'),
            Species().fromSMILES('[OH]'),
            Species().fromSMILES('c1ccccc1'),
        ]

    def testJoback(self):
        """Test transport property estimation via Joback groups."""
        self.testCases = [
            ['acetone', 'CC(=O)C', Length(5.36421, 'angstroms'), Energy(3.20446, 'kJ/mol'), "Epsilon & sigma estimated with Tc=500.53 K, Pc=47.11 bar (from Joback method)"],
            ['cyclopenta-1,2-diene', 'C1=C=CCC1', None, None, None],  # not sure what to expect, we just want to make sure it doesn't crash
            ['benzene', 'c1ccccc1', None, None, None],
            ]

        #values calculate from joback's estimations
        for name, smiles, sigma, epsilon, comment in self.testCases:
            species = Species().fromSMILES(smiles)
            transportData, blank, blank2 = self.database.getTransportPropertiesViaGroupEstimates(species)
            # check Joback worked.
            # If we don't know what to expect, don't check (just make sure we didn't crash)
            if comment:
                self.assertTrue(transportData.comment == comment)
            if sigma:
                self.assertAlmostEqual(transportData.sigma.value_si * 1e10, sigma.value_si * 1e10, 4)
            if epsilon:
                self.assertAlmostEqual(transportData.epsilon.value_si, epsilon.value_si, 1)

    @work_in_progress
    def testJobackOnBenzeneBonds(self):
        """Test Joback doesn't crash on Cb desription of benzene"""
        species = Species().fromAdjacencyList("""
                                              1  C u0 p0 {2,B} {6,B} {7,S}
                                              2  C u0 p0 {1,B} {3,B} {8,S}
                                              3  C u0 p0 {2,B} {4,B} {9,S}
                                              4  C u0 p0 {3,B} {5,B} {10,S}
                                              5  C u0 p0 {4,B} {6,B} {11,S}
                                              6  C u0 p0 {1,B} {5,B} {12,S}
                                              7  H u0 p0 {1,S}
                                              8  H u0 p0 {2,S}
                                              9  H u0 p0 {3,S}
                                              10 H u0 p0 {4,S}
                                              11 H u0 p0 {5,S}
                                              12 H u0 p0 {6,S}
                                              """)
        transportData, blank, blank2 = self.database.getTransportPropertiesViaGroupEstimates(species)
        self.assertIsNotNone(transportData)

    def testGetTransportProperties(self):
        """Test that we can retrieve best transport properties for a species."""

        for species in self.speciesList:
            transport = self.database.getTransportProperties(species)
            self.assertIsNotNone(transport)
            self.assertTrue(isinstance(transport, tuple))
            self.assertTrue(isinstance(transport[0], TransportData))

    def testGetAllTransportProperties(self):
        """Test that we can retrieve transport properties from all sources for a species.

        Used for transport search on website."""

        for species in self.speciesList:
            transport = self.database.getAllTransportProperties(species)
            self.assertIsNotNone(transport)
            for result in transport:
                self.assertTrue(isinstance(result, tuple))
                self.assertTrue(isinstance(result[0], TransportData))
Ejemplo n.º 11
0
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)
Ejemplo n.º 12
0
def loadDatabase(component='', section=''):
    """
    Load the requested `component` of the RMG database if modified since last loaded.
    """
    global database
    if not database:
        database = RMGDatabase()
        database.solvation = SolvationDatabase()
        database.thermo = ThermoDatabase()
        database.kinetics = KineticsDatabase()
        database.transport = TransportDatabase()
        database.statmech = StatmechDatabase()
        database.loadForbiddenStructures(
            os.path.join(rmgweb.settings.DATABASE_PATH,
                         'forbiddenStructures.py'))

    if component == 'initialize':
        return database
    if component in ['thermo', '']:
        if section in ['depository', '']:
            dirpath = os.path.join(rmgweb.settings.DATABASE_PATH, 'thermo',
                                   'depository')
            if isDirModified(dirpath):
                database.thermo.loadDepository(dirpath)
                resetDirTimestamps(dirpath)
        if section in ['libraries', '']:
            dirpath = os.path.join(rmgweb.settings.DATABASE_PATH, 'thermo',
                                   'libraries')
            if isDirModified(dirpath):
                database.thermo.loadLibraries(dirpath)
                # put them in our preferred order, so that when we look up thermo in order to estimate kinetics,
                # we use our favorite values first.
                preferred_order = [
                    'primaryThermoLibrary', 'DFT_QCI_thermo', 'GRI-Mech3.0',
                    'CBS_QB3_1dHR', 'KlippensteinH2O2'
                ]
                new_order = [
                    i for i in preferred_order
                    if i in database.thermo.libraryOrder
                ]
                for i in database.thermo.libraryOrder:
                    if i not in new_order: new_order.append(i)
                database.thermo.libraryOrder = new_order
                resetDirTimestamps(dirpath)
        if section in ['groups', '']:
            dirpath = os.path.join(rmgweb.settings.DATABASE_PATH, 'thermo',
                                   'groups')
            if isDirModified(dirpath):
                database.thermo.loadGroups(dirpath)
                resetDirTimestamps(dirpath)

    if component in ['transport', '']:
        if section in ['libraries', '']:
            dirpath = os.path.join(rmgweb.settings.DATABASE_PATH, 'transport',
                                   'libraries')
            if isDirModified(dirpath):
                database.transport.loadLibraries(dirpath)
                resetDirTimestamps(dirpath)
        if section in ['groups', '']:
            dirpath = os.path.join(rmgweb.settings.DATABASE_PATH, 'transport',
                                   'groups')
            if isDirModified(dirpath):
                database.transport.loadGroups(dirpath)
                resetDirTimestamps(dirpath)

    if component in ['solvation', '']:
        dirpath = os.path.join(rmgweb.settings.DATABASE_PATH, 'solvation')
        if isDirModified(dirpath):
            database.solvation.load(dirpath)
            resetDirTimestamps(dirpath)

    if component in ['kinetics', '']:
        if section in ['libraries', '']:
            dirpath = os.path.join(rmgweb.settings.DATABASE_PATH, 'kinetics',
                                   'libraries')
            if isDirModified(dirpath):
                database.kinetics.loadLibraries(dirpath)
                resetDirTimestamps(dirpath)
        if section in ['families', '']:
            dirpath = os.path.join(rmgweb.settings.DATABASE_PATH, 'kinetics',
                                   'families')
            if isDirModified(dirpath):
                database.kinetics.loadFamilies(dirpath,
                                               families='all',
                                               depositories='all')
                resetDirTimestamps(dirpath)

                # Make sure to load the entire thermo database prior to adding training values to the rules
                loadDatabase('thermo', '')
                for family in database.kinetics.families.values():
                    oldentries = len(family.rules.entries)
                    family.addKineticsRulesFromTrainingSet(
                        thermoDatabase=database.thermo)
                    newentries = len(family.rules.entries)
                    if newentries != oldentries:
                        print '{0} new entries added to {1} family after adding rules from training set.'.format(
                            newentries - oldentries, family.label)
                    # Filling in rate rules in kinetics families by averaging...
                    family.fillKineticsRulesByAveragingUp()

    if component in ['statmech', '']:
        dirpath = os.path.join(rmgweb.settings.DATABASE_PATH, 'statmech')
        if isDirModified(dirpath):
            database.statmech.load(dirpath)
            resetDirTimestamps(dirpath)

    return database
Ejemplo n.º 13
0
class TestTransportDatabase(unittest.TestCase):
    """
    Contains unit tests of the :class:`TransportDatabase` class.
    """

    @classmethod
    def setUpClass(self):
        """A function that is run ONCE before all unit tests in this class."""
        self.database = TransportDatabase()
        self.database.load(os.path.join(settings['database.directory'], 'transport'),
                           ['GRI-Mech', 'PrimaryTransportLibrary'])

        self.speciesList = [
            Species().from_smiles('C'),
            Species().from_smiles('CCCC'),
            Species().from_smiles('O'),
            Species().from_smiles('[CH3]'),
            Species().from_smiles('[OH]'),
            Species().from_smiles('c1ccccc1'),
        ]

    def test_joback(self):
        """Test transport property estimation via Joback groups."""
        self.testCases = [
            ['acetone', 'CC(=O)C', Length(5.36421, 'angstroms'), Energy(3.20446, 'kJ/mol'), "Epsilon & sigma estimated with Tc=500.53 K, Pc=47.11 bar (from Joback method)"],
            ['cyclopenta-1,2-diene', 'C1=C=CCC1', None, None, None],  # not sure what to expect, we just want to make sure it doesn't crash
            ['benzene', 'c1ccccc1', None, None, None],
        ]

        # values calculate from joback's estimations
        for name, smiles, sigma, epsilon, comment in self.testCases:
            species = Species().from_smiles(smiles)
            transport_data, blank, blank2 = self.database.get_transport_properties_via_group_estimates(species)
            # check Joback worked.
            # If we don't know what to expect, don't check (just make sure we didn't crash)
            if comment:
                self.assertTrue(transport_data.comment == comment)
            if sigma:
                self.assertAlmostEqual(transport_data.sigma.value_si * 1e10, sigma.value_si * 1e10, 4)
            if epsilon:
                self.assertAlmostEqual(transport_data.epsilon.value_si, epsilon.value_si, 1)

    @work_in_progress
    def test_joback_on_benzene_bonds(self):
        """Test Joback doesn't crash on Cb desription of benzene"""
        species = Species().from_adjacency_list("""
                                              1  C u0 p0 {2,B} {6,B} {7,S}
                                              2  C u0 p0 {1,B} {3,B} {8,S}
                                              3  C u0 p0 {2,B} {4,B} {9,S}
                                              4  C u0 p0 {3,B} {5,B} {10,S}
                                              5  C u0 p0 {4,B} {6,B} {11,S}
                                              6  C u0 p0 {1,B} {5,B} {12,S}
                                              7  H u0 p0 {1,S}
                                              8  H u0 p0 {2,S}
                                              9  H u0 p0 {3,S}
                                              10 H u0 p0 {4,S}
                                              11 H u0 p0 {5,S}
                                              12 H u0 p0 {6,S}
                                              """)
        transport_data, blank, blank2 = self.database.get_transport_properties_via_group_estimates(species)
        self.assertIsNotNone(transport_data)

    def test_get_transport_properties(self):
        """Test that we can retrieve best transport properties for a species."""

        for species in self.speciesList:
            transport = self.database.get_transport_properties(species)
            self.assertIsNotNone(transport)
            self.assertTrue(isinstance(transport, tuple))
            self.assertTrue(isinstance(transport[0], TransportData))

    def test_get_all_transport_properties(self):
        """Test that we can retrieve transport properties from all sources for a species.

        Used for transport search on website."""

        for species in self.speciesList:
            transport = self.database.get_all_transport_properties(species)
            self.assertIsNotNone(transport)
            for result in transport:
                self.assertTrue(isinstance(result, tuple))
                self.assertTrue(isinstance(result[0], TransportData))