Exemplo n.º 1
0
def _select_dihedrals(mol, args):

    from parameterize.parameterization.detect import detectParameterizableDihedrals

    logger.info("=== Dihedral angles ===")

    # Detect parameterizable dihedral angles
    parameterizable_dihedrals = detectParameterizableDihedrals(mol)
    logger.info("Parameterizable dihedral angles (and their equivalents):")
    for i, equivalent_dihedrals in enumerate(parameterizable_dihedrals):
        names = [
            "-".join(mol.name[list(dihedral)])
            for dihedral in equivalent_dihedrals
        ]
        line = "    {:2d}: {}".format(i + 1, names[0])
        if names[1:]:
            line += " ({})".format(", ".join(names[1:]))
        logger.info(line)

    # Print parameterize dihedral list to a file and exit
    # TODO factor this out
    if args.list:
        dihedral_file = "torsions.txt"
        with open(dihedral_file, "w") as file:
            for dihedrals in parameterizable_dihedrals:
                name = "-".join(mol.name[list(dihedrals[0])])
                file.write("{}\n".format(name))
            logger.info(
                "Write the list of the parameterizable dihedral angles to {}".
                format(dihedral_file))
        sys.exit()

    # Select dihedrals to parameterize
    selected_dihedrals = []
    if args.fit_dihedral:
        if args.dihedral:
            name2dihedral = {
                "-".join(mol.name[list(dihedrals[0])]): dihedrals[0]
                for dihedrals in parameterizable_dihedrals
            }
            for dihedral_name in args.dihedral:
                if dihedral_name not in name2dihedral.keys():
                    raise ValueError(
                        "%s is not recognized as a rotatable dihedral angle" %
                        dihedral_name)
                selected_dihedrals.append(list(name2dihedral[dihedral_name]))
        else:
            # By default parameterize all the dihedrals
            selected_dihedrals = [
                list(dihedrals[0]) for dihedrals in parameterizable_dihedrals
            ]

    if len(selected_dihedrals) > 0:
        logger.info("Selected dihedral angles:")
        for i, dihedral in enumerate(selected_dihedrals):
            name = "-".join(mol.name[list(dihedral)])
            logger.info("    {:2d}: {}".format(i + 1, name))
    else:
        logger.info("No dihedral angles selected")

    return selected_dihedrals
Exemplo n.º 2
0
    def _setup(self):

        if len(self.dihedrals) != len(self.qm_results):
            raise ValueError(
                "The number of dihedral and QM result sets has to be the same!"
            )

        # Get dihedral names
        self._names = [
            "-".join(self.molecule.name[dihedral]) for dihedral in self.dihedrals
        ]

        # Get all equivalent dihedrals
        all_equivalent_dihedrals = detectParameterizableDihedrals(self.molecule)
        all_equivalent_dihedrals = {
            tuple(dihedrals[0]): dihedrals for dihedrals in all_equivalent_dihedrals
        }

        # Choose the selected dihedrals
        equivalent_dihedrals = []
        for dihedral, name in zip(self.dihedrals, self._names):
            if tuple(dihedral) not in all_equivalent_dihedrals:
                raise ValueError("{} is not a parameterizable dihedral!".format(name))
            equivalent_dihedrals.append(all_equivalent_dihedrals[tuple(dihedral)])

        # Get dihedral atom types
        self._dihedral_atomtypes = [
            findDihedralType(tuple(self.molecule.atomtype[dihedral]), self.parameters)
            for dihedral in self.dihedrals
        ]

        # Get reference QM energies and rotamer coordinates
        self._reference_energies = []
        self._coords = []
        for results in self.qm_results:
            self._reference_energies.append(
                np.array([result.energy for result in results])
            )
            self._coords.append([result.coords for result in results])

        # Calculate dihedral angle values
        # [# of scans, # of dihedrals, # of conformations, # of equivalents]
        self._angle_values = []
        for scan_coords in self._coords:
            scan_angle_values = []
            for equivalent_indices in equivalent_dihedrals:
                angle_values = []
                for coords in scan_coords:
                    angle_values.append(
                        [
                            dihedralAngle(coords[indices, :, 0])
                            for indices in equivalent_indices
                        ]
                    )
                scan_angle_values.append(np.array(angle_values))
            self._angle_values.append(scan_angle_values)

        # Calculated initial MM energies
        ff = FFEvaluate(self.molecule, self.parameters)
        self._initial_energies = []
        for scan_coords in self._coords:
            energies = [
                ff.calculateEnergies(coords[:, :, 0])["total"] for coords in scan_coords
            ]
            self._initial_energies.append(np.array(energies))

        # Make result directories
        os.makedirs(self.result_directory, exist_ok=True)