def test_get_atoms(self): molecule = Molecule() # get_atoms() should return list of len 0 before any atoms added to Molecule self.assertEqual(len(molecule.get_atoms()), 0) fragment0 = Fragment(0, 1) atom0 = Atom("H", 0, 0, 0) fragment0.add_atom(atom0) molecule.add_fragment(fragment0) self.assertEqual(molecule.get_atoms()[0], atom0) # get_atoms() should return list of len 1 after 1 atom added to Molecule self.assertEqual(len(molecule.get_atoms()), 1) fragment1 = Fragment(0, 1) atom1 = Atom("H", 0, 0, 0) atom2 = Atom("He", 234, -0.1, 32) atom3 = Atom("He", 34, 43.53, 0) fragment1.add_atom(atom1) fragment1.add_atom(atom2) fragment1.add_atom(atom3) molecule.add_fragment(fragment1) self.assertEqual(molecule.get_atoms()[0], atom0) self.assertEqual(molecule.get_atoms()[1], atom1) self.assertEqual(molecule.get_atoms()[2], atom2) self.assertEqual(molecule.get_atoms()[3], atom3) # get_atoms() should return list of len 4 after 4 atoms added to molecule self.assertEqual(len(molecule.get_atoms()), 4)
def test_get_num_atoms(self): molecule = Molecule() # get_num_atoms() should return 0 before any atoms added to molecule self.assertEqual(molecule.get_num_atoms(), 0) fragment0 = Fragment(-1, 2) atom0 = Atom("F", 0, 0, 0) fragment0.add_atom(atom0) molecule.add_fragment(fragment0) # get_num_fragments() should return 1 after 1 atom added to molecule self.assertEqual(molecule.get_num_atoms(), 1) fragment1 = Fragment(-1, 2) atom1 = Atom("F", 0, 0, 3) atom2 = Atom("Cl", 0, 0, 0) fragment1.add_atom(atom1) fragment1.add_atom(atom2) molecule.add_fragment(fragment1) # get_num_fragments() should return 3 after 3 atoms added to molecule self.assertEqual(molecule.get_num_atoms(), 3)
def test_add_fragment_and_get_fragments(self): molecule = Molecule() # get_fragments() should return list of len 0 before any fragments added to Molecule self.assertEqual(len(molecule.get_fragments()), 0) fragment0 = Fragment(-3, 2) atom0 = Atom("H", 0, 0, 0) fragment0.add_atom(atom0) molecule.add_fragment(fragment0) self.assertEqual(molecule.get_fragments()[0], fragment0) # get_fragments() should return list of len 1 after 1 fragment added to Molecule self.assertEqual(len(molecule.get_fragments()), 1) fragment1 = Fragment(1, 1) atom1 = Atom("H", 0, 0, 0) atom2 = Atom("He", 234, -0.1, 32) atom3 = Atom("He", 34, 43.53, 0) fragment1.add_atom(atom1) fragment1.add_atom(atom2) fragment1.add_atom(atom3) molecule.add_fragment(fragment1) self.assertEqual(molecule.get_fragments()[0], fragment0) self.assertEqual(molecule.get_fragments()[1], fragment1) # get_fragments() should return list of len 2 after 2 fragments added to Molecule self.assertEqual(len(molecule.get_fragments()), 2)
def get_optimized_energies(self, method, basis, cp, tag): """ Returns a list of pairs of [molecule, energies] where energies is an array of the form [E0, ...] of molecules in the database with the given method, basis, cp and tag and optimized geometries % can be used as a wildcard to stand in for any method, basis, cp, or tag. Args: method - retrieve only energies computed with this method basis - retrieve only energies computed with this basis cp - retrieve only energies computed with this coutnerpoise correction tag - retrieve only energies with this tag Returns: a generator of [molecule, [E0, E1, E2, E01, ...]] pairs from the calculated energies in this database using the given model and tag of optimized geometries """ # get a list of all calculations that have the appropriate method, basis, and cp calculation_ids = [ elements[0] for elements in self.cursor.execute( "SELECT ROWID FROM Calculations WHERE model_id=(SELECT ROWID FROM Models WHERE method LIKE ? AND basis LIKE ? AND cp LIKE ? AND tag LIKE ? AND optimized=?)", (method, basis, cp, tag, 1)).fetchall() ] for calculation_id in calculation_ids: # get the molecule id corresponding to this calculation molecule_id = self.cursor.execute( "SELECT molecule_id FROM Calculations WHERE ROWID=?", (calculation_id, )).fetchone()[0] # Reconstruct the molecule from the information in this database molecule = Molecule() # loop over all rows in the Fragments table that correspond to this molecule for fragment_id, charge, spin in self.cursor.execute( "SELECT ROWID, charge, spin FROM Fragments WHERE molecule_id=?", (molecule_id, )).fetchall(): fragment = Fragment(charge, spin) # loop over all rows in the Atoms table that correspond to this fragment for symbol, x, y, z in self.cursor.execute( "SELECT symbol, x, y, z FROM Atoms WHERE fragment_id=?", (fragment_id, )).fetchall(): fragment.add_atom(Atom(symbol, x, y, z)) molecule.add_fragment(fragment) # get the energies corresponding to this calculation energies = [ energy_index_value_pair[1] for energy_index_value_pair in sorted( self.cursor.execute( "SELECT energy_index, energy FROM Energies WHERE calculation_id=?", (calculation_id, )).fetchall()) ] yield molecule, energies
def test_get_num_atoms(self): fragment = Fragment(3, 2) # get_num_atoms() should return 0 before any Atoms added to Fragment self.assertEqual(fragment.get_num_atoms(), 0) fragment.add_atom(Atom("H", 0, 0, 0)) # get_num_atoms() should return 1 after single atom added to Fragment self.assertEqual(fragment.get_num_atoms(), 1) fragment.add_atom(Atom("Al", 0, 0, 0)) # get_num_atoms() should return 2 after second atom added to Fragment self.assertEqual(fragment.get_num_atoms(), 2) fragment.add_atom(Atom("He", 0, 0, 0)) # get_num_atoms() should return 3 after third atom added to Fragment self.assertEqual(fragment.get_num_atoms(), 3)
def test_to_standard_xyz(self): molecule = Molecule() fragment0 = Fragment(-1, 1) fragment0.add_atom(Atom("H", 5, 3, 0.00343)) fragment0.add_atom(Atom("Cl", 2, 0, -13)) fragment0.add_atom(Atom("He", 6, 2, 0.343)) molecule.add_fragment(fragment0) self.assertEqual(molecule.to_xyz(), fragment0.to_xyz()[:-1]) fragment1 = Fragment(-2, 1) fragment1.add_atom(Atom("Ar", 0.23430523424, -34, -234.5235)) molecule.add_fragment(fragment1) self.assertEqual(molecule.to_xyz(), fragment1.to_xyz() + fragment0.to_xyz()[:-1]) fragment2 = Fragment(0, 2) fragment2.add_atom(Atom("Xe", 0, 0, 0)) fragment2.add_atom(Atom("Br", 62, 5, 0.001)) molecule.add_fragment(fragment2) self.assertEqual( molecule.to_xyz(), fragment1.to_xyz() + fragment2.to_xyz() + fragment0.to_xyz()[:-1])
def test_add_atom_and_get_atoms(self): fragment = Fragment(0, 1) # get_atom() should return list of length 0 before any atoms added to fragment self.assertEqual(len(fragment.get_atoms()), 0) atom0 = Atom("H", 0, 0, 0) fragment.add_atom(atom0) self.assertEqual(fragment.get_atoms()[0], atom0) # get_atom() should return list of length 1 after 1 atom added to fragment self.assertEqual(len(fragment.get_atoms()), 1) atom1 = Atom("Cl", 400, 32, 23) fragment.add_atom(atom1) self.assertEqual(fragment.get_atoms()[0], atom1) self.assertEqual(fragment.get_atoms()[1], atom0) # get_atom() should return list of length 2 after 2 atoms added to fragment self.assertEqual(len(fragment.get_atoms()), 2)
def get_missing_energy(self): """ Returns a single Calculation object, which contains the info a user needs to calculate an energy missing in the table. The user should calculate the energy, then call either set_energy() or set_failed() Args: None Returns: A Calculation object describing the calculation to be performed """ # retrieve a pending job from the Jobs table try: job_id = self.cursor.execute( "SELECT ROWID FROM Jobs WHERE status=?", ("pending", )).fetchone()[0] except TypeError: # this error will be thrown if there are no more energies to calculate, because None[0] throws a TypeError return None # retrieve the calculation and energy to be calculated for this job from the Energies table calculation_id, energy_index = self.cursor.execute( "SELECT calculation_id, energy_index FROM Energies WHERE job_id=?", (job_id, )).fetchone() # retrieve the molecule and model from the Calculations table molecule_id, model_id, tag, optimized = self.cursor.execute( "SELECT molecule_id, model_id, tag, optimized FROM Calculations WHERE ROWID=?", (calculation_id, )).fetchone() # retrieve the method, basis, and cp for this model method, basis, cp = self.cursor.execute( "SELECT method, basis, cp FROM Models WHERE ROWID=?", (model_id, )).fetchone() # Reconstruct the molecule from the information in this database molecule = Molecule() # loop over all rows in the Fragments table that correspond to this molecule for fragment_id, charge, spin in self.cursor.execute( "SELECT ROWID, charge, spin FROM Fragments WHERE molecule_id=?", (molecule_id, )).fetchall(): fragment = Fragment(charge, spin) # loop over all rows in the Atoms table that correspond to this fragment for symbol, x, y, z in self.cursor.execute( "SELECT symbol, x, y, z FROM Atoms WHERE fragment_id=?", (fragment_id, )).fetchall(): fragment.add_atom(Atom(symbol, x, y, z)) molecule.add_fragment(fragment) # get the indicies of the fragments to include in this calculation fragment_indicies = energy_index_to_fragment_indicies( energy_index, molecule.get_num_fragments()) # update the job with its start date and running status self.cursor.execute( "UPDATE Jobs SET status=?, start_date=? WHERE ROWID=?", ("running", datetime.datetime.today().strftime('%Y/%m/%d'), job_id)) return Calculation(molecule, method, basis, True if cp == 1 else False, fragment_indicies, job_id)
def test_to_xyz(self): atom = Atom("H", 0, 0, 0) self.assertEqual( atom.to_xyz(), "H 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00" ) atom = Atom("Ar", 0.34234, -0.342, 1.2334) self.assertEqual( atom.to_xyz(), "Ar 3.42340000000000e-01 -3.42000000000000e-01 1.23340000000000e+00" ) atom = Atom("He", 12.34, 105.34, -0.00432) self.assertEqual( atom.to_xyz(), "He 1.23400000000000e+01 1.05340000000000e+02 -4.32000000000000e-03" ) atom = Atom("C", -2523452, 0.0003453, 34534) self.assertEqual( atom.to_xyz(), "C -2.52345200000000e+06 3.45300000000000e-04 3.45340000000000e+04" ) atom = Atom("Cl", 0.00000000000068, 0.74576456847823583, 34534262462472457756745) self.assertEqual( atom.to_xyz(), "Cl 6.80000000000000e-13 7.45764568478236e-01 3.45342624624725e+22" )
def test_to_xyz(self): fragment = Fragment(-2, 2) # to_xyz() should return empty string when no atoms are added to fragment self.assertEqual(fragment.to_xyz(), "") atom0 = Atom("H", 0, 0, 0) fragment.add_atom(atom0) # to_xyz() should return string of first atom after only 1 atom added self.assertEqual(fragment.to_xyz(), atom0.to_xyz() + "\n") atom1 = Atom("Cl", 5, 7, -3) fragment.add_atom(atom1) # to_xyz() should return string of 2 atoms after 2nd atom added self.assertEqual(fragment.to_xyz(), atom1.to_xyz() + "\n" + atom0.to_xyz() + "\n") atom2 = Atom("Xe", 10.234235, -0.00000234, 2.353523) fragment.add_atom(atom2) # to_xyz() should return string of 3 atoms after only 3rd atom added self.assertEqual( fragment.to_xyz(), atom1.to_xyz() + "\n" + atom0.to_xyz() + "\n" + atom2.to_xyz() + "\n")
def test_get_name(self): atom = Atom("H", 0, 0, 0) self.assertEqual(atom.get_name(), "H") atom = Atom("Cl", 0, 0, 0) self.assertEqual(atom.get_name(), "Cl") atom = Atom("He", 0, 0, 0) self.assertEqual(atom.get_name(), "He") atom = Atom("Ar", 0, 0, 0) self.assertEqual(atom.get_name(), "Ar")