def test_get_num_fragments(self): molecule = Molecule() # get_num_fragments() should return 0 before any fragments added to molecule self.assertEqual(molecule.get_num_fragments(), 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 fragment added to molecule self.assertEqual(molecule.get_num_fragments(), 1) fragment1 = Fragment(3, 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 2 after 2 fragment added to molecule self.assertEqual(molecule.get_num_fragments(), 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)