def testAll(self): with open('symmetry_data.json') as f: data = json.load(f) messages = [ 'Expected external symmetry: {}, calculated: {}', 'Expected internal symmetry: {}, calculated: {}', 'Expected number of single events symmetry: {}, calculated: {}', ] for name in data: par = Parameters() qc = QuantumChemistry(par) mol = StationaryPoint(name, 0, 1, smiles=name) mol.characterize() kinbot.symmetry.calculate_symmetry(mol) sigma_int = 1 for row in mol.sigma_int: for at in row: sigma_int *= at calc = [mol.sigma_ext, sigma_int, mol.nopt] for i in range(3): cal = calc[i] exp = data[name]['expected_values'][i] self.assertEqual(exp, cal, name + ': ' + messages[i].format(exp, cal))
def testDihedralChangeHeptyl(self): """ The generation of ring conformers requires qc calculations and is therefore slow! """ if not os.path.exists('conf/'): os.mkdir('conf/') par = Parameters() qc = QuantumChemistry(par) smi = '[CH2]CCCCC' mol = StationaryPoint(smi, 0, 2, smiles=smi) mol.characterize() changes = [ [0, 3, 4, 5, 25.], [3, 4, 5, 6, 25.], [4, 5, 6, 7, 25.], [5, 6, 7, 16, 25.], ] name = 'hexyl_dihedral' success, new_geom = kinbot.modify_geom.modify_coordinates( mol, name, mol.geom, changes, mol.bond, write_files=self.write_files)
def testAll(self): data = { 'CC': [1, 0], 'CCC': [2, 0], 'CCCC': [3, 1], 'C=C': [0, 0], 'C=CC': [1, 0], 'C=C[CH2]': [0, 0], 'CC=C[CH2]': [1, 0], 'C1CCCC1': [0, 0], 'CO': [1, 0], 'C=CO': [1, 1], } for name in data: par = Parameters() qc = QuantumChemistry(par) mol = StationaryPoint(name, 0, 1, smiles=name) mol.characterize() hir_exp = data[name][0] conf_exp = data[name][1] hir_calc = len(mol.dihed) conf_calc = len(mol.conf_dihed) self.assertEqual( hir_exp, hir_calc, name + ': HIR, expected: {}, calculated: {}'.format( hir_exp, hir_calc)) self.assertEqual( conf_exp, conf_calc, name + ': CONF, expected: {}, calculated: {}'.format( conf_exp, conf_calc))
def testAll(self): with open('multimolecular_data.json') as f: data = json.load(f) for name in data: print name par = Parameters() qc = QuantumChemistry(par) structure = data[name]['structure'] mol = StationaryPoint(name,0,1,structure = structure) mol.characterize() mols = mol.start_multi_molecular() calculated = len(mols) expected = data[name]['expected_value'] self.assertEqual(calculated,expected, name + ': expected: {}, calculated: {}'.format(expected,calculated))
def testAll(self): data = {"C1=CC=CC=C1":2, "C1=CC=C(C)C=C1":2, "C=C[CH2]":2, "C=C=C":1, "C#C[CH2]":2, "S=S":1, "O=S=C":1, "O=S(C)[CH2]":3, "C1CC=CC=C1":1 } for name in data: par = Parameters() qc = QuantumChemistry(par) mol = StationaryPoint(name,0,1,smiles = name) mol.characterize() cal = len(mol.bonds) exp = data[name] self.assertEqual(exp ,cal ,name + ': expected: {}, calculated: {}'.format(exp,cal))
def testBondChangeEthane(self): """ The generation of a longer C-C bond in ethane """ if not os.path.exists('conf/'): os.mkdir('conf/') par = Parameters() qc = QuantumChemistry(par) smi = 'CC' mol = StationaryPoint(smi, 0, 1, smiles=smi) mol.characterize() changes = [ [0, 1, 1.8], ] name = 'ethane_bond_length_test' success, new_geom = kinbot.modify_geom.modify_coordinates( mol, name, mol.geom, changes, mol.bond, write_files=self.write_files)
def main(): try: input_file = sys.argv[1] except IndexError: print('To use KinBot, supply one argument being the input file!') sys.exit(-1) # print the license message to the console print(license_message.message) # initialize the parameters for this run masterpar = Parameters(input_file) par = masterpar.par input_file = masterpar.input_file # set up the logging environment if par['verbose']: logging.basicConfig(filename='kinbot.log', level=logging.DEBUG) else: logging.basicConfig(filename='kinbot.log', level=logging.INFO) # write the license message to the log file logging.info(license_message.message) logging.info('Input parameters') for param in par: logging.info('{} {}'.format(param, par[param])) # time stamp of the KinBot start logging.info('Starting KinBot at {}'.format(datetime.datetime.now())) # Make the necessary directories if not os.path.exists('perm'): os.makedirs('perm') if not os.path.exists('scratch'): os.makedirs('scratch') if not os.path.exists(par['single_point_qc']): os.mkdir(par['single_point_qc']) if par['rotor_scan'] == 1: if not os.path.exists('hir'): os.mkdir('hir') if not os.path.exists('hir_profiles'): os.mkdir('hir_profiles') if not os.path.exists('perm/hir/'): os.makedirs('perm/hir/') if par['conformer_search'] == 1: if not os.path.exists('conf'): os.mkdir('conf') if not os.path.exists('perm/conf'): os.makedirs('perm/conf') if not os.path.exists('me'): os.mkdir('me') # initialize the reactant well0 = StationaryPoint('well0', par['charge'], par['mult'], smiles=par['smiles'], structure=par['structure']) well0.short_name = 'w1' # write the initial reactant geometry to a file for visualization geom_out = open('geometry.xyz', 'w') geom_out.write('{}\n\n'.format(well0.natom)) for i, at in enumerate(well0.atom): x, y, z = well0.geom[i] geom_out.write('{} {:.6f} {:.6f} {:.6f}\n'.format(at, x, y, z)) geom_out.write('\n\n') geom_out.close() # characterize the initial reactant well0.characterize(dimer=par['dimer']) well0.name = str(well0.chemid) start_name = well0.name # initialize the qc instance qc = QuantumChemistry(par) # only run filecopying if PES is turned on # if par['pes']: # check if this well was calcualted before in another directory # this flag indicates that this kinbot run # should wait for the information from another # kinbot run to become available and copy the necessary information # wait_for_well = 1 # while wait_for_well: # wait_for_well = filecopying.copy_from_database_folder(well0.chemid, well0.chemid, qc) # if wait_for_well: # time.sleep(1) # start the initial optimization of the reactant logging.info('Starting optimization of intial well') qc.qc_opt(well0, well0.geom) err, well0.geom = qc.get_qc_geom(str(well0.chemid) + '_well', well0.natom, wait=1) err, well0.freq = qc.get_qc_freq(str(well0.chemid) + '_well', well0.natom, wait=1) if err < 0: logging.error('Error with initial structure optimization.') return if any(well0.freq[i] <= 0 for i in range(len(well0.freq))): logging.error('Found imaginary frequency for initial structure.') return # characterize again and look for differences well0.characterize(dimer=par['dimer']) well0.name = str(well0.chemid) if well0.name != start_name: logging.error( 'The first well optimized to a structure different from the input.' ) return # do an MP2 optimization of the reactant, # to compare some scan barrier heigths to if par['families'] == ['all'] or \ 'birad_recombination_R' in par['families'] or \ 'r12_cycloaddition' in par['families'] or \ 'r14_birad_scission' in par['families'] or \ 'R_Addition_MultipleBond' in par['families'] or \ (par['skip_families'] != ['none'] and \ ('birad_recombination_R' not in par['skip_families'] or \ 'r12_cycloaddition' not in par['skip_families'] or \ 'r14_birad_scission' not in par['skip_families'] or \ 'R_Addition_MultipleBond' not in par['skip_families'])) or \ par['reaction_search'] == 0: logging.info('Starting MP2 optimization of intial well') qc.qc_opt(well0, well0.geom, mp2=1) err, geom = qc.get_qc_geom( str(well0.chemid) + '_well_mp2', well0.natom, 1) # comparison for barrierless scan if par['barrierless_saddle']: logging.info( 'Optimization of intial well for barrierless at {}/{}'.format( par['barrierless_saddle_method'], par['barrierless_saddle_basis'])) qc.qc_opt(well0, well0.geom, bls=1) err, geom = qc.get_qc_geom( str(well0.chemid) + '_well_bls', well0.natom, 1) # characterize again and look for differences well0.characterize(dimer=par['dimer']) well0.name = str(well0.chemid) err, well0.energy = qc.get_qc_energy(str(well0.chemid) + '_well', 1) err, well0.zpe = qc.get_qc_zpe(str(well0.chemid) + '_well', 1) well_opt = Optimize(well0, par, qc, wait=1) well_opt.do_optimization() if well_opt.shigh == -999: logging.error( 'Error with high level optimization of initial structure.') return if par['pes']: filecopying.copy_to_database_folder(well0.chemid, well0.chemid, qc) if par['reaction_search'] == 1: logging.info('Starting reaction searches of intial well') rf = ReactionFinder(well0, par, qc) rf.find_reactions() rg = ReactionGenerator(well0, par, qc, input_file) rg.generate() if par['homolytic_scissions'] == 1: logging.info('Starting the search for homolytic scission products') well0.homolytic_scissions = HomolyticScissions(well0, par, qc) well0.homolytic_scissions.find_homolytic_scissions() if par['me'] > 0: # it will be 2 for kinbots when the mess file is needed but not run mess = MESS(par, well0) mess.write_input(qc) if par['me'] == 1: logging.info('Starting Master Equation calculations') if par['me_code'] == 'mess': mess.run() postprocess.createSummaryFile(well0, qc, par) postprocess.createPESViewerInput(well0, qc, par) postprocess.creatMLInput(well0, qc, par) logging.info('Finished KinBot at {}'.format(datetime.datetime.now())) print("Done!")
def main(): try: input_file = sys.argv[1] except IndexError: print('To use KinBot, supply one argument being the input file!') sys.exit(-1) # print the license message to the console print(license_message.message) # initialize the parameters for this run par = Parameters(input_file) # set up the logging environment if par.par['verbose']: logging.basicConfig(filename='kinbot.log', level=logging.DEBUG) else: logging.basicConfig(filename='kinbot.log', level=logging.INFO) # write the license message to the log file logging.info(license_message.message) # time stamp of the KinBot start logging.info('Starting KinBot at {}'.format(datetime.datetime.now())) # Make the necessary directories if not os.path.exists('perm'): os.makedirs('perm') if not os.path.exists('scratch'): os.makedirs('scratch') if not os.path.exists(par.par['single_point_qc']): os.mkdir(par.par['single_point_qc']) if par.par['rotor_scan'] == 1: if not os.path.exists('hir'): os.mkdir('hir') if not os.path.exists('hir_profiles'): os.mkdir('hir_profiles') if not os.path.exists('perm/hir/'): os.makedirs('perm/hir/') if par.par['conformer_search'] == 1: if not os.path.exists('conf'): os.mkdir('conf') if not os.path.exists('perm/conf'): os.makedirs('perm/conf') if not os.path.exists('me'): os.mkdir('me') if par.par['pes'] and par.par['specific_reaction']: logging.error('Specific reaction cannot be searched in PES mode.') return # initialize the reactant well0 = StationaryPoint('well0', par.par['charge'], par.par['mult'], smiles=par.par['smiles'], structure=par.par['structure']) well0.short_name = 'w1' # wrtie the initial reactant geometry to a file for visualization geom_out = open('geometry.xyz', 'w') geom_out.write('{}\n\n'.format(well0.natom)) for i, at in enumerate(well0.atom): x, y, z = well0.geom[i] geom_out.write('{} {:.6f} {:.6f} {:.6f}\n'.format(at, x, y, z)) geom_out.write('\n\n') geom_out.close() # characterize the initial reactant well0.characterize(par.par['dimer']) well0.name = str(well0.chemid) start_name = well0.name # initialize the qc instance qc = QuantumChemistry(par) # start the initial optimization of the reactant logging.info('Starting optimization of intial well') qc.qc_opt(well0, well0.geom) err, well0.geom = qc.get_qc_geom(str(well0.chemid) + '_well', well0.natom, wait=1) err, well0.freq = qc.get_qc_freq(str(well0.chemid) + '_well', well0.natom, wait=1) if err < 0: logging.error('Error with initial structure optimization.') return if any(well0.freq[i] <= 0 for i in range(len(well0.freq))): logging.error('Found imaginary frequency for initial structure.') return # characterize again and look for differences well0.characterize(par.par['dimer']) well0.name = str(well0.chemid) if well0.name != start_name: logging.error('The first well optimized to a structure different from the input.') return # do an MP2 optimization of the reactant, # to compare Beta scission barrier heigths to logging.info('Starting MP2 optimization of intial well') qc.qc_opt(well0, well0.geom, mp2=1) err, geom = qc.get_qc_geom(str(well0.chemid) + '_well_mp2', well0.natom, 1) # characterize again and look for differences well0.characterize(par.par['dimer']) well0.name = str(well0.chemid) # read the energy and the zpe corrected energy err, well0.energy = qc.get_qc_energy(str(well0.chemid) + '_well', 1) err, well0.zpe = qc.get_qc_zpe(str(well0.chemid) + '_well', 1) well_opt = Optimize(well0, par, qc, wait=1) well_opt.do_optimization() if well_opt.shigh == -999: logging.error('Error with high level optimization of initial structure.') return # do the reaction search using heuristics if par.par['reaction_search'] == 1: logging.info('Starting reaction searches of intial well') rf = ReactionFinder(well0, par, qc) rf.find_reactions() rg = ReactionGenerator(well0, par, qc) rg.generate() # do the homolytic scission products search if par.par['homolytic_scissions'] == 1: logging.info('Starting the search for homolytic scission products') well0.homolytic_scissions = HomolyticScissions(well0, par, qc) well0.homolytic_scissions.find_homolytic_scissions() # initialize the master equation instance mess = MESS(par, well0) mess.write_input() mesmer = MESMER(par, well0) mesmer.write_input() if par.par['me'] == 1: logging.info('Starting Master Equation calculations') if par.par['me_code'] == 'mess': mess.run() elif par.par['me_code'] == 'mesmer': mesmer.run() else: logging.error('Cannot recognize me code {}'.format(par.par['me_code'])) # postprocess the calculations postprocess.createSummaryFile(well0, qc, par) postprocess.createPESViewerInput(well0, qc, par) postprocess.creatMLInput(well0, qc, par) logging.info('Finished KinBot at {}'.format(datetime.datetime.now())) print("Done!")