Пример #1
0
    def retrieve(self):

        ff = FFEvaluate(self.molecule, self._parameters)

        results = []
        for iframe in range(self.molecule.numFrames):
            self.molecule.frame = iframe

            directory = os.path.join(self.directory, '%05d' % iframe)
            os.makedirs(directory, exist_ok=True)
            pickleFile = os.path.join(directory, 'data.pkl')

            if self._completed(directory):
                with open(pickleFile, 'rb') as fd:
                    result = pickle.load(fd)
                logger.info('Loading QM data from %s' % pickleFile)

            else:
                result = QMResult()
                result.errored = False
                result.coords = self.molecule.coords[:, :, iframe:iframe + 1].copy()

                if self.optimize:
                    opt = nlopt.opt(nlopt.LN_COBYLA, result.coords.size)
                    opt.set_min_objective(lambda x, _: ff.calculateEnergies(x.reshape((-1, 3)))['total'])
                    if self.restrained_dihedrals is not None:
                        for dihedral in self.restrained_dihedrals:
                            indices = dihedral.copy()
                            ref_angle = dihedralAngle(self.molecule.coords[indices, :, iframe])
                            def constraint(x, _):
                                coords = x.reshape((-1, 3))
                                angle = dihedralAngle(coords[indices])
                                return np.sin(.5*(angle - ref_angle))
                            opt.add_equality_constraint(constraint)
                    opt.set_xtol_abs(1e-3) # Similar to Psi4 default
                    opt.set_maxeval(1000*opt.get_dimension())
                    opt.set_initial_step(1e-3)
                    result.coords = opt.optimize(result.coords.ravel()).reshape((-1, 3, 1))
                    logger.info('Optimization status: %d' % opt.last_optimize_result())

                result.energy = ff.calculateEnergies(result.coords[:, :, 0])['total']
                result.dipole = getDipole(self.molecule)

                if self.optimize:
                    assert opt.last_optimum_value() == result.energy # A self-consistency test

                # Compute ESP values
                if self.esp_points is not None:
                    assert self.molecule.numFrames == 1
                    result.esp_points = self.esp_points
                    distances = cdist(result.esp_points, result.coords[:, :, 0])  # Angstrom
                    distances *= const.physical_constants['Bohr radius'][0] / const.angstrom  # Angstrom --> Bohr
                    result.esp_values = np.dot(np.reciprocal(distances), self.molecule.charge)  # Hartree/Bohr

                with open(pickleFile, 'wb') as fd:
                    pickle.dump(result, fd)

            results.append(result)

        return results
Пример #2
0
    def run(self):

        ff = FFEvaluate(self.molecule)

        results = []
        for iframe in range(self.molecule.numFrames):
            self.molecule.frame = iframe

            directory = os.path.join(self.directory, '%05d' % iframe)
            os.makedirs(directory, exist_ok=True)
            pickleFile = os.path.join(directory, 'data.pkl')

            if self._completed(directory):
                with open(pickleFile, 'rb') as fd:
                    result = pickle.load(fd)
                logger.info('Loading QM data from %s' % pickleFile)

            else:
                result = QMResult()
                result.errored = False
                result.coords = self.molecule.coords[:, :, iframe:iframe + 1].copy()

                if self.optimize:
                    opt = nlopt.opt(nlopt.LN_COBYLA, result.coords.size)
                    opt.set_min_objective(lambda x, _: ff.run(x.reshape((-1, 3)))['total'])
                    if self.restrained_dihedrals is not None:
                        for dihedral in self.restrained_dihedrals:
                            indices = dihedral.copy()
                            ref_angle = np.deg2rad(dihedralAngle(self.molecule.coords[indices, :, iframe]))
                            def constraint(x, _):
                                coords = x.reshape((-1, 3))
                                angle = np.deg2rad(dihedralAngle(coords[indices]))
                                return np.sin(.5*(angle - ref_angle))
                            opt.add_equality_constraint(constraint)
                    opt.set_xtol_abs(1e-3) # Similar to Psi4 default
                    opt.set_maxeval(1000*opt.get_dimension())
                    opt.set_initial_step(1e-3)
                    result.coords = opt.optimize(result.coords.ravel()).reshape((-1, 3, 1))
                    logger.info('Optimization status: %d' % opt.last_optimize_result())

                result.energy = ff.run(result.coords[:, :, 0])['total']
                result.dipole = self.molecule.getDipole()

                if self.optimize:
                    assert opt.last_optimum_value() == result.energy # A self-consistency test

                # Compute ESP values
                if self.esp_points is not None:
                    assert self.molecule.numFrames == 1
                    result.esp_points = self.esp_points
                    distances = cdist(result.esp_points, result.coords[:, :, 0])  # Angstrom
                    distances *= const.physical_constants['Bohr radius'][0] / const.angstrom  # Angstrom --> Bohr
                    result.esp_values = np.dot(np.reciprocal(distances), self.molecule.charge)  # Hartree/Bohr

                with open(pickleFile, 'wb') as fd:
                    pickle.dump(result, fd)

            results.append(result)

        return results
