12
12
import numpy as np
13
13
import toml
14
14
15
+ from mindlessgen .molecules .molecule import PSE_SYMBOLS
16
+
15
17
from ..molecules import PSE_NUMBERS
16
18
17
19
@@ -290,18 +292,19 @@ def element_composition(self):
290
292
291
293
@element_composition .setter
292
294
def element_composition (
293
- self , composition : None | str | dict [int , tuple [int | None , int | None ]]
295
+ self , composition : None | str | dict [int | str , tuple [int | None , int | None ]]
294
296
) -> None :
295
297
"""
296
- If composition_str : str, it should be a string with the format :
298
+ If composition : str:
297
299
Parses the element_composition string and stores the parsed data
298
300
in the _element_composition dictionary.
299
301
Format: "C:2-10, H:10-20, O:1-5, N:1-*"
300
- If composition_str: dict, it should be a dictionary with integer keys and tuple values. Will be stored as is.
302
+ If composition: dict:
303
+ Should be a dictionary with integer/string keys and tuple values. Will be stored as is.
301
304
302
305
Arguments:
303
306
composition_str (str): String with the element composition
304
- composition_str (dict): Dictionary with integer keys and tuple values
307
+ composition_str (dict): Dictionary with integer/str keys and tuple values
305
308
Raises:
306
309
TypeError: If composition_str is not a string or a dictionary
307
310
AttributeError: If the element is not found in the periodic table
@@ -312,25 +315,50 @@ def element_composition(
312
315
313
316
if not composition :
314
317
return
318
+
319
+ # Will return if composition dict does not contain either int or str keys and tuple[int | None, int | None] values
320
+ # Will also return if dict is valid after setting property
315
321
if isinstance (composition , dict ):
322
+ tmp = {}
323
+
324
+ # Check validity and also convert str keys into atomic numbers
316
325
for key , value in composition .items ():
317
326
if (
318
- not isinstance (key , int )
327
+ not ( isinstance (key , int ) or isinstance ( key , str ) )
319
328
or not isinstance (value , tuple )
320
329
or len (value ) != 2
321
330
or not all (isinstance (val , int ) or val is None for val in value )
322
331
):
323
332
raise TypeError (
324
- "Element composition dictionary should be a dictionary with integer keys and tuple values (int, int)."
333
+ "Element composition dictionary should be a dictionary with either integer or string keys and tuple values (int, int)."
325
334
)
326
- self ._element_composition = composition
335
+
336
+ # Convert str keys
337
+ if isinstance (key , str ):
338
+ element_number = PSE_NUMBERS .get (key .lower (), None )
339
+ if element_number is None :
340
+ raise KeyError (
341
+ f"Element { key } not found in the periodic table."
342
+ )
343
+ tmp [element_number - 1 ] = composition [key ]
344
+ # Check int keys
345
+ else :
346
+ if key + 1 in PSE_SYMBOLS :
347
+ tmp [key ] = composition [key ]
348
+ else :
349
+ raise KeyError (
350
+ f"Element with atomic number { key + 1 } (provided key: { key } ) not found in the periodic table."
351
+ )
352
+ self ._element_composition = tmp
327
353
return
354
+
328
355
if not isinstance (composition , str ):
329
356
raise TypeError (
330
357
"Element composition should be a string (will be parsed) or "
331
- + "a dictionary with integer keys and tuple values."
358
+ + "a dictionary with integer/string keys and tuple values."
332
359
)
333
360
361
+ # Parsing composition string
334
362
element_dict : dict [int , tuple [int | None , int | None ]] = {}
335
363
elements = composition .split ("," )
336
364
# remove leading and trailing whitespaces
@@ -537,9 +565,11 @@ def check_config(self, verbosity: int = 1) -> None:
537
565
if (
538
566
np .sum (
539
567
[
540
- self .element_composition .get (i , (0 , 0 ))[0 ]
541
- if self .element_composition .get (i , (0 , 0 ))[0 ] is not None
542
- else 0
568
+ (
569
+ self .element_composition .get (i , (0 , 0 ))[0 ]
570
+ if self .element_composition .get (i , (0 , 0 ))[0 ] is not None
571
+ else 0
572
+ )
543
573
for i in self .element_composition
544
574
]
545
575
)
0 commit comments