Exemplo n.º 1
0
    def call_qcengine(
        self,
        molecule: Ligand,
        extras: Optional[Dict[str, str]] = None,
    ) -> qcel.models.AtomicResult:
        """
        Calculate the requested property using qcengine for the given molecule.

        Args:
            molecule: The QUBEKit ligand that the calculation should be ran on.
            extras: Any extra calculation keywords that are program specific.

        Returns:
            The full qcelemental atomic result so any required information can be extracted.
        """
        qc_mol = molecule.to_qcschema()
        # default keywords
        keywords = {
            "scf_type": "df",
            # make sure we always use an ultrafine grid
            "dft_spherical_points": 590,
            "dft_radial_points": 99,
        }
        if extras is not None:
            keywords.update(extras)
        task = qcel.models.AtomicInput(
            molecule=qc_mol,
            driver=self.driver,
            model=self.qc_model,
            keywords=keywords,
        )

        result = qcng.compute(task,
                              self.program,
                              local_options=self.local_options)

        return result
Exemplo n.º 2
0
    def optimise(
        self,
        molecule: Ligand,
        allow_fail: bool = False,
        return_result: bool = False,
        extras: Optional[Dict[str, Any]] = None,
    ) -> Tuple[Ligand, Optional[qcel.models.OptimizationResult]]:
        """
        For the given specification in the class run an optimisation on the ligand.

        Run the specified optimisation on the ligand the final coordinates are extracted and stored in the ligand.
        The optimisation schema is dumped to file along with the optimised geometry and the trajectory.

        Args:
            molecule:
                The molecule which should be optimised
            allow_fail:
                If we should not raise an error if the molecule fails to be optimised, this will extract the last geometry
                from the trajectory and return it.
            return_result:
                If the full result json should also be returned useful for extracting the trajectory.
            extras:
                A dictionary of extras that should be used to update the optimiser keywords.

        Returns:
            A new copy of the molecule at the optimised coordinates.
        """
        # first validate the settings
        self._validate_specification()
        # now validate that the programs are installed
        self.check_available(program=self.program, optimiser=self.optimiser)

        # now we need to distribute the job
        model = self.qc_model
        specification = qcel.models.procedures.QCInputSpecification(
            model=model, keywords={"dft_spherical_points": 590, "dft_radial_points": 99}
        )
        initial_mol = molecule.to_qcschema()
        optimiser_keywords = self.build_optimiser_keywords()
        if extras is not None:
            optimiser_keywords.update(extras)
        opt_task = qcel.models.OptimizationInput(
            initial_molecule=initial_mol,
            input_specification=specification,
            keywords=optimiser_keywords,
        )
        opt_result = qcng.compute_procedure(
            input_data=opt_task,
            procedure=self.optimiser,
            raise_error=False,
            local_options=self.local_options,
        )
        # dump info to file
        result_mol = self.handle_output(molecule=molecule, opt_output=opt_result)
        # check if we can/have failed and raise the error
        if not opt_result.success and not allow_fail:
            raise RuntimeError(
                f"{opt_result.error.error_type}: {opt_result.error.error_message}"
            )

        full_result = opt_result if return_result else None
        return result_mol, full_result