Skip to content

Commit 33f5046

Browse files
committed
Add optional year attribute to Level class
Allows differentiating between computational methods or functionals released in different years, such as b97d3 vs. b97d3 (2023). Includes validation for 4-digit year integers and updates string representations to reflect the version. This means that a user could add 'year' as a key in the input.yml for any of the {job}_level/arkane_level_of_theory, however, it will only be consumed when it's in arkane_level_of_theory. For {job}_level, it will be ignored (and user will be warned). The reason why this exists is because Level.build() iterates `allowed_keys` and passes them to the `__init__`. If we wanted to seriously enforce the year **only** for `arkane_level_of_theory` it would then need some serious refactoring to put it as a standalone attribute on ARC that attaches to arkane_level_of_theory I believe.
1 parent 1a72830 commit 33f5046

2 files changed

Lines changed: 21 additions & 1 deletion

File tree

arc/level.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ class Level(object):
3939
args (Dict[Dict[str, str]], optional): Additional arguments provided to the software.
4040
Different than the ``args`` in ``LevelOfTheory``.
4141
compatible_ess (list, optional): Entries are names of compatible ESS. Not in ``LevelOfTheory``.
42+
year (int, optional): Optional 4-digit year suffix for differentiating methods such as b97d3/b97d32023.
4243
"""
4344

4445
def __init__(self,
@@ -56,6 +57,7 @@ def __init__(self,
5657
solvent: Optional[str] = None,
5758
solvation_scheme_level: Optional['Level'] = None,
5859
args: Optional[Union[Dict[str, str], Iterable, str]] = None,
60+
year: Optional[int] = None,
5961
):
6062
self.repr = repr
6163
self.method = method
@@ -88,6 +90,12 @@ def __init__(self,
8890
'Both solvation method and solvent must be defined together, or both must be None. '
8991
f'Got solvation method = "{self.solvation_method}", solvent = "{self.solvent}".'
9092
)
93+
if year is not None:
94+
self.year = int(year)
95+
if self.year < 1000 or self.year > 9999:
96+
raise ValueError(f'year must be a 4-digit integer (1000-9999), got {self.year}.')
97+
else:
98+
self.year = None
9199
self.args = args or {'keyword': dict(), 'block': dict()}
92100

93101
if self.repr is not None:
@@ -122,6 +130,8 @@ def __str__(self) -> str:
122130
str_ = self.method
123131
if self.basis is not None:
124132
str_ += f'/{self.basis}'
133+
if self.year is not None:
134+
str_ += f', year: {self.year}'
125135
if self.auxiliary_basis is not None:
126136
str_ += f', auxiliary_basis: {self.auxiliary_basis}'
127137
if self.dispersion is not None:
@@ -165,6 +175,8 @@ def simple(self) -> str:
165175
str_ = self.method
166176
if self.basis is not None:
167177
str_ += f'/{self.basis}'
178+
if self.year is not None:
179+
str_ += f' ({self.year})'
168180
return str_
169181

170182
def as_dict(self) -> dict:
@@ -196,7 +208,8 @@ def build(self):
196208
'solvation_method': None,
197209
'solvent': None,
198210
'solvation_scheme_level': None,
199-
'args': None}
211+
'args': None,
212+
'year': None}
200213
allowed_keys = list(level_dict.keys())
201214

202215
if isinstance(self.repr, str):

arc/level_test.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,13 @@ def test_build(self):
119119
"dlpno-ccsd(t)/def2-tzvp, auxiliary_basis: def2-tzvp/c, solvation_method: smd, "
120120
"solvent: water, solvation_scheme_level: 'apfd/def2-tzvp, software: gaussian', software: orca")
121121

122+
def test_year_validation(self):
123+
"""Test year validation for Level"""
124+
with self.assertRaises(ValueError):
125+
Level(method='b97d3', basis='def2tzvp', year=23)
126+
level = Level(method='b97d3', basis='def2tzvp', year=2023)
127+
self.assertEqual(level.year, 2023)
128+
122129
def test_ess_methods_yml(self):
123130
"""Test reading the ess_methods.yml file"""
124131
ess_methods = read_yaml_file(path=os.path.join(ARC_PATH, 'data', 'ess_methods.yml'))

0 commit comments

Comments
 (0)