Пример #3
0
    def retrieve(self):

        results = []
        for iframe in range(self.molecule.numFrames):
            self.molecule.frame = iframe

            directory = os.path.join(self.directory, '%05d' % iframe)
            os.makedirs(directory, exist_ok=True)
            pickleFile = os.path.join(directory, 'data.pkl')
            molFile = os.path.join(directory, 'mol.mol2')

            if self._completed(directory):
                with open(pickleFile, 'rb') as fd:
                    result = pickle.load(fd)
                logger.info('Loading data from %s' % pickleFile)

            else:
                start = time.clock()

                result = QMResult()
                result.errored = False
                result.coords = self.molecule.coords[:, :,
                                                     iframe:iframe + 1].copy()

                if self.optimize:
                    if self.minimizer is None:
                        self.minimizer = CustomEnergyBasedMinimizer(
                            self.molecule, self.calculator)
                    result.coords = self.minimizer.minimize(
                        result.coords, self.restrained_dihedrals).reshape(
                            (-1, 3, 1))
                    mol = self.molecule.copy()
                    mol.frame = 0
                    mol.coords = result.coords
                    mol.write(molFile)

                result.energy = float(
                    self.calculator.calculate(result.coords,
                                              self.molecule.element,
                                              units='kcalmol')[0])
                result.dipole = [0, 0, 0]

                #if self.optimize:
                #    assert opt.last_optimum_value() == result.energy # A self-consistency test

                finish = time.clock()
                result.calculator_time = finish - start
                if self._verbose:
                    logger.info('Custom calculator calculation time: %f s' %
                                result.calculator_time)

                with open(pickleFile, 'wb') as fd:
                    pickle.dump(result, fd)

            results.append(result)

        return results
