Beispiel #1
0
def run_two_stage_resp(
        esp_data: EspData,
        respin1: Respin,
        respin2: Respin,
        initial_charges: Optional[List[Charge]] = None,
        generate_esout: bool = False,
        save_intermediates_to: Optional[str] = None) -> List[Charge]:
    """Apply the two-stage procedure to fit RESP charges

    This function takes the two "respin" files, as this is the simplest way to
    provide information about equivalence as well as methyl and methylene groups.
    Another interface is possible where this information is provided directly
    and may be provided in the future.

    Parameters
    ----------
    esp_data : EspData
        See `run_resp` function parameter
    respin1 : Respin
        Instructions for 1st stage RESP fitting.
    respin2 : Respin
        Instructions for 2nd stage RESP fitting.
    initial_charges : Optional[typing.List[Charge]], optional
        See `run_resp` function parameter
    generate_esout : bool, optional
        See `run_resp` function parameter
    save_intermediates_to : Optional[str], optional
        See `run_resp` function parameter

    Returns
    -------
    typing.List[Charge]
        The fitted two-stage RESP charges.
    """
    # Some verification of respin file compatibility should be performed.
    total_charge = respin1.charge
    molecule = respin1.molecule

    get_calc_dir: Callable[[int], Optional[str]] = lambda stage: (
        f"{save_intermediates_to}/stage_{stage}"
        if save_intermediates_to is not None else None)

    respin1_generated = prepare_respin(
        RespStage1RespinGenerator(respin1.ivary),
        total_charge,
        molecule,
        read_charges=initial_charges is not None)

    resp1_charges = run_resp(esp_data, respin1, initial_charges,
                             generate_esout, get_calc_dir(1))

    respin2_generated = prepare_respin(RespStage2RespinGenerator(
        respin2.ivary),
                                       total_charge,
                                       molecule,
                                       read_charges=True)

    return run_resp(esp_data, respin2, resp1_charges, generate_esout,
                    get_calc_dir(2))
Beispiel #2
0
    def test_defaults(self) -> None:

        generated = prepare_respin(respin_generator=RespStage1RespinGenerator(
            self.ivary),
                                   total_charge=0,
                                   molecule=self.molecule)

        self.assertAlmostEqualRecursive(self.expected_respin, generated)
Beispiel #3
0
    def test_with_total_charge(self) -> None:

        generated = prepare_respin(respin_generator=RespStage1RespinGenerator(
            self.ivary),
                                   total_charge=1,
                                   molecule=self.molecule)

        expected = deepcopy(self.expected_respin)
        expected.charge = 1

        self.assertAlmostEqualRecursive(expected, generated)
Beispiel #4
0
    def test_with_read_charges(self) -> None:

        generated = prepare_respin(respin_generator=RespStage1RespinGenerator(
            self.ivary),
                                   total_charge=0,
                                   molecule=self.molecule,
                                   read_charges=True)

        expected = deepcopy(self.expected_respin)
        expected.cntrl.iqopt = 2

        self.assertAlmostEqualRecursive(expected, generated)
Beispiel #5
0
    def test_with_title_and_subtitles(self) -> None:

        generated = prepare_respin(respin_generator=RespStage1RespinGenerator(
            self.ivary),
                                   total_charge=0,
                                   molecule=self.molecule,
                                   title="Custom title",
                                   subtitle="Custom subtitle")

        expected = deepcopy(self.expected_respin)
        expected.title = "Custom title"
        expected.subtitle = "Custom subtitle"

        self.assertAlmostEqualRecursive(expected, generated)
Beispiel #6
0
def fit_with_frozen_atoms(
        esp_data: EspData,
        equivalence: Equivalence,
        molecule: Molecule[Atom],
        frozen_atoms: List[int],
        total_charge: int,
        initial_charges: List[Charge],
        generate_esout: bool = False,
        save_intermediates_to: Optional[str] = None) -> List[Charge]:
    """Fit hydrogen atom charges to the provided ESP subject to equivalence relations

    Parameters
    ----------
    esp_data : EspData
        See `run_resp` function parameter
    equivalence : Equivalence
        The chemical equivalence relations between atoms of the molecule.
    molecule : Molecule[Atom]
        The molecule which charges are being fitted. Only atom identities are required.
    frozen_atoms : List[int]
        List of zero-based indices of atoms in the molecule which charges should
        not be fitted but fixed at the values provided in `initial_charges` argument.
    total_charge : int
        The total charge of the molecule.
    initial_charges : typing.List[Charge]
        Initial charges to be used for the fitting. Charges on atoms specified
        in the `frozen_atoms` arguments will be fixed at the provided values.
    generate_esout : bool, optional
        See `run_resp` function parameter
    save_intermediates_to : Optional[str], optional
        See `run_resp` function parameter

    Returns
    -------
    typing.List[Charge]
        The charges fitted to the provided ESP subject to equivalence relations,
        except where the charges were frozen at initial values.
    """

    respin_generator = FrozenAtomsRespinGenerator(equivalence, frozen_atoms)
    respin = prepare_respin(respin_generator,
                            total_charge,
                            molecule,
                            read_charges=True)

    return run_resp(esp_data, respin, initial_charges, generate_esout,
                    save_intermediates_to)
