diff --git a/data/libraries.yml b/data/libraries.yml new file mode 100644 index 00000000..30549626 --- /dev/null +++ b/data/libraries.yml @@ -0,0 +1,153 @@ +# Recommended RMG libraries per application + +primary: + thermo: + - primaryThermoLibrary + - BurkeH2O2 + - Spiekermann_refining_elementary_reactions + - thermo_DFT_CCSDTF12_BAC + - DFT_QCI_thermo + - CBS_QB3_1dHR + kinetics: + - primaryH2O2 + +nitrogen: + thermo: + - NH3 + - NitrogenCurran + - CHON_G4 + - CN + - NOx2018 + - name: primaryNS + credence: low + - name: CHN + credence: low + - name: CHON + credence: low + - name: BurcatNS + credence: low + kinetics: + - primaryNitrogenLibrary + - HydrazinePDep + - Ethylamine + +sulfur: + thermo: + - name: primaryNS + credence: low + - name: SulfurGlarborgH2S + credence: low + - name: SulfurGlarborgBozzeli + credence: low + - name: BurcatNS + credence: low + kinetics: + - primarySulfurLibrary + - Sulfur/DMDS + - Sulfur/DMS + +combustion: + thermo: + - FFCM1(-) + - NOx2018 + - name: CHO + credence: low + kinetics: + - FFCM1(-) + - 2006_Joshi_OH_CO + - 2005_Senosiain_OH_C2H2 + - NOx2018 + +CH_pyrolysis: + thermo: + - NOx2018 + - Butadiene_Dimerization + - C10H11 + - s3_5_7_ane + - Fulvene_H + - naphthalene_H + - vinylCPD_H + - Lai_Hexylbenzene + - Narayanaswamy + - SABIC_aromatics_1dHR_extended + - SABIC_aromatics_1dHR + - SABIC_aromatics + - heavy_oil_ccsdtf12_1dHR + - bio_oil + - Chernov + - CurranPentane + - Klippenstein_Glarborg2016 + - name: CH + credence: low + kinetics: + - 2001_Tokmakov_H_Toluene_to_CH3_Benzene + - 2003_Miller_Propargyl_Recomb_High_P + - 2009_Sharma_C5H5_CH3_highP + - 2015_Buras_C2H3_C4H6_highP + - Butadiene_Dimerization + - C10H11 + - C12H11_pdep + - C2H2_init + - C6H5_C4H4_Mebel + - Fulvene_H + - Mebel_Naphthyl + - Mebel_C6H5_C2H2 + - biCPD_H_shift + - c-C5H5_CH3_Sharma + - fascella + - kislovB + - naphthalene_H + - vinylCPD_H + - First_to_Second_Aromatic_Ring/2005_Ismail_C6H5_C4H6_highP + - First_to_Second_Aromatic_Ring/2012_Matsugi_C3H3_C7H7_highP + - First_to_Second_Aromatic_Ring/2016_Mebel_C10H9_highP + - First_to_Second_Aromatic_Ring/2016_Mebel_C9H9_highP + - First_to_Second_Aromatic_Ring/2016_Mebel_Indene_CH3_highP + - First_to_Second_Aromatic_Ring/2017_Buras_C6H5_C3H6_highP + - First_to_Second_Aromatic_Ring/2017_Mebel_C6H4C2H_C2H2_highP + - First_to_Second_Aromatic_Ring/2017_Mebel_C6H5C2H2_C2H2_highP + - First_to_Second_Aromatic_Ring/2017_Mebel_C6H5_C2H2_highP + - First_to_Second_Aromatic_Ring/2017_Mebel_C6H5_C4H4_highP + - First_to_Second_Aromatic_Ring/phenyl_diacetylene_effective + - Aromatics_high_pressure/C10H10_1 + - Aromatics_high_pressure/C10H10_2 + - Aromatics_high_pressure/C10H10_H_abstraction + - Aromatics_high_pressure/C10H11_1 + - Aromatics_high_pressure/C10H11_2 + - Aromatics_high_pressure/C10H11_3 + - Aromatics_high_pressure/C10H11_4 + - Aromatics_high_pressure/C10H7 + - Aromatics_high_pressure/C10H8_H_abstraction_H_recomb + - Aromatics_high_pressure/C10H9_1 + - Aromatics_high_pressure/C10H9_2 + - Aromatics_high_pressure/C10H9_3 + - Aromatics_high_pressure/C10H9_4 + - Aromatics_high_pressure/C12H10_1 + - Aromatics_high_pressure/C12H10_2 + - Aromatics_high_pressure/C12H10_H_abstraction + - Aromatics_high_pressure/C12H11 + - Aromatics_high_pressure/C12H8_H_abstraction + - Aromatics_high_pressure/C12H9 + - Aromatics_high_pressure/C14H10_H_abstraction_H_recomb + - Aromatics_high_pressure/C14H11_1 + - Aromatics_high_pressure/C14H11_2 + - Aromatics_high_pressure/C14H11_3 + - Aromatics_high_pressure/C14H11_4 + - Aromatics_high_pressure/C14H9 + - Aromatics_high_pressure/C16H11 + - Aromatics_high_pressure/C7H8 + - Aromatics_high_pressure/C7H8_H_abstraction + - Aromatics_high_pressure/C7H9 + - Aromatics_high_pressure/C8H6_H_abstraction + - Aromatics_high_pressure/C8H7 + - Aromatics_high_pressure/C8H8_H_abstraction + - Aromatics_high_pressure/C8H9 + - Aromatics_high_pressure/C9H10_H_abstraction + - Aromatics_high_pressure/C9H11 + - Aromatics_high_pressure/C9H7 + - Aromatics_high_pressure/C9H8_1 + - Aromatics_high_pressure/C9H8_2 + - Aromatics_high_pressure/C9H8_H_abstraction + - Aromatics_high_pressure/C9H9_1 + - Aromatics_high_pressure/C9H9_2 + diff --git a/examples/commented/input.yml b/examples/commented/input.yml index a67ddefc..a90a0446 100644 --- a/examples/commented/input.yml +++ b/examples/commented/input.yml @@ -72,8 +72,10 @@ rmg: # database (a required block) database: - thermo_libraries: ['BurkeH2O2', 'DFT_QCI_thermo', 'primaryThermoLibrary', 'CBS_QB3_1dHR'] # *required*, can be an empty list - kinetics_libraries: ['BurkeH2O2inN2', 'NOx2018', 'Klippenstein_Glarborg2016'] # *required*, can be an empty list + thermo_libraries: ['BurkeH2O2', 'DFT_QCI_thermo', 'primaryThermoLibrary', 'CBS_QB3_1dHR'] # Can be None for auto-completion + kinetics_libraries: ['BurkeH2O2inN2', 'NOx2018', 'Klippenstein_Glarborg2016'] # Can be None for auto-completion + chemistry_sets: ['primary', 'nitrogen', 'combustion'] # The chemistry systems for which thermo and kinetics libraries will be loaded. Can be None to avoid auto-completion + use_low_credence_libraries: False # Whether to use low credence libraries during auto-completion, default: ``False`` transport_libraries: ['PrimaryTransportLibrary', 'OneDMinN2', 'NOx2018', 'GRI-Mech'] # optional, default: ['PrimaryTransportLibrary', 'OneDMinN2', 'NOx2018', 'GRI-Mech'] seed_mechanisms: [] # optional, default: [] kinetics_depositories: default # optional, default: 'default' diff --git a/t3/common.py b/t3/common.py index 5ce5c811..fc4a47fa 100644 --- a/t3/common.py +++ b/t3/common.py @@ -14,8 +14,9 @@ VERSION = '0.1.0' t3_path = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) # absolute path to the T3 folder -DATA_BASE_PATH = os.path.join(t3_path, 'tests', 'data') -SIMULATE_DATA_BASE_PATH = os.path.join(t3_path, 'tests', 'test_simulate_adapters', 'data') +DATA_BASE_PATH = os.path.join(t3_path, 'data') +TEST_DATA_BASE_PATH = os.path.join(t3_path, 'tests', 'data') +SIMULATE_TEST_DATA_BASE_PATH = os.path.join(t3_path, 'tests', 'test_simulate_adapters', 'data') EXAMPLES_BASE_PATH = os.path.join(t3_path, 'examples') SCRATCH_BASE_PATH = os.path.join(t3_path, 'tests', 'scratch') IPYTHON_SIMULATOR_EXAMPLES_PATH = os.path.join(t3_path, 'ipython', 'simulator_adapter_examples') diff --git a/t3/main.py b/t3/main.py index fd2a141f..1695c0a9 100755 --- a/t3/main.py +++ b/t3/main.py @@ -45,7 +45,12 @@ from arc.species.species import ARCSpecies, check_label from arc.species.converter import check_xyz_dict -from t3.common import PROJECTS_BASE_PATH, VALID_CHARS, delete_root_rmg_log, get_species_by_label, time_lapse +from t3.common import (DATA_BASE_PATH, + PROJECTS_BASE_PATH, + VALID_CHARS, + delete_root_rmg_log, + get_species_by_label, + time_lapse) from t3.logger import Logger from t3.runners.rmg_runner import rmg_runner from t3.schema import InputBase @@ -177,6 +182,7 @@ def __init__(self, self.project_directory = self.schema['project_directory'] self.t3 = self.schema['t3'] self.rmg = self.schema['rmg'] + self.rmg['database'] = auto_complete_rmg_libraries(database=self.rmg['database']) self.qm = self.schema['qm'] self.verbose = self.schema['verbose'] @@ -1538,3 +1544,38 @@ def get_species_with_qm_label(species: Species, rmg_species=qm_species, ) return qm_species + + +def auto_complete_rmg_libraries(database: dict) -> dict: + """ + Update the RMG libraries using auto-completion. + + Args: + database (dict): The RMG libraries dictionary. + + Returns: + dict: The updated RMG libraries dictionary. + """ + database['thermo_libraries'] = database['thermo_libraries'] or list() + database['kinetics_libraries'] = database['kinetics_libraries'] or list() + if database['chemistry_sets'] is not None: + libraries_dict = read_yaml_file(path=os.path.join(DATA_BASE_PATH, 'libraries.yml')) + low_credence = database['use_low_credence_libraries'] + for chemistry_set in database['chemistry_sets']: + if chemistry_set not in libraries_dict: + raise ValueError(f"Chemistry set '{chemistry_set}' not found in the libraries.yml file.") + for key, libraries in zip(['thermo', 'kinetics'], [database['thermo_libraries'], database['kinetics_libraries']]): + low_credence_libraries = list() + if key in libraries_dict[chemistry_set]: + for entry in libraries_dict[chemistry_set][key]: + if isinstance(entry, str) and entry not in libraries: + libraries.append(entry) + elif isinstance(entry, dict): + if entry['credence'] != 'low' and entry['name'] not in libraries: + libraries.append(entry['name']) + if entry['credence'] == 'low' and low_credence and entry['name'] not in libraries: + low_credence_libraries.append(entry['name']) + libraries.extend(low_credence_libraries) + del database['chemistry_sets'] + del database['use_low_credence_libraries'] + return database diff --git a/t3/schema.py b/t3/schema.py index b9d53d18..0cca7633 100644 --- a/t3/schema.py +++ b/t3/schema.py @@ -1,16 +1,17 @@ """ t3 schema module used for input validation - -Todo: add "live" validators for actually implemented adapters, need to access the respective factory register dicts """ +import os from enum import Enum from typing import Dict, List, Optional, Tuple, Union from pydantic import BaseModel, conint, confloat, constr, root_validator, validator -from t3.common import VALID_CHARS +from arc.common import read_yaml_file + +from t3.common import DATA_BASE_PATH, VALID_CHARS from t3.simulate.factory import _registered_simulate_adapters @@ -174,8 +175,10 @@ class RMGDatabase(BaseModel): """ A class for validating input.RMG.database arguments """ - thermo_libraries: List[str] - kinetics_libraries: List[str] + thermo_libraries: Optional[List[str]] = None + kinetics_libraries: Optional[List[str]] = None + chemistry_sets: Optional[List[str]] = None + use_low_credence_libraries: bool = False transport_libraries: List[str] = ['OneDMinN2', 'PrimaryTransportLibrary', 'NOx2018', 'GRI-Mech'] seed_mechanisms: List[str] = list() kinetics_depositories: Union[List[str], str] = 'default' @@ -185,6 +188,17 @@ class RMGDatabase(BaseModel): class Config: extra = "forbid" + @validator('chemistry_sets') + def check_chemistry_sets(cls, value, values): + """RMGDatabase.chemistry_sets validator""" + libraries_dict = read_yaml_file(path=os.path.join(DATA_BASE_PATH, 'libraries.yml')) + allowed_values = libraries_dict.keys() + if value and any(v not in allowed_values for v in value): + raise ValueError(f'The chemistry sets must be within of the following:\n{allowed_values}\nGot: {value}') + if value is None and (values['thermo_libraries'] is None or values['kinetics_libraries'] is None): + raise ValueError('The chemistry set must be specified if thermo or kinetics libraries are not specified.') + return value + class RadicalTypeEnum(str, Enum): """ diff --git a/tests/common.py b/tests/common.py index 57046196..304fb4e6 100644 --- a/tests/common.py +++ b/tests/common.py @@ -19,7 +19,18 @@ def run_minimal(project: Optional[str] = None, iteration: Optional[int] = None, set_paths: bool = False, ) -> T3: - """A helper function for running the minimal example""" + """ + A helper function for running the minimal example. + + Args: + project (str, optional): The project name. + project_directory (str, optional): The project directory. + iteration (int, optional): The iteration number. + set_paths (bool, optional): Whether to set the paths. + + Returns: + T3: The T3 object. + """ minimal_input = os.path.join(EXAMPLES_BASE_PATH, 'minimal', 'input.yml') input_dict = read_yaml_file(path=minimal_input) input_dict['verbose'] = 10 diff --git a/tests/test_common.py b/tests/test_common.py index 86eac63f..6d0bcec0 100644 --- a/tests/test_common.py +++ b/tests/test_common.py @@ -11,7 +11,7 @@ from rmgpy.species import Species import t3.common as common -from t3.common import DATA_BASE_PATH +from t3.common import TEST_DATA_BASE_PATH from t3.schema import RMGSpecies from tests.common import run_minimal @@ -33,7 +33,7 @@ def test_dict_to_str(): def test_get_species_by_label(): """Test getting species by label""" - t3 = run_minimal(project_directory=os.path.join(DATA_BASE_PATH, 'minimal_data'), + t3 = run_minimal(project_directory=os.path.join(TEST_DATA_BASE_PATH, 'minimal_data'), iteration=1, set_paths=True, ) @@ -131,7 +131,7 @@ def test_get_interval(): def test_get_chem_to_rmg_rxn_index_map(): """Test the get_chem_to_rmg_rxn_index_map() function""" - chemkin_path = os.path.join(DATA_BASE_PATH, 'chem_annotated_1.inp') + chemkin_path = os.path.join(TEST_DATA_BASE_PATH, 'chem_annotated_1.inp') rxn_map = common.get_chem_to_rmg_rxn_index_map(chem_annotated_path=chemkin_path) assert rxn_map == {1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 5, 7: 6, 8: 7, 9: 8, 10: 9, 11: 9, 12: 10, 13: 11, 14: 12, 15: 13, 16: 14, 17: 15, 18: 16, 19: 17, 20: 18, 21: 19, 22: 20, 23: 21, 24: 22, 25: 23, 26: 24, diff --git a/tests/test_functional.py b/tests/test_functional.py index f7d67d0c..899b763b 100644 --- a/tests/test_functional.py +++ b/tests/test_functional.py @@ -12,7 +12,7 @@ from arc.common import read_yaml_file from t3 import T3 -from t3.common import DATA_BASE_PATH +from t3.common import TEST_DATA_BASE_PATH from t3.runners.rmg_runner import backup_rmg_files from t3.utils.dependencies import check_dependencies @@ -58,7 +58,7 @@ def test_computing_thermo(): Tests computing thermo for two species and running RMG with the updated data Need xtb installed """ - functional_test_directory = os.path.join(DATA_BASE_PATH, 'functional_2_thermo') + functional_test_directory = os.path.join(TEST_DATA_BASE_PATH, 'functional_2_thermo') #delete_selective_content_from_test_dirs(test_dir=functional_test_directory) input_file = os.path.join(functional_test_directory, 'input.yml') input_dict = read_yaml_file(path=input_file) @@ -113,7 +113,7 @@ def test_rmg_files_backup_before_restart(): 3.chem_edge_annotated 4.RMG log files """ - backup_test_directory = os.path.join(DATA_BASE_PATH, 'backup_rmg_files_before_restart','iteration_1', 'RMG') + backup_test_directory = os.path.join(TEST_DATA_BASE_PATH, 'backup_rmg_files_before_restart','iteration_1', 'RMG') backup_rmg_files(backup_test_directory) # Find the backup directory (there should only be one per restart) backup_directories = [d for d in os.listdir(backup_test_directory) if d.startswith('restart_backup')] @@ -152,11 +152,11 @@ def delete_selective_content_from_test_dirs(test_dir: str): def teardown_module(): """teardown any state that was previously setup with a setup_module method.""" - test_dirs_to_selectively_delete = [os.path.join(DATA_BASE_PATH, 'functional_2_thermo'), + test_dirs_to_selectively_delete = [os.path.join(TEST_DATA_BASE_PATH, 'functional_2_thermo'), ] for test_dir in test_dirs_to_selectively_delete: delete_selective_content_from_test_dirs(test_dir) - test_dirs = [os.path.join(DATA_BASE_PATH, 'T3_functional_test_1'), + test_dirs = [os.path.join(TEST_DATA_BASE_PATH, 'T3_functional_test_1'), ] for test_dir in test_dirs: shutil.rmtree(test_dir, ignore_errors=True) diff --git a/tests/test_libraries.py b/tests/test_libraries.py index 821e98fa..37e99cb8 100644 --- a/tests/test_libraries.py +++ b/tests/test_libraries.py @@ -13,14 +13,14 @@ from rmgpy.thermo import ThermoData from rmgpy.statmech import Conformer, IdealGasTranslation, NonlinearRotor, HarmonicOscillator -from t3.common import DATA_BASE_PATH +from t3.common import TEST_DATA_BASE_PATH from tests.common import run_minimal from t3.utils.libraries import add_to_rmg_libraries def test_add_to_rmg_library(): """Test adding thermo calculations to an existing thermo library""" - libraries_path = os.path.join(DATA_BASE_PATH, 'libraries') + libraries_path = os.path.join(TEST_DATA_BASE_PATH, 'libraries') if not os.path.isdir(libraries_path): os.makedirs(libraries_path) @@ -153,6 +153,6 @@ def test_add_to_rmg_library(): def teardown_module(): """teardown any state that was previously set up.""" - path = os.path.join(DATA_BASE_PATH, 'libraries') + path = os.path.join(TEST_DATA_BASE_PATH, 'libraries') if os.path.isdir(path): shutil.rmtree(path, ignore_errors=True) diff --git a/tests/test_logger.py b/tests/test_logger.py index 7cf9ebd5..75911c70 100644 --- a/tests/test_logger.py +++ b/tests/test_logger.py @@ -10,11 +10,11 @@ import shutil from typing import Optional -from t3.common import DATA_BASE_PATH +from t3.common import TEST_DATA_BASE_PATH import t3.logger as logger -log_project_directory = os.path.join(DATA_BASE_PATH, 'log_file_testing_dir') +log_project_directory = os.path.join(TEST_DATA_BASE_PATH, 'log_file_testing_dir') def init_logger(project: str = 'project_name', diff --git a/tests/test_main.py b/tests/test_main.py index a3257947..35e25d04 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -19,9 +19,10 @@ from arc.common import read_yaml_file from arc.species import ARCSpecies -from t3.common import DATA_BASE_PATH, EXAMPLES_BASE_PATH, PROJECTS_BASE_PATH +from t3.common import TEST_DATA_BASE_PATH, EXAMPLES_BASE_PATH, PROJECTS_BASE_PATH from tests.common import run_minimal from t3.main import (T3, + auto_complete_rmg_libraries, legalize_species_label, get_reaction_by_index, get_species_label_by_structure) @@ -204,8 +205,8 @@ 'species': [], } -restart_base_path = os.path.join(DATA_BASE_PATH, 'restart') -dump_species_path = os.path.join(DATA_BASE_PATH, 'test_dump_species') +restart_base_path = os.path.join(TEST_DATA_BASE_PATH, 'restart') +dump_species_path = os.path.join(TEST_DATA_BASE_PATH, 'test_dump_species') def setup_module(): @@ -451,7 +452,7 @@ def test_run_arc(): def test_process_arc_run(): """Tests processing an ARC run and copying over a thermo library to the RMG-database repository""" t3 = run_minimal(project='T3', - project_directory=os.path.join(DATA_BASE_PATH, 'process_arc'), + project_directory=os.path.join(TEST_DATA_BASE_PATH, 'process_arc'), iteration=2, set_paths=True, ) @@ -539,7 +540,7 @@ def test_run_rmg(): def test_determine_species_to_calculate(): """Test determining the species to be calculated""" - t3 = run_minimal(project_directory=os.path.join(DATA_BASE_PATH, 'determine_species')) + t3 = run_minimal(project_directory=os.path.join(TEST_DATA_BASE_PATH, 'determine_species')) # 1. no calculations required t3.iteration = 1 @@ -586,7 +587,7 @@ def test_determine_species_to_calculate(): def test_species_requires_refinement(): """Test properly identifying the thermo comment of a species to determine whether it requires refinement""" - t3 = run_minimal(project_directory=os.path.join(DATA_BASE_PATH, 'determine_species')) + t3 = run_minimal(project_directory=os.path.join(TEST_DATA_BASE_PATH, 'determine_species')) spc_1 = Species(smiles='C') spc_1.thermo = NASA() spc_1.thermo.comment = 'Thermo group additivity estimation: group(O2s-(Cds-Cd)H) + missing(O2d-CO) + ' \ @@ -646,7 +647,7 @@ def test_species_requires_refinement(): def test_reaction_requires_refinement(): """Test properly identifying the kinetic comment of a reaction to determine whether it requires refinement""" - t3 = run_minimal(project_directory=os.path.join(DATA_BASE_PATH, 'determine_reactions'), + t3 = run_minimal(project_directory=os.path.join(TEST_DATA_BASE_PATH, 'determine_reactions'), iteration=1, set_paths=True, ) @@ -660,7 +661,7 @@ def test_reaction_requires_refinement(): def test_determine_species_based_on_sa(): """Test determining species to calculate based on sensitivity analysis""" - t3 = run_minimal(project_directory=os.path.join(DATA_BASE_PATH, 'minimal_data'), + t3 = run_minimal(project_directory=os.path.join(TEST_DATA_BASE_PATH, 'minimal_data'), iteration=1, set_paths=True, ) @@ -687,14 +688,14 @@ def test_determine_species_based_on_sa(): for dir_ in dirs: if os.path.isdir(dir_): shutil.rmtree(dir_, ignore_errors=True) - t3_log = os.path.join(DATA_BASE_PATH, 'minimal_data', 't3.log') + t3_log = os.path.join(TEST_DATA_BASE_PATH, 'minimal_data', 't3.log') if os.path.isfile(t3_log): os.remove(t3_log) def test_determine_species_from_pdep_network(): """Test determining species from pdep network""" - t3 = run_minimal(project_directory=os.path.join(DATA_BASE_PATH, 'pdep_network'), + t3 = run_minimal(project_directory=os.path.join(TEST_DATA_BASE_PATH, 'pdep_network'), iteration=1, set_paths=True, ) @@ -716,9 +717,9 @@ def test_determine_species_from_pdep_network(): def test_determine_species_based_on_collision_violators(): """Test determining species to calculate based on collision rate violating reactions""" t3 = run_minimal() - t3.paths['RMG coll vio'] = os.path.join(DATA_BASE_PATH, 'collision_rate_violators', 'collision_rate_violators.log') - t3.paths['chem annotated'] = os.path.join(DATA_BASE_PATH, 'collision_rate_violators', 'chem_annotated.inp') - t3.paths['species dict'] = os.path.join(DATA_BASE_PATH, 'collision_rate_violators', 'species_dictionary.txt') + t3.paths['RMG coll vio'] = os.path.join(TEST_DATA_BASE_PATH, 'collision_rate_violators', 'collision_rate_violators.log') + t3.paths['chem annotated'] = os.path.join(TEST_DATA_BASE_PATH, 'collision_rate_violators', 'chem_annotated.inp') + t3.paths['species dict'] = os.path.join(TEST_DATA_BASE_PATH, 'collision_rate_violators', 'species_dictionary.txt') t3.rmg_species, t3.rmg_reactions = t3.load_species_and_reactions_from_chemkin_file() species_to_calc = t3.determine_species_and_reactions_based_on_collision_violators()[0] assert len(species_to_calc) == 18 @@ -778,7 +779,7 @@ def test_trsh_rmg_tol(): def test_get_species_key(): """Test checking whether a species already exists in self.species and getting its key""" - t3 = run_minimal(project_directory=os.path.join(DATA_BASE_PATH, 'determine_species'), + t3 = run_minimal(project_directory=os.path.join(TEST_DATA_BASE_PATH, 'determine_species'), iteration=2, set_paths=True, ) @@ -799,7 +800,7 @@ def test_get_species_key(): def test_load_species_and_reactions_from_chemkin_file(): """Test loading RMG species and reactions from a Chemkin file""" - t3 = run_minimal(project_directory=os.path.join(DATA_BASE_PATH, 'determine_species'), + t3 = run_minimal(project_directory=os.path.join(TEST_DATA_BASE_PATH, 'determine_species'), iteration=2, set_paths=True, ) @@ -814,7 +815,7 @@ def test_load_species_and_reactions_from_chemkin_file(): def test_add_species(): """Test adding a species to self.species and to self.qm['species']""" - t3 = run_minimal(project_directory=os.path.join(DATA_BASE_PATH, 'determine_species'), + t3 = run_minimal(project_directory=os.path.join(TEST_DATA_BASE_PATH, 'determine_species'), iteration=2, set_paths=True, ) @@ -867,7 +868,7 @@ def test_add_species(): def test_add_reaction(): """Test adding a reaction to self.reactions and to self.qm['reactions']""" - t3 = run_minimal(project_directory=os.path.join(DATA_BASE_PATH, 'determine_reactions'), + t3 = run_minimal(project_directory=os.path.join(TEST_DATA_BASE_PATH, 'determine_reactions'), iteration=1, set_paths=True, ) @@ -978,7 +979,7 @@ def test_load_species(): def test_get_reaction_by_index(): """Test getting reaction by index""" - t3 = run_minimal(project_directory=os.path.join(DATA_BASE_PATH, 'minimal_data'), + t3 = run_minimal(project_directory=os.path.join(TEST_DATA_BASE_PATH, 'minimal_data'), iteration=1, set_paths=True, ) @@ -1007,7 +1008,7 @@ def test_legalize_species_label(): def test_get_species_label_by_structure(): """Test getting the species label from a list by its structure""" - t3 = run_minimal(project_directory=os.path.join(DATA_BASE_PATH, 'minimal_data'), + t3 = run_minimal(project_directory=os.path.join(TEST_DATA_BASE_PATH, 'minimal_data'), iteration=1, set_paths=True, ) @@ -1041,7 +1042,7 @@ def test_get_species_label_by_structure(): def test_check_overtime(): """Test checking overtime""" - t3 = run_minimal(project_directory=os.path.join(DATA_BASE_PATH, 'minimal_data'), + t3 = run_minimal(project_directory=os.path.join(TEST_DATA_BASE_PATH, 'minimal_data'), iteration=1, set_paths=True, ) @@ -1052,9 +1053,45 @@ def test_check_overtime(): assert t3.check_overtime() is True +def test_auto_complete_rmg_libraries(): + """Test auto completing RMG libraries""" + t3 = run_minimal(project_directory=os.path.join(TEST_DATA_BASE_PATH, 'minimal_data'), + iteration=1, + set_paths=True, + ) + assert t3.rmg['database']['thermo_libraries'] == ['primaryThermoLibrary'] + assert t3.rmg['database']['kinetics_libraries'] == [] + database_1 = t3.rmg['database'].copy() + database_1['chemistry_sets'] = None # auto_complete_rmg_libraries() is called upon initiation, these get deleted + database_1['use_low_credence_libraries'] = False + database_1 = auto_complete_rmg_libraries(database_1) + assert database_1['thermo_libraries'] == ['primaryThermoLibrary'] + assert database_1['kinetics_libraries'] == [] + assert 'chemistry_sets' not in database_1 + + database_2 = t3.rmg['database'].copy() + database_2['chemistry_sets'] = ['primary', 'nitrogen'] + database_2['use_low_credence_libraries'] = False + database_2 = auto_complete_rmg_libraries(database_2) + assert database_2['thermo_libraries'] == ['primaryThermoLibrary', 'BurkeH2O2', 'Spiekermann_refining_elementary_reactions', + 'thermo_DFT_CCSDTF12_BAC', 'DFT_QCI_thermo', 'CBS_QB3_1dHR', 'NH3', 'NitrogenCurran', + 'CHON_G4', 'CN', 'NOx2018'] + assert database_2['kinetics_libraries'] == ['primaryH2O2', 'primaryNitrogenLibrary', 'HydrazinePDep', 'Ethylamine'] + assert 'chemistry_sets' not in database_2 + + database_3 = t3.rmg['database'].copy() + database_3['chemistry_sets'] = ['primary', 'nitrogen'] + database_3['use_low_credence_libraries'] = True + database_3 = auto_complete_rmg_libraries(database_3) + assert database_3['thermo_libraries'] == ['primaryThermoLibrary', 'BurkeH2O2', 'Spiekermann_refining_elementary_reactions', + 'thermo_DFT_CCSDTF12_BAC', 'DFT_QCI_thermo', 'CBS_QB3_1dHR', 'NH3', 'NitrogenCurran', + 'CHON_G4', 'CN', 'NOx2018', 'primaryNS', 'CHN', 'CHON', 'BurcatNS'] + assert database_3['kinetics_libraries'] == ['primaryH2O2', 'primaryNitrogenLibrary', 'HydrazinePDep', 'Ethylamine'] + assert 'chemistry_sets' not in database_3 + + def teardown_module(): """teardown any state that was previously set up.""" - # delete log files for i in range(10): directory = os.path.join(restart_base_path, f'r{i}') @@ -1070,7 +1107,7 @@ def teardown_module(): files = [os.path.join(restart_base_path, 'r6', 'iteration_6', 'ARC', 'T3_ARC_restart_test.info'), os.path.join(restart_base_path, 'r6', 'iteration_6', 'ARC', 'input.yml'), os.path.join(restart_base_path, 'r6', 'species.yml'), - os.path.join(DATA_BASE_PATH, 'process_arc', 'species.yml'), + os.path.join(TEST_DATA_BASE_PATH, 'process_arc', 'species.yml'), ] for file in files: if os.path.isfile(file): @@ -1079,10 +1116,10 @@ def teardown_module(): # delete folders for directory in [test_minimal_project_directory, dump_species_path, - os.path.join(DATA_BASE_PATH, 'minimal_data', 'log_archive'), - os.path.join(DATA_BASE_PATH, 'determine_species', 'log_archive'), - os.path.join(DATA_BASE_PATH, 'pdep_network', 'log_archive'), - os.path.join(DATA_BASE_PATH, 'process_arc', 'log_archive'), + os.path.join(TEST_DATA_BASE_PATH, 'minimal_data', 'log_archive'), + os.path.join(TEST_DATA_BASE_PATH, 'determine_species', 'log_archive'), + os.path.join(TEST_DATA_BASE_PATH, 'pdep_network', 'log_archive'), + os.path.join(TEST_DATA_BASE_PATH, 'process_arc', 'log_archive'), os.path.join(restart_base_path, 'r6', 'iteration_6', 'ARC', 'output'), os.path.join(restart_base_path, 'r6', 'iteration_6', 'ARC', 'log_and_restart_archive'), ]: diff --git a/tests/test_rmg_runner.py b/tests/test_rmg_runner.py index fd458d6a..433f21de 100644 --- a/tests/test_rmg_runner.py +++ b/tests/test_rmg_runner.py @@ -6,7 +6,7 @@ """ import os -from t3.common import DATA_BASE_PATH, EXAMPLES_BASE_PATH +from t3.common import TEST_DATA_BASE_PATH, EXAMPLES_BASE_PATH from t3.runners.rmg_runner import rmg_job_converged, write_submit_script @@ -138,12 +138,12 @@ def test_minimal_parameters_set(self): def test_rmg_job_converged(self): """Test correctly identifying whether an RMG job converged ot not, and if not which error was received.""" - rmg_folder_1 = os.path.join(DATA_BASE_PATH, 'rmg_convergence', '1_frag_error') + rmg_folder_1 = os.path.join(TEST_DATA_BASE_PATH, 'rmg_convergence', '1_frag_error') converged, error = rmg_job_converged(project_directory=rmg_folder_1) assert not converged assert error == "AttributeError: 'Fragment' object has no attribute 'count_internal_rotors'" - rmg_folder_2 = os.path.join(DATA_BASE_PATH, 'rmg_convergence', '2_converged') + rmg_folder_2 = os.path.join(TEST_DATA_BASE_PATH, 'rmg_convergence', '2_converged') converged, error = rmg_job_converged(project_directory=rmg_folder_2) assert converged assert error is None diff --git a/tests/test_schema.py b/tests/test_schema.py index 70f1ba62..7076e71b 100644 --- a/tests/test_schema.py +++ b/tests/test_schema.py @@ -250,6 +250,8 @@ def test_rmg_database_schema(): assert rmg_database.kinetics_depositories == 'default' assert rmg_database.kinetics_families == 'default' assert rmg_database.kinetics_estimator == 'rate rules' + assert rmg_database.chemistry_sets is None + assert rmg_database.use_low_credence_libraries is False def test_rmg_species_schema(): diff --git a/tests/test_simulate_adapters/test_rmg_constantTP.py b/tests/test_simulate_adapters/test_rmg_constantTP.py index 181f3586..a508d635 100755 --- a/tests/test_simulate_adapters/test_rmg_constantTP.py +++ b/tests/test_simulate_adapters/test_rmg_constantTP.py @@ -8,12 +8,12 @@ import os import shutil -from t3.common import SIMULATE_DATA_BASE_PATH +from t3.common import SIMULATE_TEST_DATA_BASE_PATH from tests.common import run_minimal from t3.simulate.rmg_constantTP import RMGConstantTP -TEST_DIR = os.path.join(SIMULATE_DATA_BASE_PATH, 'rmg_simulator_test') +TEST_DIR = os.path.join(SIMULATE_TEST_DATA_BASE_PATH, 'rmg_simulator_test') def test_set_up_no_sa(): diff --git a/tests/test_writer.py b/tests/test_writer.py index 6cca1187..408cdb82 100644 --- a/tests/test_writer.py +++ b/tests/test_writer.py @@ -9,7 +9,7 @@ from arc.common import read_yaml_file -from t3.common import DATA_BASE_PATH, EXAMPLES_BASE_PATH +from t3.common import TEST_DATA_BASE_PATH, EXAMPLES_BASE_PATH from t3.schema import InputBase, RMG, T3 from t3.utils.writer import to_camel_case, write_rmg_input_file @@ -31,9 +31,9 @@ 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') + minimal_input_file_path = os.path.join(TEST_DATA_BASE_PATH, 'minimal_input.py') schema = InputBase(project=input_dict['project'], - project_directory=DATA_BASE_PATH, + project_directory=TEST_DATA_BASE_PATH, t3=input_dict['t3'], rmg=input_dict['rmg'], qm=input_dict['qm'], @@ -250,7 +250,7 @@ def test_write_rmg_input_file_liquid(): } } - file_path = os.path.join(DATA_BASE_PATH, 'test_write_rmg_input_file_liquid.py') + file_path = os.path.join(TEST_DATA_BASE_PATH, 'test_write_rmg_input_file_liquid.py') rmg_schema = RMG(**rmg).dict() # fill in defaults t3_schema = T3(**t3).dict() # fill in defaults @@ -315,7 +315,7 @@ def test_write_rmg_input_file_seed_all_radicals(): } } - file_path = os.path.join(DATA_BASE_PATH, 'test_write_rmg_input_file_seed_rads.py') + file_path = os.path.join(TEST_DATA_BASE_PATH, 'test_write_rmg_input_file_seed_rads.py') rmg_schema = RMG(**rmg).dict() # fill in defaults t3_schema = T3(**t3).dict() # fill in defaults