Пример #4
0
    def run(self):

        prmtop = self._get_prmtop()
        system = prmtop.createSystem()
        groups = {force.getForceGroup() for force in system.getForces()}

        if self.optimize:
            if self.restrained_dihedrals is not None:
                restraint = openmm.PeriodicTorsionForce()
                restraint.setForceGroup(max(groups) + 1)

                for dihedral in self.restrained_dihedrals:
                    restraint.addTorsion(*tuple(map(int, dihedral)),
                                         periodicity=1,
                                         phase=0,
                                         k=-1000 * unit.kilocalorie_per_mole)

                system.addForce(restraint)

        simulation = app.Simulation(
            prmtop.topology, system,
            openmm.VerletIntegrator(1 * unit.femtosecond),
            openmm.Platform.getPlatformByName('CPU'))

        results = []
        molecule_copy = self.molecule.copy()
        for iframe in range(self.molecule.numFrames):
            self.molecule.frame = iframe
            molecule_copy.frame = iframe

            directory = os.path.join(self.directory, '%05d' % iframe)
            os.makedirs(directory, exist_ok=True)
            pickleFile = os.path.join(directory, 'data.pkl')

            if self._completed(directory):
                with open(pickleFile, 'rb') as fd:
                    results.append(pickle.load(fd))
                logger.info('Loading QM data from %s' % pickleFile)
                continue

            simulation.context.setPositions(
                self.molecule.coords[:, :, iframe] * unit.angstrom)
            if self.optimize:
                if self.restrained_dihedrals is not None:
                    for i, dihedral in enumerate(self.restrained_dihedrals):
                        ref_angle = dihedralAngle(
                            self.molecule.coords[dihedral, :, iframe])
                        parameters = restraint.getTorsionParameters(i)
                        parameters[5] = ref_angle * unit.degree
                        restraint.setTorsionParameters(i, *parameters)
                    restraint.updateParametersInContext(simulation.context)
                simulation.minimizeEnergy(tolerance=0.001 *
                                          unit.kilocalorie_per_mole)
            state = simulation.context.getState(getEnergy=True,
                                                getPositions=True,
                                                groups=groups)

            result = QMResult()
            result.errored = False
            result.energy = state.getPotentialEnergy().value_in_unit(
                unit.kilocalorie_per_mole)
            result.coords = state.getPositions(asNumpy=True).value_in_unit(
                unit.angstrom).reshape((-1, 3, 1))
            result.dipole = self.molecule.getDipole()

            if self.esp_points is not None:
                assert self.molecule.numFrames == 1
                result.esp_points = self.esp_points
                distances = cdist(result.esp_points,
                                  result.coords[:, :, 0])  # Angstrom
                distances *= const.physical_constants['Bohr radius'][
                    0] / const.angstrom  # Angstrom --> Bohr
                result.esp_values = np.dot(
                    np.reciprocal(distances),
                    self.molecule.charge)  # Hartree/Bohr

            results.append(result)

            with open(pickleFile, 'wb') as fd:
                pickle.dump(result, fd)

            self.molecule.write(os.path.join(
                directory, 'mol-init.mol2'))  # Write an optimiz
            molecule_copy.coords[:, :, iframe] = result.coords[:, :, 0]
            molecule_copy.write(os.path.join(directory,
                                             'mol.mol2'))  # Write an optimiz

        return results
Пример #5
0
    def _readOutput(self, directory):

        result = QMResult()
        result.completed = True

        xyzFile = os.path.join(directory, 'psi4out.xyz')
        if os.path.exists(xyzFile):
            with open(xyzFile) as f:
                result.energy = float(f.readline().split()[1])  # Read the 2nd number on the 1st line
            result.energy *= const.physical_constants['Hartree energy'][0]/(const.kilo*const.calorie/const.Avogadro) # Hartree to kcal/mol
            result.coords = np.loadtxt(xyzFile, skiprows=2, usecols=(1, 2, 3))
            result.coords = np.atleast_3d(result.coords)  # TODO get rid of this
        else:
            result.errored = True

        if self.esp_points is not None:
            espFile = os.path.join(directory, 'grid_esp.dat')
            if os.path.exists(espFile):
                result.esp_points = self.esp_points
                result.esp_values = np.loadtxt(espFile)
                result.esp_values *= const.angstrom/const.physical_constants['Bohr radius'][0] # 1/Bohr to 1/Angstrom
            else:
                result.errored = True

        outFile = os.path.join(directory, 'psi4.out')
        if os.path.exists(outFile):
            with open(outFile) as f:
                lines = f.readlines()

            for i in range(len(lines)):
                if "Mulliken Charges: (a.u.)" in lines[i]:
                    result.mulliken = []
                    for j in range(self._natoms):
                        s = lines[i + 2 + j].split()
                        result.mulliken.append(float(s[5]))

                if "Dipole Moment: (Debye)" in lines[i]:
                    s = lines[i + 1].split()
                    result.dipole = [float(s[1]), float(s[3]), float(s[5]), float(s[7])]

                if " Traceless Quadrupole Moment: (Debye Ang)" in lines[i]:
                    s1, s2 = lines[i + 1].split(), lines[i + 2].split()
                    result.quadrupole = [float(s1[1]), float(s1[3]), float(s1[5]),
                                         float(s2[1]), float(s2[3]), float(s2[5])]

        else:
            result.errored = True

        return result
