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)
Пример #2
0
    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)