def init_dynamics(self, Nm, V, L, dt, T): self.L = L # Generate the box of junk self.__generategarbagebox__(Nm, L, T) # Make mol self.mol = Atoms(symbols=self.S, positions=self.X) # Set box and PBC self.mol.set_cell(([[L, 0, 0], [0, L, 0], [0, 0, L]])) self.mol.set_pbc((True, True, True)) # Set ANI calculator # Set ANI calculator self.mol.set_calculator(ANIENS(self.aens)) #self.mol.set_calculator(ANI(False)) #self.mol.calc.setnc(self.ncl[0]) # Give molecules random velocity acc_idx = 0 vel = np.empty_like(self.X) for n in self.Na: rv = np.random.uniform(-V, V, size=(3)) for k in range(n): vel[acc_idx + k, :] = rv acc_idx += n #print(vel) self.mol.set_velocities(vel) # Declare Dyn self.dyn = Langevin(self.mol, dt * units.fs, T * units.kB, 0.1)
def init_dynamics(self, Nm, Nembed, V, L, dt, T): self.L = L # Generate the box of junk self.__generategarbagebox__(Nm, Nembed, L, T) # Make mol self.mol = Atoms(symbols=self.S, positions=self.X) # Set box and PBC self.mol.set_cell(([[L, 0, 0], [0, L, 0], [0, 0, L]])) self.mol.set_pbc((True, True, True)) # Set ANI calculator self.mol.set_calculator(ANIENS(self.aens)) # Open MD output #self.mdcrd = open(xyzfile, 'w') # Open MD output #self.traj = open(trjfile, 'w') # Set the velocities corresponding to a boltzmann dist @ T/4.0 MaxwellBoltzmannDistribution(self.mol, 300.0 * units.kB) # Declare Dyn self.dyn = Langevin(self.mol, dt * units.fs, T * units.kB, 0.1)
def ani_ase_calculator(ani_model): """ Return a calculator from a model. choices are %s """ % " ".join(models.keys()) return ANIENS(aniensloader(models[ani_model]))
def opt(self, rdkmol, dhls, logger='optlog.out'): Na = rdkmol.GetNumAtoms() X, S = __convert_rdkitmol_to_nparr__(rdkmol) atm=Atoms(symbols=S, positions=X) atm.set_calculator(ANIENS(self.ens)) #Set the ANI Ensemble as the calculator phi_fix = [] for d in dhls: phi_restraint=atm.get_dihedral(d) phi_fix.append([phi_restraint, d]) c = FixInternals(dihedrals=phi_fix, epsilon=1.e-9) atm.set_constraint(c) dyn = LBFGS(atm, logfile=logger) #Choose optimization algorith dyn.run(fmax=self.fmax, steps=1000) #optimize molecule to Gaussian's Opt=Tight fmax criteria, input in eV/A (I think) e=atm.get_potential_energy()*hdt.evtokcal s=atm.calc.stddev*hdt.evtokcal phi_value = [] for d in dhls: phi_value.append(atm.get_dihedral(d)*180./np.pi) #X = mol.get_positions() if self.printer: print('Phi value (degrees), energy (kcal/mol), sigma= ', phi_value, "{0:.2f}".format(e), "{0:.2f}".format(s)) return phi_value, e, s, atm
def run_md(self, f, Tmax, steps, n_steps, nmfile=None, displacement=0, min_steps=0, sig=0.34, t=0.1, nm=0, record=False): X, S, Na, cm = hdt.readxyz2(f) if nmfile != None: mode=self.get_mode(nmfile, Na, mn=nm) X=X+mode*np.random.uniform(-displacement,displacement) X=X[0] mol=Atoms(symbols=S, positions=X) mol.set_calculator(ANIENS(self.net,sdmx=20000000.0)) f=os.path.basename(f) T_eff = float(random.randrange(5, Tmax, 1)) # random T (random velocities) from 0K to TK minstep_eff = float(random.randrange(1, min_steps, 1)) # random T (random velocities) from 0K to TK dyn = Langevin(mol, t * units.fs, T_eff * units.kB, 0.01) MaxwellBoltzmannDistribution(mol, T_eff * units.kB) # steps=10000 #10000=1picosecond #Max number of steps to run # n_steps = 1 #Number of steps to run for before checking the standard deviation hsdt_Na=[] evkcal=hdt.evtokcal if record==True: #Records the coordinates at every step of the dynamics fname = f + '_record_' + str(T_eff) + 'K' + '.xyz' #name of file to store coodinated in def printenergy(name=fname, a=mol): """Function to print the potential, kinetic and total energy.""" fil= open(name,'a') Na=a.get_number_of_atoms() c = a.get_positions(wrap=True) fil.write('%s \n comment \n' %Na) for j, i in zip(a, c): fil.write(str(j.symbol) + ' ' + str(i[0]) + ' ' + str(i[1]) + ' ' + str(i[2]) + '\n') fil.close() dyn.attach(printenergy, interval=1) e=mol.get_potential_energy() #Calculate the energy of the molecule. Must be done to get the standard deviation s=mol.calc.stddev stddev = 0 tot_steps = 0 failed = False while (tot_steps <= steps): if stddev > sig and tot_steps > minstep_eff: #Check the standard deviation self.hstd.append(stddev) c = mol.get_positions() s = mol.get_chemical_symbols() Na=mol.get_number_of_atoms() self.Na_train.append(Na) self.coor_train.append(c) self.S_train.append(s) failed=True break else: #if the standard deviation is low, run dynamics, then check it again tot_steps = tot_steps + n_steps dyn.run(n_steps) stddev = evkcal*mol.calc.stddev c = mol.get_positions() s = mol.get_chemical_symbols() e=mol.get_potential_energy() #print("{0:.2f}".format(tot_steps*t),':',"{0:.2f}".format(stddev),':',"{0:.2f}".format(evkcal*e)) return c, s, tot_steps*t, stddev, failed, T_eff
def get_modes(self,atm,freqname="vib."): for f in [f for f in os.listdir(".") if freqname in f and '.pckl' in f]: os.remove(f) new_target = open(os.devnull, "w") old_target, sys.stdout = sys.stdout, new_target atm.set_calculator(ANIENS(self.ens)) vib = Vibrations(atm, nfree=2, name=freqname) vib.run() freq = vib.get_frequencies() modes = np.stack(vib.get_mode(i) for i in range(freq.size)) vib.clean() sys.stdout = old_target return modes
def __run_rand_dyn__(self, mid, T1, T2, dt, Nc, Ns, dS): # Setup calculator mol = self.mols[0].copy() # Setup PBC if active if self.pbc: mol.set_cell(([[self.pbl, 0, 0], [0, self.pbl, 0], [0, 0, self.pbl]])) mol.set_pbc((self.pbc, self.pbc, self.pbc)) # Setup calculator mol.set_calculator(ANIENS(self.aens)) #mol.set_calculator(ANI(False)) #mol.calc.setnc(self.ncl[0]) # Set chemical symbols spc = mol.get_chemical_symbols() # Set the velocities corresponding to a boltzmann dist @ T/4.0 MaxwellBoltzmannDistribution(mol, T1 * units.kB) # Set the thermostat dyn = Langevin(mol, dt * units.fs, T1 * units.kB, 0.02) dT = (T2 - T1)/Nc #print('Running...') for i in range(Nc): # Set steps temperature dyn.set_temperature((T1 + dT*i) * units.kB) # Do Ns steps of dynamics dyn.run(Ns) # Return sigma sigma = hdt.evtokcal * mol.calc.stddev ekin = mol.get_kinetic_energy() / len(mol) # Check for dynamics failure if sigma > dS: self.Nbad += 1 self.X.append(mol.get_positions()) #print('Step:', dyn.get_number_of_steps(), 'Sig:', sigma, 'Temp:', # str(ekin / (1.5 * units.kB)) + '(' + str(T1 + dT * i) + ')') return True,dyn.get_number_of_steps() return False,dyn.get_number_of_steps()
def get_energy_force_function(self, molecule): atoms = Atoms(numbers=molecule.atoms, positions=molecule.coords) atoms.set_calculator(ANIENS(self.aens)) def get_energy_and_force(xyz_coords, do_force=True): nonlocal atoms atoms.set_positions(xyz_coords) energy = atoms.get_potential_energy() * (eV / Hartree) if (do_force): force = atoms.get_forces() * (eV / (kJ / mol) * 1000) return energy, force else: return energy return get_energy_and_force
def optimize_molecule(self, X, S, fmax=0.1, steps=10000, logger='opt.out'): mol = Atoms(symbols=S, positions=X) mol.set_pbc((False, False, False)) mol.set_calculator(ANIENS(self.ens)) dyn = LBFGS(mol,logfile=logger) #dyn = LBFGS(mol) #dyn = QuasiNewton(mol,logfile=logger) dyn.run(fmax=fmax,steps=steps) stps = dyn.get_number_of_steps() opt = True if steps == stps: opt = False return np.array(mol.get_positions(),dtype=np.float32), opt
def optimize_rdkit_molecule(self, mrdk, cid, fmax=0.1, steps=10000, logger='opt.out'): mol = __convert_rdkitmol_to_aseatoms__(mrdk,cid) mol.set_pbc((False, False, False)) mol.set_calculator(ANIENS(self.ens)) dyn = LBFGS(mol,logfile=logger) #dyn = LBFGS(mol) #dyn = QuasiNewton(mol,logfile=logger) dyn.run(fmax=fmax,steps=steps) stps = dyn.get_number_of_steps() opt = True if steps == stps: opt = False xyz = mol.get_positions() for i,x in enumerate(xyz): mrdk.GetConformer(cid).SetAtomPosition(i,x) return opt
from ase_interface import ANIENS from ase_interface import aniensloader import ase import time from ase import units from ase.io import read, write from ase.optimize import BFGS, LBFGS # Read molecule from xyz mol = read('data/water.xyz') # Current ANI model options are: # '../ani_models/ani-1ccx_8x.info' Coupled cluster transfer learned model # '../ani_models/ani-1x_8x.info' Full ANI-1x wb97x/6-31g* dataset model mol.set_calculator(ANIENS(aniensloader('../ani_models/ani-1ccx_8x.info', 0))) # Calculate energy ei = mol.get_potential_energy() print("Initial Energy: ", ei) # Optimize molecule print("Optimizing...") start_time = time.time() dyn = LBFGS(mol) dyn.run(fmax=0.001) print('[ANI Optimization - Total time:', time.time() - start_time, 'seconds]') # Calculate energy ef = mol.get_potential_energy() print("Final Energy: ", ef)
def run_task_ase_one_layer(self, settings, systems, n_sweeps, n_steps_per_sweep=100, verbose_freq=1, temperature_pot_mm=unit.Quantity(300, unit.kelvin), temperature_kin_mm=unit.Quantity(300, unit.kelvin), label="0", checkpoint_freq=100, restart=False, ): """ Method that runs a HMC sampler. Parameters ---------- settings : dict Dictionary containing global ParaMol settings. systems : list of :obj:`ParaMol.System.system.ParaMolSystem` List containing instances of ParaMol systems. n_sweeps : int Number of MC sweeps to perform. n_steps_per_sweep : int Number of MD steps per MC sweep. verbose_freq : int Verbose frequency. temperature_pot_mm : unit.Quantity Temperature used for the MM potential part. temperature_kin_mm : unit.Quantity Temperature used for the MM kinetic part. label : int HMC sampler label. It has to be an integer number. checkpoint_freq : int Frequency at which checkpoint restart files are written. restart : bool Flag that controls whether or not to perform a restart. Returns ------- systems : list List with the updated instances of ParaMol System. """ from ase_interface import ANIENS from ase_interface import aniensloader from ase import units as ase_unit assert len(systems) == 1, "HMC task currently only supports one system at once." # Create QM Engines and initiate OpenMM for system in systems: system.convert_system_ref_arrays_to_list() # Create OpenMM system system.engine.init_openmm(create_system_params=system.engine._create_system_params) system.engine.get_masses() # Create QM Engine if system.interface is None: system.interface = ParaMolInterface() system.create_qm_engines(settings.qm_engine["qm_engine"], settings.qm_engine[settings.qm_engine["qm_engine"].lower()]) # Create ASE NN calculator # Get atom list and atomic numbers list system.engine.get_atom_list() """ mm_ase_engine = ASEWrapper(system_name=system.name, interface=system.interface, calculator=ANIENS(aniensloader('../ani_models/ani-1ccx_8x.info', 0)), n_atoms=system.n_atoms, atom_list=system.engine.atom_list, n_calculations=1, cell=None, work_dir_prefix="NN_ASEWorkDir_") """ calc = ANIENS(aniensloader('/home/joao/programs/ASE_ANI/ani_models/ani-2x_8x.info',0)) #calc = DFTD3(dft=calc, cutoff=np.sqrt(9000) * ase_units.Bohr, damping="bj", a1=0.5719, a2=3.6017, s8=0.5883, s6=1.000, alpha6=1.0) mm_ase_engine = ASEWrapper(system_name=system.name, interface=system.interface, calculator=calc, n_atoms=system.n_atoms, atom_list=system.engine.atom_list, n_calculations=1, cell=None, work_dir_prefix="NN_ASEWorkDir_") system = systems[0] self._label = label parameter_space, objective_function, optimizer = (None, None, None) # TODO: Once this is included in the main ParaMol version, add this line to the default dictionary settings.restart["restart_hmc_file_{}".format(self._label)] = "restart_hmc_{}.pickle".format(self._label) if restart: logging.info("Starting HMC sampler parametrization from a previous restart.") # Read HMCSampler pickle self.__dict__ = self.read_restart_pickle(settings.restart, system.interface, "restart_hmc_file_{}".format(self._label)) # Read data into system system.read_data(os.path.join(settings.restart["restart_dir"], "{}_hmc_{}.nc".format(system.name, self._label))) else: self._n = 1 # MM chain self._n_total_mm = 0 self._n_accepted_mm = 0 while self._n <= n_sweeps: if self._n % verbose_freq == 0: print("HMC sampler of system {} # Sweep number {}.".format(system.name, self._n)) print("HMC sampler of system {} # Acceptance rate of MM chain {:.4f}".format(system.name, self._acceptance_rate_mm())) if len(system.ref_coordinates) > 0 and self._n != 1: # Do not need to compute the QM energy if there are structures in the top ensemble or if we are not in the first ever iteration. system.engine.set_positions(system.ref_coordinates[-1]) potential_initial_mm = mm_ase_engine.run_calculation(coords=system.ref_coordinates[-1] * 10, label=int(self._label)) coord_to_run = system.ref_coordinates[-1] * 10 else: # Compute MM initial kinetic and potential energy potential_initial_mm = mm_ase_engine.run_calculation(coords=system.engine.get_positions().in_units_of(unit.angstrom)._value, label=int(self._label)) coord_to_run = system.engine.get_positions().in_units_of(unit.angstrom)._value # Run short MD using ASE coords, potential_initial_mm, kinetic_initial, forces_initial, potential_final_mm, kinetic_final, forces_final = mm_ase_engine.run_md(coords=coord_to_run, label=int(self._label), steps=n_steps_per_sweep, dt=0.5*ase_unit.fs, initial_temperature=300.0*ase_unit.kB,) # Compute MM final kinetic and potential energy kinetic_initial = unit.Quantity(kinetic_initial, unit.kilojoules_per_mole) potential_initial_mm = unit.Quantity(potential_initial_mm, unit.kilojoules_per_mole) kinetic_final = unit.Quantity(kinetic_final, unit.kilojoules_per_mole) potential_final_mm = unit.Quantity(potential_final_mm, unit.kilojoules_per_mole) coords = unit.Quantity(coords, unit.nanometers) if self._hmc_acceptance_criterion_mm(potential_final_mm, potential_initial_mm, kinetic_final, kinetic_initial, temperature_pot_mm, temperature_kin_mm): # Append energies, forces and conformations system.ref_energies.append(potential_final_mm._value) system.ref_coordinates.append(coords._value) system.n_structures += 1 # TODO: include code related to partial momentum refreshment elif len(system.ref_coordinates) > 0: # Append last accepted structure system.ref_energies.append(system.ref_energies[-1]) system.ref_coordinates.append(system.ref_coordinates[-1]) system.n_structures += 1 else: # No structures have been accepted yet. pass # Write restart files if self._n % checkpoint_freq == 0: self.write_restart_pickle(settings.restart, system.interface, "restart_hmc_file_{}".format(self._label), self.__dict__) system.write_data(os.path.join(settings.restart["restart_dir"], "{}_hmc_{}.nc".format(system.name, self._label))) system.write_coordinates_xyz("{}_hmc_{}.xyz".format(system.name, self._label)) self._n += 1 return systems
# Load molecule mol = read(molfile) #print('test') L = 70.0 mol.set_cell(([[L, 0, 0], [0, L, 0], [0, 0, L]])) mol.set_pbc((True, True, True)) #print(mol.get_chemical_symbols()) # Set NC aens = ensemblemolecule(cnstfile, saefile, nnfdir, Nn, 5) # Set ANI calculator mol.set_calculator(ANIENS(aens, sdmx=20000000.0)) print(mol.get_potential_energy()) print(np.where(mol.get_forces() > 200.0)) print("size: ", len(mol.get_chemical_symbols())) # Optimize molecule start_time = time.time() dyn = QuasiNewton(mol) dyn.run(fmax=C) print('[ANI Total time:', time.time() - start_time, 'seconds]') #print(hdt.evtokcal*mol.get_potential_energy()) #print(hdt.evtokcal*mol.get_forces())