Пример #6
0
    def _readOutput(self, directory):

        result = QMResult()

        with open(os.path.join(directory, 'g09.out')) as f:
            fl = f.readlines()

        try:
            data = {}

            for i in range(len(fl)):
                if "Dipole moment (field-independent basis, Debye):" in fl[i]:
                    s = fl[i + 1].split()
                    data['dipole'] = [
                        float(s[1]),
                        float(s[3]),
                        float(s[5]),
                        float(s[7])
                    ]
                if "Traceless Quadrupole moment (field-independent basis, Debye-Ang):" in fl[
                        i]:
                    s1 = fl[i + 1].split()
                    s2 = fl[i + 2].split()
                    data['quadrupole'] = [
                        float(s1[1]),
                        float(s1[3]),
                        float(s1[5]),
                        float(s2[1]),
                        float(s2[3]),
                        float(s2[5])
                    ]
                if "Mulliken atomic charges:" in fl[
                        i] or "Mulliken charges:" in fl[i]:
                    data['mulliken'] = []
                    for j in range(self._natoms):
                        data['mulliken'].append(float(fl[i + 2 +
                                                         j].split()[2]))

            for l in fl:
                if "SCF Done:  E(RHF) = " in l:
                    ff = l.split()
                    data['energy'] = float(ff[4])
                if "SCF Done:  E(RB3LYP) = " in l:
                    ff = l.split()
                    data['energy'] = float(ff[4])
            i = 0
            while i < len(fl):
                if "Number     Number       Type             X           Y           Z" in fl[
                        i]:
                    i += 2
                    data['coords'] = np.zeros((self._natoms, 3))
                    for j in range(self._natoms):
                        ff = fl[j + i].split()
                        data['coords'][j, 0] = float(ff[3])
                        data['coords'][j, 1] = float(ff[4])
                        data['coords'][j, 2] = float(ff[5])
                else:
                    i += 1

            i = 0
            while i < len(fl):
                if "               Potential          X             Y             Z" in fl[
                        i]:
                    i = i + 2 + self._natoms
                    data['gridesp'] = []
                    while not ("----" in fl[i]):
                        ff = fl[i].split()
                        data['gridesp'].append(float(ff[1]))
                        i += 1
                    data['gridesp'] = np.asarray(data['gridesp'],
                                                 dtype=np.float)

                else:
                    i += 1

        except:
            data = None

        if data is None:
            result.errored = True
        elif not ('energy' in data) or data['energy'] == 0.:
            result.errored = True
        else:
            result.energy = data['energy']
            result.energy *= const.physical_constants['Hartree energy'][0] / (
                const.kilo * const.calorie / const.Avogadro
            )  # Hartree to kcal/mol
            result.coords = np.atleast_3d(data['coords'])
            if 'gridesp' in data:
                result.esp_points = np.squeeze(np.asarray(self.esp_points))
                result.esp_values = data['gridesp']
                result.esp_values *= const.angstrom / const.physical_constants[
                    'Bohr radius'][0]  # 1/Bohr to 1/Angstrom
            if 'dipole' in data:
                result.dipole = data['dipole']
            if 'quadrupole' in data:
                result.quadrupole = data['quadrupole']
            if 'mulliken' in data:
                result.mulliken = data['mulliken']

        return result
