2828RMG_ENV_NAME = settings .get ('RMG_ENV_NAME' , 'rmg_env' )
2929logger = get_logger ()
3030
31+ # Section boundary markers in the RMG quantum_corrections/data.py file.
32+ AEC_SECTION_START = "atom_energies = {"
33+ AEC_SECTION_END = "pbac = {"
34+ PBAC_SECTION_START = "pbac = {"
35+ PBAC_SECTION_END = "mbac = {"
36+ MBAC_SECTION_START = "mbac = {"
37+ MBAC_SECTION_END = "freq_dict ="
38+ FREQ_SECTION_START = "freq_dict = {"
39+
3140
3241main_input_template = """#!/usr/bin/env python
3342# -*- coding: utf-8 -*-
@@ -699,7 +708,7 @@ def _extract_section(file_path: str, section_start: str, section_end: Optional[s
699708
700709
701710
702- def _get_qm_corrections_files () -> List [str ]:
711+ def get_qm_corrections_files () -> List [str ]:
703712 """
704713 Return quantum corrections data.py paths from the RMG database.
705714 """
@@ -834,7 +843,7 @@ def _format_years(years: List[Optional[int]]) -> str:
834843 return ", " .join ("none" if y is None else str (y ) for y in years )
835844
836845
837- def _find_best_across_files (level : "Level" ,
846+ def find_best_across_files (level : "Level" ,
838847 qm_corr_files : List [str ],
839848 section_start : str ,
840849 section_end : Optional [str ],
@@ -886,6 +895,10 @@ def _warn_no_match(level: "Level",
886895 f"available years: { _format_years (years )} . "
887896 f"Specify a year to select a matching entry."
888897 )
898+ else :
899+ logger .warning (
900+ f"No Arkane { label } entry found for { level .simple ()} in the RMG database."
901+ )
889902
890903
891904def _find_best_level_key_for_sp_level (level : "Level" ,
@@ -1015,33 +1028,28 @@ def get_arkane_model_chemistry(sp_level: 'Level',
10151028 Returns:
10161029 Optional[str]: Arkane-compatible model chemistry string.
10171030 """
1018- qm_corr_files = _get_qm_corrections_files ()
1019-
1020- aec_start = "atom_energies = {"
1021- aec_end = "pbac = {"
1022- freq_start = "freq_dict = {"
1023- freq_end = None # freq_dict is the last section in data.py; read to EOF
1031+ qm_corr_files = get_qm_corrections_files ()
10241032
10251033 # Composite methods and user-supplied freq_scale_factor both only need an AEC entry.
10261034 if sp_level .method_type == 'composite' or freq_scale_factor is not None :
1027- best_energy = _find_best_across_files (sp_level , qm_corr_files , aec_start , aec_end )
1035+ best_energy = find_best_across_files (sp_level , qm_corr_files , AEC_SECTION_START , AEC_SECTION_END )
10281036 if best_energy is None :
1029- _warn_no_match (sp_level , qm_corr_files , aec_start , aec_end , label = "AEC" )
1037+ _warn_no_match (sp_level , qm_corr_files , AEC_SECTION_START , AEC_SECTION_END , label = "AEC" )
10301038 return None
10311039 return best_energy
10321040
10331041 # CompositeLevelOfTheory: need both energy (AEC) and frequency entries.
10341042 if freq_level is None :
10351043 raise ValueError ("freq_level required when freq_scale_factor isn't provided" )
10361044
1037- best_energy = _find_best_across_files (sp_level , qm_corr_files , aec_start , aec_end )
1038- best_freq = _find_best_across_files (freq_level , qm_corr_files , freq_start , freq_end )
1045+ best_energy = find_best_across_files (sp_level , qm_corr_files , AEC_SECTION_START , AEC_SECTION_END )
1046+ best_freq = find_best_across_files (freq_level , qm_corr_files , FREQ_SECTION_START , None )
10391047
10401048 if best_energy is None or best_freq is None :
10411049 if best_energy is None :
1042- _warn_no_match (sp_level , qm_corr_files , aec_start , aec_end , label = "AEC" )
1050+ _warn_no_match (sp_level , qm_corr_files , AEC_SECTION_START , AEC_SECTION_END , label = "AEC" )
10431051 if best_freq is None :
1044- _warn_no_match (freq_level , qm_corr_files , freq_start , freq_end , label = "frequency correction" )
1052+ _warn_no_match (freq_level , qm_corr_files , FREQ_SECTION_START , None , label = "frequency correction" )
10451053 return None
10461054
10471055 return (
@@ -1052,6 +1060,33 @@ def get_arkane_model_chemistry(sp_level: 'Level',
10521060 )
10531061
10541062
1063+ def check_arkane_aec (sp_level : 'Level' , raise_error : bool = False ) -> bool :
1064+ """
1065+ Check that Arkane has AEC for the given sp level of theory (no BAC check).
1066+ Used when bac_type is None but we still want to verify AEC availability.
1067+
1068+ Args:
1069+ sp_level (Level): Level of theory for energy.
1070+ raise_error (bool): Whether to raise an error if AEC is missing.
1071+
1072+ Returns:
1073+ bool: True if AEC is available, False otherwise.
1074+ """
1075+ try :
1076+ qm_corr_files = get_qm_corrections_files ()
1077+ except InputError as e :
1078+ logger .warning (f'Could not load Arkane quantum corrections data: { e } ' )
1079+ return False
1080+ best_aec_key = find_best_across_files (sp_level , qm_corr_files , AEC_SECTION_START , AEC_SECTION_END )
1081+ if best_aec_key is not None :
1082+ logger .info (f'Arkane atom energy corrections (AEC) matched for { best_aec_key } (BAC disabled)' )
1083+ else :
1084+ _warn_no_match (sp_level , qm_corr_files , AEC_SECTION_START , AEC_SECTION_END , label = "AEC" )
1085+ if raise_error :
1086+ raise ValueError (f'Arkane has no atom energy corrections (AEC) for { _level_to_str (sp_level )} .' )
1087+ return best_aec_key is not None
1088+
1089+
10551090def check_arkane_bacs (sp_level : 'Level' ,
10561091 bac_type : str = 'p' ,
10571092 raise_error : bool = False ,
@@ -1071,19 +1106,19 @@ def check_arkane_bacs(sp_level: 'Level',
10711106 Returns:
10721107 bool: True if both AECs and BACs are available, False otherwise.
10731108 """
1074- qm_corr_files = _get_qm_corrections_files ()
1109+ try :
1110+ qm_corr_files = get_qm_corrections_files ()
1111+ except InputError as e :
1112+ logger .warning (f'Could not load Arkane quantum corrections data: { e } ' )
1113+ return False
10751114
1076- aec_start = "atom_energies = {"
1077- aec_end = "pbac = {"
10781115 if bac_type .lower () == 'm' :
1079- bac_start = "mbac = {"
1080- bac_end = "freq_dict ="
1116+ bac_start , bac_end = MBAC_SECTION_START , MBAC_SECTION_END
10811117 else :
1082- bac_start = "pbac = {"
1083- bac_end = "mbac = {"
1118+ bac_start , bac_end = PBAC_SECTION_START , PBAC_SECTION_END
10841119
1085- best_aec_key = _find_best_across_files (sp_level , qm_corr_files , aec_start , aec_end )
1086- best_bac_key = _find_best_across_files (sp_level , qm_corr_files , bac_start , bac_end )
1120+ best_aec_key = find_best_across_files (sp_level , qm_corr_files , AEC_SECTION_START , AEC_SECTION_END )
1121+ best_bac_key = find_best_across_files (sp_level , qm_corr_files , bac_start , bac_end )
10871122
10881123 has_aec = best_aec_key is not None
10891124 has_bac = best_bac_key is not None
@@ -1092,7 +1127,7 @@ def check_arkane_bacs(sp_level: 'Level',
10921127 if not has_encorr :
10931128 repr_level = best_aec_key if best_aec_key is not None else _level_to_str (sp_level )
10941129 year_note = ""
1095- aec_years = _all_available_years (sp_level , qm_corr_files , aec_start , aec_end )
1130+ aec_years = _all_available_years (sp_level , qm_corr_files , AEC_SECTION_START , AEC_SECTION_END )
10961131 bac_years = _all_available_years (sp_level , qm_corr_files , bac_start , bac_end )
10971132 if sp_level .year is not None :
10981133 year_note = (
@@ -1105,14 +1140,29 @@ def check_arkane_bacs(sp_level: 'Level',
11051140 f"available BAC years: { _format_years (bac_years )} . "
11061141 f"Specify a year to select a matching entry."
11071142 )
1108- mssg = (
1109- f"Arkane does not have the required energy corrections for { repr_level } "
1110- f"(AEC: { has_aec } , BAC: { has_bac } ).{ year_note } "
1111- )
1143+ if has_aec and not has_bac :
1144+ mssg = (
1145+ f"Arkane atom energy corrections (AEC) matched for { repr_level } , "
1146+ f"but bond additivity corrections (BAC) were NOT found in the RMG database. "
1147+ f"Thermo/kinetics results will use AEC but lack BAC.{ year_note } "
1148+ )
1149+ elif has_bac and not has_aec :
1150+ mssg = (
1151+ f"Arkane { bac_type .upper ()} BAC matched for { best_bac_key } , "
1152+ f"but atom energy corrections (AEC) were NOT found in the RMG database. "
1153+ f"Energy corrections will be disabled.{ year_note } "
1154+ )
1155+ else :
1156+ mssg = (
1157+ f"Arkane does not have atom energy corrections (AEC) or bond additivity corrections (BAC) "
1158+ f"for { repr_level } .{ year_note } "
1159+ )
11121160 if raise_error :
11131161 raise ValueError (mssg )
11141162 else :
11151163 logger .warning (mssg )
1164+ else :
1165+ logger .info (f'Arkane energy corrections matched for { best_aec_key } (AEC and { bac_type .upper ()} BAC)' )
11161166 return has_encorr
11171167
11181168
0 commit comments