Beispiel #7
0
    def test_fitting_with_frozen_atoms(self) -> None:

        respin = Respin(
            title=
            "Respin file prepared by `repESP` to perform fitting with selected atom charges frozen.",
            cntrl=Respin.Cntrl(iqopt=2, ihfree=0, qwt=0.0),
            subtitle="Resp charges for organic molecule",
            charge=0,
            molecule=Molecule(
                [Atom(atomic_number) for atomic_number in [6, 1, 1, 1, 1]]),
            ivary=Respin.Ivary([-1, 0, 2, -1, 2]))

        generated = prepare_respin(respin_generator=FrozenAtomsRespinGenerator(
            Equivalence([None, None, 1, 1, 1]), frozen_atoms=[0, 3]),
                                   total_charge=0,
                                   molecule=respin.molecule)

        self.assertAlmostEqualRecursive(respin, generated)
Beispiel #8
0
    def test_equivalencing(self) -> None:

        respin = Respin(
            title=
            "Respin file prepared by `repESP` to perform atom equivalencing.",
            cntrl=Respin.Cntrl(ihfree=0, qwt=0.0),
            subtitle="Resp charges for organic molecule",
            charge=0,
            molecule=Molecule(
                [Atom(atomic_number) for atomic_number in [6, 1, 1, 1, 1]]),
            ivary=Respin.Ivary([0, 0, 2, 2, 2]))

        generated = prepare_respin(
            respin_generator=EquivalenceOnlyRespinGenerator(
                Equivalence([None, None, 1, 1, 1])),
            total_charge=0,
            molecule=respin.molecule)

        self.assertAlmostEqualRecursive(respin, generated)
Beispiel #9
0
    def test_fitting_hydrogens_only(self) -> None:

        respin = Respin(
            title=
            "Respin file prepared by `repESP` to perform fitting of hydrogen atoms.",
            cntrl=Respin.Cntrl(iqopt=2, ihfree=0, qwt=0.0),
            subtitle="Resp charges for organic molecule",
            charge=0,
            molecule=Molecule(
                [Atom(atomic_number) for atomic_number in [6, 1, 1, 1, 1]]),
            ivary=Respin.Ivary([-1, 0, 2, 2, 2]))

        generated = prepare_respin(
            respin_generator=FitHydrogensOnlyRespinGenerator(
                Equivalence([None, None, 1, 1, 1]), respin.molecule),
            total_charge=0,
            molecule=respin.molecule)

        self.assertAlmostEqualRecursive(respin, generated)
Beispiel #10
0
def fit_hydrogens_only(
        esp_data: EspData,
        equivalence: Equivalence,
        molecule: Molecule[Atom],
        total_charge: int,
        initial_charges: List[Charge],
        generate_esout: bool = False,
        save_intermediates_to: Optional[str] = None) -> List[Charge]:
    """Fit hydrogen atom charges to the provided ESP subject to equivalence relations

    Parameters
    ----------
    esp_data : EspData
        See `run_resp` function parameter
    equivalence : Equivalence
        The chemical equivalence relations between atoms of the molecule.
    molecule : Molecule[Atom]
        The molecule which charges are being fitted. Only atom identities are required.
    total_charge : int
        The total charge of the molecule.
    initial_charges : typing.List[Charge]
        Initial charges to be used for the fitting. Charges on atoms other than
        hydrogen atoms will be fixed at the provided values.
    generate_esout : bool, optional
        See `run_resp` function parameter
    save_intermediates_to : Optional[str], optional
        See `run_resp` function parameter

    Returns
    -------
    typing.List[Charge]
        The hydrogen charges fitted to the provided ESP subject to equivalence
        relations. Other charges have values fixed at values from `initial_charges`.
    """

    respin_generator = FitHydrogensOnlyRespinGenerator(equivalence, molecule)
    respin = prepare_respin(respin_generator,
                            total_charge,
                            molecule,
                            read_charges=True)

    return run_resp(esp_data, respin, initial_charges, generate_esout,
                    save_intermediates_to)
Beispiel #11
0
def fit_with_equivalencing(
        esp_data: EspData,
        equivalence: Equivalence,
        molecule: Molecule[Atom],
        total_charge: int,
        initial_charges: Optional[List[Charge]] = None,
        generate_esout: bool = False,
        save_intermediates_to: Optional[str] = None) -> List[Charge]:
    """Fit charges to the provided ESP subject to equivalence relations

    Parameters
    ----------
    esp_data : EspData
        See `run_resp` function parameter
    equivalence : Equivalence
        The chemical equivalence relations between atoms of the molecule.
    molecule : Molecule[Atom]
        The molecule which charges are being fitted. Only atom identities are required.
    total_charge : int
        The total charge of the molecule.
    initial_charges : Optional[typing.List[Charge]], optional
        See `run_resp` function parameter
    generate_esout : bool, optional
        See `run_resp` function parameter
    save_intermediates_to : Optional[str], optional
        See `run_resp` function parameter

    Returns
    -------
    typing.List[Charge]
        The charges fitted to the provided ESP subject to equivalence relations.
    """

    respin_generator = EquivalenceOnlyRespinGenerator(equivalence)
    respin = prepare_respin(respin_generator,
                            total_charge,
                            molecule,
                            read_charges=initial_charges is not None)

    return run_resp(esp_data, respin, initial_charges, generate_esout,
                    save_intermediates_to)