Пример #7
0
    def _readOutput(self, directory):

        result = QMResult()

        with open(os.path.join(directory, 'g09.out')) as f:
            fl = f.readlines()

        try:
            data = {}

            for i in range(len(fl)):
                if "Dipole moment (field-independent basis, Debye):" in fl[i]:
                    s = fl[i + 1].split()
                    data['dipole'] = [float(s[1]), float(s[3]), float(s[5]), float(s[7])]
                if "Traceless Quadrupole moment (field-independent basis, Debye-Ang):" in fl[i]:
                    s1 = fl[i + 1].split()
                    s2 = fl[i + 2].split()
                    data['quadrupole'] = [float(s1[1]), float(s1[3]), float(s1[5]), float(s2[1]), float(s2[3]),
                                          float(s2[5])]
                if "Mulliken atomic charges:" in fl[i] or "Mulliken charges:" in fl[i]:
                    data['mulliken'] = []
                    for j in range(self._natoms):
                        data['mulliken'].append(float(fl[i + 2 + j].split()[2]))

            for l in fl:
                if "SCF Done:  E(RHF) = " in l:
                    ff = l.split()
                    data['energy'] = float(ff[4])
                if "SCF Done:  E(RB3LYP) = " in l:
                    ff = l.split()
                    data['energy'] = float(ff[4])
            i = 0
            while i < len(fl):
                if "Number     Number       Type             X           Y           Z" in fl[i]:
                    i += 2
                    data['coords'] = np.zeros((self._natoms, 3))
                    for j in range(self._natoms):
                        ff = fl[j + i].split()
                        data['coords'][j, 0] = float(ff[3])
                        data['coords'][j, 1] = float(ff[4])
                        data['coords'][j, 2] = float(ff[5])
                else:
                    i += 1

            i = 0
            while i < len(fl):
                if "               Potential          X             Y             Z" in fl[i]:
                    i = i + 2 + self._natoms
                    data['gridesp'] = []
                    while not ("----" in fl[i]):
                        ff = fl[i].split()
                        data['gridesp'].append(float(ff[1]))
                        i += 1
                    data['gridesp'] = np.asarray(data['gridesp'], dtype=np.float)

                else:
                    i += 1

        except:
            data = None

        if data is None:
            result.errored = True
        elif not ('energy' in data) or data['energy'] == 0.:
            result.errored = True
        else:
            result.energy = data['energy']
            result.energy *= const.physical_constants['Hartree energy'][0]/(const.kilo*const.calorie/const.Avogadro) # Hartree to kcal/mol
            result.coords = np.atleast_3d(data['coords'])
            if 'gridesp' in data:
                result.esp_points = np.squeeze(np.asarray(self.esp_points))
                result.esp_values = data['gridesp']
                result.esp_values *= const.angstrom/const.physical_constants['Bohr radius'][0] # 1/Bohr to 1/Angstrom
            if 'dipole' in data:
                result.dipole = data['dipole']
            if 'quadrupole' in data:
                result.quadrupole = data['quadrupole']
            if 'mulliken' in data:
                result.mulliken = data['mulliken']

        return result
Пример #8
0
    def _readOutput(self, directory):

        result = QMResult()
        result.completed = True

        xyzFile = os.path.join(directory, 'psi4out.xyz')
        if os.path.exists(xyzFile):
            with open(xyzFile) as f:
                result.energy = float(f.readline().split()[1])  # Read the 2nd number on the 1st line
            result.energy *= const.physical_constants['Hartree energy'][0]/(const.kilo*const.calorie/const.Avogadro) # Hartree to kcal/mol
            result.coords = np.loadtxt(xyzFile, skiprows=2, usecols=(1, 2, 3))
            result.coords = np.atleast_3d(result.coords)  # TODO get rid of this
        else:
            result.errored = True

        if self.esp_points is not None:
            espFile = os.path.join(directory, 'grid_esp.dat')
            if os.path.exists(espFile):
                result.esp_points = self.esp_points
                result.esp_values = np.loadtxt(espFile)
                result.esp_values *= const.angstrom/const.physical_constants['Bohr radius'][0] # 1/Bohr to 1/Angstrom
            else:
                result.errored = True

        outFile = os.path.join(directory, 'psi4.out')
        if os.path.exists(outFile):
            with open(outFile) as f:
                lines = f.readlines()

            for i in range(len(lines)):
                if "Mulliken Charges: (a.u.)" in lines[i]:
                    result.mulliken = []
                    for j in range(self._natoms):
                        s = lines[i + 2 + j].split()
                        result.mulliken.append(float(s[5]))

                if "Dipole Moment: (Debye)" in lines[i]:
                    s = lines[i + 1].split()
                    result.dipole = [float(s[1]), float(s[3]), float(s[5]), float(s[7])]

                if " Traceless Quadrupole Moment: (Debye Ang)" in lines[i]:
                    s1, s2 = lines[i + 1].split(), lines[i + 2].split()
                    result.quadrupole = [float(s1[1]), float(s1[3]), float(s1[5]),
                                         float(s2[1]), float(s2[3]), float(s2[5])]

        else:
            result.errored = True

        return result