def test_read_yaml_file(self): """Test the read_yaml_file() function""" restart_path = os.path.join(arc_path, 'arc', 'testing', 'restart', 'restart(H,H2O2,N2H3,CH3CO2).yml') input_dict = common.read_yaml_file(restart_path) self.assertIsInstance(input_dict, dict) self.assertTrue('reactions' in input_dict) self.assertTrue('freq_level' in input_dict) self.assertTrue('use_bac' in input_dict) self.assertTrue('ts_guess_level' in input_dict) self.assertTrue('running_jobs' in input_dict) with self.assertRaises(InputError): common.read_yaml_file('nopath')
def test_minimal_example(): """Tests that the minimal example is functional (ARC is not being called)""" delete_minimal_example_dirs() functional_minimal_directory = os.path.join(DATA_BASE_PATH, 'functional_minimal_example') input_file = os.path.join(functional_minimal_directory, 'input.yml') input_dict = read_yaml_file(path=input_file) verbose = 20 input_dict['verbose'] = verbose input_dict['project_directory'] = functional_minimal_directory # check that RMG and ARC are available check_dependencies() # run the minimal example t3_object = T3(**input_dict) t3_object.execute() # check that the minimal example ran to completion by checking for existence of some files and directories assert os.path.isfile(os.path.join(functional_minimal_directory, 't3.log')) assert os.path.isdir(os.path.join(functional_minimal_directory, 'iteration_1')) assert os.path.isfile(os.path.join(functional_minimal_directory, 'iteration_1', 'RMG', 'chemkin', 'species_dictionary.txt')) assert os.path.isdir(os.path.join(functional_minimal_directory, 'iteration_2')) assert os.path.isfile(os.path.join(functional_minimal_directory, 'iteration_2', 'RMG', 'chemkin', 'species_dictionary.txt')) delete_minimal_example_dirs()
def main() -> None: """ The main T3 executable function. """ args = parse_command_line_arguments() input_file = args.file project_directory = os.path.abspath(os.path.dirname(args.file)) input_dict = read_yaml_file(path=input_file) if 'project' not in list(input_dict.keys()): raise ValueError('A project name must be provided.') verbose = 20 if args.debug: verbose = 10 elif args.quiet: verbose = 30 input_dict['verbose'] = input_dict['verbose'] if 'verbose' in input_dict else verbose if 'project_directory' not in input_dict or not input_dict['project_directory']: input_dict['project_directory'] = project_directory # check that RMG and ARC are available check_dependencies() t3_object = T3(**input_dict) t3_object.execute()
def test_ess_methods_yml(self): """Test reading the ess_methods.yml file""" ess_methods = read_yaml_file( path=os.path.join(ARC_PATH, 'data', 'ess_methods.yml')) self.assertIsInstance(ess_methods, dict) for ess, methods in ess_methods.items(): self.assertIsInstance(ess, str) for method in methods: self.assertIsInstance(method, str) self.assertIn('gaussian', list(ess_methods.keys()))
def test_globalize_paths(self): """Test modifying a YAML file's contents to correct absolute file paths""" project_directory = os.path.join(ARC_PATH, 'arc', 'testing', 'restart', '4_globalized_paths') restart_path = os.path.join(project_directory, 'restart_paths.yml') input_dict = read_yaml_file(path=restart_path, project_directory=project_directory) input_dict['project_directory'] = project_directory ARC(**input_dict) globalized_restart_path = os.path.join(project_directory, 'restart_paths_globalized.yml') content = read_yaml_file( globalized_restart_path ) # not giving a project directory, this is tested in common self.assertEqual(content['output']['restart'], 'Restarted ARC at 2020-02-28 12:51:14.446086; ') self.assertIn( 'ARC/arc/testing/restart/4_globalized_paths/calcs/Species/HCN/freq_a38229/output.out', content['output']['spc']['paths']['freq']) self.assertNotIn('gpfs/workspace/users/user', content['output']['spc']['paths']['freq'])
def test_check_arc_args(): """Test the check_arc_args() method""" minimal_input = os.path.join(EXAMPLES_BASE_PATH, 'minimal', 'input.yml') input_dict = read_yaml_file(path=minimal_input) input_dict['verbose'] = 10 input_dict['project_directory'] = test_minimal_project_directory input_dict['qm'] = { 'adapter': 'ARC', 'unsupported_ARC_arg': 'value', 'bac_type': 'm', } t3 = T3(**input_dict) assert t3.qm['adapter'] == 'ARC' assert t3.qm['bac_type'] == 'm' assert 'unsupported_ARC_arg' not in t3.qm
def test_restart_bde(self): """Test restarting ARC and attaining reaction a rate coefficient""" restart_path = os.path.join(ARC_PATH, 'arc', 'testing', 'restart', '3_restart_bde', 'restart.yml') input_dict = read_yaml_file(path=restart_path) arc1 = ARC(**input_dict) arc1.execute() report_path = os.path.join(ARC_PATH, 'Projects', 'test_restart_bde', 'output', 'BDE_report.txt') with open(report_path, 'r') as f: lines = f.readlines() self.assertIn(' BDE report for anilino_radical:\n', lines) self.assertIn(' (1, 9) N - H 353.92\n', lines) self.assertIn(' (3, 4) C - H 454.12\n', lines) self.assertIn(' (5, 10) C - H 461.75\n', lines)
def parse_species_in_arc_input(input_path: str) -> dict: """ A function used to get species scope from the ARC input file. """ spc_info = {} try: input_file = read_yaml_file(input_path) except: # Bad input path return spc_info if not 'species' in input_file: # An input file without species information, weird! return spc_info for spc in input_file['species']: label = spc['label'] if 'smiles' in spc: try: spc_info[label] = { 'label': label, 'species': ARCSpecies(label=label, smiles=spc['smiles']), 'smiles': spc['smiles'], 'ts': False } except: pass elif 'xyz' in spc: try: mol = xyz_to_mol(spc['xyz']) except: pass else: smiles = mol.to_smiles() spc_info[label] = { 'label': label, 'species': ARCSpecies(label=label, smiles=smiles), 'smiles': smiles, 'ts': False } if label not in spc_info: # Cannot get smiles or xyz spc_info[label] = {'label': label, 'ts': False} return spc_info
def run_minimal( project: Optional[str] = None, project_directory: Optional[str] = None, iteration: Optional[int] = None, set_paths: bool = False, ) -> T3: """A helper function for running the minimal example""" minimal_input = os.path.join(EXAMPLES_BASE_PATH, 'minimal', 'input.yml') input_dict = read_yaml_file(path=minimal_input) input_dict['verbose'] = 10 input_dict['project_directory'] = project_directory \ or os.path.join(PROJECTS_BASE_PATH, 'test_minimal_delete_after_usage') if project is not None: input_dict['project'] = project t3 = T3(**input_dict) t3.iteration = iteration or 0 if set_paths: t3.set_paths() return t3
def determine_compatible_ess(self): """ Determine compatible ESS. """ if self.compatible_ess is None: # Don't append if the user already specified a restricted list. self.compatible_ess = list() ess_methods = read_yaml_file(path=os.path.join(arc_path, 'data', 'ess_methods.yml')) ess_methods = {ess: [method.lower() for method in methods] for ess, methods in ess_methods.items()} if self.method in ess_methods['gaussian']: self.compatible_ess.append('gaussian') if self.method in ess_methods['orca']: self.compatible_ess.append('orca') if self.method in ess_methods['qchem']: self.compatible_ess.append('qchem') if self.method in ess_methods['terachem']: self.compatible_ess.append('terachem') if self.method in ess_methods['molpro']: self.compatible_ess.append('molpro')
def main(): """The main ARC executable function""" # Parse the command-line arguments (requires the argparse module) args = parse_command_line_arguments() input_file = args.file input_dict = read_yaml_file(input_file) project_directory = os.path.abspath(os.path.dirname(args.file)) try: input_dict['project'] except KeyError: print('A project name must be provided!') verbose = logging.INFO if args.debug: verbose = logging.DEBUG elif args.quiet: verbose = logging.WARNING input_dict['verbose'] = input_dict['verbose'] if 'verbose' in input_dict else verbose arc_object = ARC(input_dict=input_dict, project_directory=project_directory) arc_object.execute()
def test_minimal_example(): """Tests that the minimal example is functional (ARC is not being called)""" input_file = os.path.join(functional_minimal_directory, 'input.yml') input_dict = read_yaml_file(path=input_file) verbose = 20 input_dict['verbose'] = verbose input_dict['project_directory'] = functional_minimal_directory # check that RMG and ARC are available check_dependencies() # run the minimal example t3_object = T3(**input_dict) t3_object.execute() # check that the minimal example ran to completion by checking for existence of some files and directories assert os.path.isfile(os.path.join(functional_minimal_directory, 't3.log')) assert os.path.isdir( os.path.join(functional_minimal_directory, 'iteration_0')) assert os.path.isfile( os.path.join(functional_minimal_directory, 'iteration_0', 'RMG', 'chemkin', 'species_dictionary.txt')) assert os.path.isdir( os.path.join(functional_minimal_directory, 'iteration_1')) assert os.path.isfile( os.path.join(functional_minimal_directory, 'iteration_1', 'RMG', 'chemkin', 'species_dictionary.txt')) # remove directories created by this functional test log_file = os.path.join(functional_minimal_directory, 't3.log') if os.path.isfile(log_file): os.remove(log_file) iteration_directories = [ os.path.join(functional_minimal_directory, f'iteration_{i}') for i in range(2) ] for iteration_dir in iteration_directories: if os.path.isdir(iteration_dir): shutil.rmtree(iteration_dir)
def test_restart_rate(self): """Test restarting ARC and attaining reaction a rate coefficient""" restart_path = os.path.join(ARC_PATH, 'arc', 'testing', 'restart', '2_restart_rate', 'restart.yml') input_dict = read_yaml_file(path=restart_path) project = 'arc_project_for_testing_delete_after_usage_restart_rate' project_directory = os.path.join(ARC_PATH, 'Projects', project) input_dict['project'], input_dict[ 'project_directory'] = project, project_directory arc1 = ARC(**input_dict) arc1.execute() kinetics_library_path = os.path.join(project_directory, 'output', 'RMG libraries', 'kinetics', 'reactions.py') with open(kinetics_library_path, 'r') as f: got_rate = False for line in f.readlines(): if "Arrhenius(A=(0.0636958,'cm^3/(mol*s)'), n=4.07981, Ea=(57.5474,'kJ/mol')" in line: got_rate = True break self.assertTrue(got_rate)
def test_globalize_paths(self): """Test modifying a file's contents to correct absolute file paths""" project_directory = os.path.join(common.arc_path, 'arc', 'testing', 'restart', '4_globalized_paths') restart_path = os.path.join(project_directory, 'restart_paths.yml') common.globalize_paths(file_path=restart_path, project_directory=project_directory) globalized_restart_path = os.path.join(project_directory, 'restart_paths_globalized.yml') content = common.read_yaml_file(globalized_restart_path) self.assertEqual(content['output']['restart'], 'Restarted ARC at 2020-02-28 12:51:14.446086; ') self.assertIn( 'ARC/arc/testing/restart/4_globalized_paths/calcs/Species/HCN/freq_a38229/output.out', content['output']['spc']['paths']['freq']) self.assertNotIn('gpfs/workspace/users/user', content['output']['spc']['paths']['freq']) path = '/home/user/runs/ARC/ARC_Project/calcs/Species/H/sp_a4339/output.out' new_path = common.globalize_path(path, project_directory) self.assertIn( '/ARC/arc/testing/restart/4_globalized_paths/calcs/Species/H/sp_a4339/output.out', new_path)
def combine_arc_species_inputs(*inputs: Union[list, tuple], resonance: bool = True): """ Combine the ARC species sections. Args: inputs: input files, either path or the actual ``dict``. resonance (bool): Generate resonance structures when checking isomorphism. Returns: dict: A dict contains combined species section. """ arc_inputs = [] for input_file in inputs: if isinstance(input_file, str): arc_inputs.append(read_yaml_file(input_file)) elif isinstance(input_file, dict): arc_inputs.append(input_file) spc_infos = [] for index, input_file in enumerate(arc_inputs): if not 'species' in input_file: raise ValueError( 'Invalid Input file which does not have species sections.') print( f'No.{index} input contains {len(input_file["species"])} species') spc_infos.append({spc['label']: spc for spc in input_file['species']}) combined_spc_info = combine_spc_infos(*spc_infos, resonance=resonance) print(f'The combined input contains {len(combined_spc_info)} species') # Generate ARC input arc_input = {'species': []} arc_input['species'] = [spc for spc in combined_spc_info.values()] return arc_input
def test_restart_thermo(self): """ Test restarting ARC through the ARC class in main.py via the input_dict argument of the API Rather than through ARC.py. Check that all files are in place and the log file content. """ restart_path = os.path.join(ARC_PATH, 'arc', 'testing', 'restart', '1_restart_thermo', 'restart.yml') input_dict = read_yaml_file(path=restart_path) project = 'arc_project_for_testing_delete_after_usage_restart_thermo' project_directory = os.path.join(ARC_PATH, 'Projects', project) input_dict['project'], input_dict[ 'project_directory'] = project, project_directory arc1 = ARC(**input_dict) arc1.execute() self.assertEqual(arc1.freq_scale_factor, 0.988) self.assertTrue( os.path.isfile( os.path.join(project_directory, 'output', 'thermo.info'))) with open(os.path.join(project_directory, 'output', 'thermo.info'), 'r') as f: thermo_dft_ccsdtf12_bac = False for line in f.readlines(): if 'thermo_DFT_CCSDTF12_BAC' in line: thermo_dft_ccsdtf12_bac = True break self.assertTrue(thermo_dft_ccsdtf12_bac) with open( os.path.join( project_directory, 'arc_project_for_testing_delete_after_usage_restart_thermo.info' ), 'r') as f: sts, n2h3, oet, lot, ap = False, False, False, False, False for line in f.readlines(): if 'Considered the following species and TSs:' in line: sts = True elif 'Species N2H3' in line: n2h3 = True elif 'Overall time since project initiation:' in line: oet = True elif 'Levels of theory used:' in line: lot = True elif 'ARC project arc_project_for_testing_delete_after_usage_restart_thermo' in line: ap = True self.assertTrue(sts) self.assertTrue(n2h3) self.assertTrue(oet) self.assertTrue(lot) self.assertTrue(ap) with open(os.path.join(project_directory, 'arc.log'), 'r') as f: aei, ver, git, spc, rtm, ldb, therm, src, ter =\ False, False, False, False, False, False, False, False, False for line in f.readlines(): if 'ARC execution initiated on' in line: aei = True elif '# Version:' in line: ver = True elif 'The current git HEAD for ARC is:' in line: git = True elif 'Considering species: CH3CO2_rad' in line: spc = True elif 'All jobs for species N2H3 successfully converged. Run time' in line: rtm = True elif 'Loading the RMG database...' in line: ldb = True elif 'Thermodynamics for H2O2' in line: therm = True elif 'Sources of thermoproperties determined by RMG for the parity plots:' in line: src = True elif 'ARC execution terminated on' in line: ter = True self.assertTrue(aei) self.assertTrue(ver) self.assertTrue(git) self.assertTrue(spc) self.assertTrue(rtm) self.assertTrue(ldb) self.assertTrue(therm) self.assertTrue(src) self.assertTrue(ter) self.assertTrue( os.path.isfile( os.path.join(project_directory, 'output', 'thermo_parity_plots.pdf'))) status = read_yaml_file( os.path.join(project_directory, 'output', 'status.yml')) self.assertEqual( status['CH3CO2_rad']['isomorphism'], 'opt passed isomorphism check; ' 'Conformers optimized and compared at b3lyp/6-31g(d,p) empiricaldispersion=gd3bj; ' ) self.assertTrue(status['CH3CO2_rad']['job_types']['sp']) with open( os.path.join(project_directory, 'output', 'Species', 'H2O2', 'arkane', 'species_dictionary.txt'), 'r') as f: lines = f.readlines() adj_list = '' for line in lines: if 'H2O2' not in line: adj_list += line if line == '\n': break mol1 = Molecule().from_adjacency_list(adj_list) self.assertEqual(mol1.to_smiles(), 'OO') thermo_library_path = os.path.join( project_directory, 'output', 'RMG libraries', 'thermo', 'arc_project_for_testing_delete_after_usage_restart_thermo.py') new_thermo_library_path = os.path.join( rmg_settings['database.directory'], 'thermo', 'libraries', 'arc_project_for_testing_delete_after_usage_restart_thermo.py') # copy the generated library to RMG-database shutil.copyfile(thermo_library_path, new_thermo_library_path) db = RMGDatabase() db.load( path=rmg_settings['database.directory'], thermo_libraries=[ 'arc_project_for_testing_delete_after_usage_restart_thermo' ], transport_libraries=[], reaction_libraries=[], seed_mechanisms=[], kinetics_families='none', kinetics_depositories=[], statmech_libraries=None, depository=False, solvation=False, testing=True, ) spc2 = Species(smiles='CC([O])=O') spc2.generate_resonance_structures() spc2.thermo = db.thermo.get_thermo_data(spc2) self.assertAlmostEqual(spc2.get_enthalpy(298), -212439.26998495663, 1) self.assertAlmostEqual(spc2.get_entropy(298), 283.3972662956835, 1) self.assertAlmostEqual(spc2.get_heat_capacity(1000), 118.751379824224, 1) self.assertTrue( 'arc_project_for_testing_delete_after_usage_restart_thermo' in spc2.thermo.comment) # delete the generated library from RMG-database os.remove(new_thermo_library_path)
def test_write_rmg_input_file(): """Test writing an RMG input file""" minimal_input = os.path.join(EXAMPLES_BASE_PATH, 'minimal', 'input.yml') input_dict = read_yaml_file(path=minimal_input) minimal_input_file_path = os.path.join(DATA_BASE_PATH, 'minimal_input.py') schema = InputBase( project=input_dict['project'], project_directory=DATA_BASE_PATH, t3=input_dict['t3'], rmg=input_dict['rmg'], qm=input_dict['qm'], verbose=20, ).dict() write_rmg_input_file(kwargs=schema['rmg'], iteration=2, path=minimal_input_file_path, walltime='01:00:00:00') # minimal input file with open(minimal_input_file_path, 'r') as f: content = f.read() expected_input = """database( thermoLibraries=['primaryThermoLibrary'], reactionLibraries=[], transportLibraries=['OneDMinN2', 'PrimaryTransportLibrary', 'NOx2018', 'GRI-Mech'], seedMechanisms=[], kineticsDepositories='default', kineticsFamilies='default', kineticsEstimator='rate rules', ) species( label='H2', reactive=True, structure=SMILES('[H][H]'), ) species( label='O2', reactive=True, structure=SMILES('[O][O]'), ) species( label='H', reactive=True, structure=SMILES('[H]'), ) species( label='OH', reactive=True, structure=SMILES('[OH]'), ) simpleReactor( temperature=(1000.0, 'K'), pressure=(1.0, 'bar'), initialMoleFractions={ 'H2': 0.67, 'O2': 0.33, 'H': 0, 'OH': 0, }, terminationConversion={'H2': 0.9}, terminationTime=(1000000.0, 's'), nSims=12, ) model( toleranceMoveToCore=0.001, toleranceInterruptSimulation=0.001, filterReactions=False, filterThreshold=100000000.0, maxNumObjsPerIter=1, terminateAtMaxObjects=False, ) simulator(atol=1e-16, rtol=1e-08) """ assert content == expected_input # other keys not in the minimal example schema['rmg']['pdep'] = { 'method': 'CSE', 'max_grain_size': 1.5, 'max_number_of_grains': 250, 'T': [300, 2500, 10], 'P': [1, 100, 10], 'interpolation': 'Chebyshev', 'T_basis_set': 6, 'P_basis_set': 4, 'max_atoms': 10, } schema['rmg']['options'] = { 'seed_name': 'Seed', 'save_edge': True, 'save_html': True, 'generate_seed_each_iteration': False, 'save_seed_to_database': False, 'units': 'si', 'generate_plots': False, 'save_simulation_profiles': False, 'verbose_comments': False, 'keep_irreversible': False, 'trimolecular_product_reversible': True, 'save_seed_modulus': -1, } schema['rmg']['species_constraints'] = { 'allowed': ['input species', 'seed mechanisms', 'reaction libraries'], 'max_C_atoms': 10, 'max_O_atoms': 4, 'max_N_atoms': 0, 'max_Si_atoms': 0, 'max_S_atoms': 1, 'max_heavy_atoms': 14, 'max_radical_electrons': 2, 'max_singlet_carbenes': 1, 'max_carbene_radicals': 0, 'allow_singlet_O2': False, } write_rmg_input_file(kwargs=schema['rmg'], iteration=2, path=minimal_input_file_path, walltime='01:00:00:00') # minimal input file with open(minimal_input_file_path, 'r') as f: lines = f.readlines() for line in [ "pressureDependence(\n", " method='chemically-significant eigenvalues',\n", " maximumGrainSize=(1.5, 'kJ/mol'),\n", " temperatures=(300, 2500, 'K', 10),\n", " pressures=(1, 100, 'bar', 10),\n", " interpolation=('Chebyshev', 6, 4),\n", "options(\n", " generateSeedEachIteration=False,\n", " generateOutputHTML=True,\n", " wallTime='01:00:00:00',\n", "generatedSpeciesConstraints(\n", " allowed=['input species', 'seed mechanisms', 'reaction libraries'],\n", " maximumCarbonAtoms=10,\n", " maximumOxygenAtoms=4,\n", " maximumNitrogenAtoms=0,\n", " maximumSulfurAtoms=1,\n", " maximumHeavyAtoms=14,\n", " maximumRadicalElectrons=2,\n", " maximumSingletCarbenes=1,\n", ]: assert line in lines os.remove(minimal_input_file_path)