3838from numbers import Integral
3939
4040elements_hdf5_file = files ("atomdb.data" ).joinpath ("elements_data.h5" )
41-
42- PROPERTY_NAME_MAP = {
43- "atmass" : "atmass" ,
44- "cov_radius" : "cov_radius" ,
45- "vdw_radius" : "vdw_radius" ,
46- "at_radius" : "at_radius" ,
47- "polarizability" : "polarizability" ,
48- "dispersion_c6" : "dispersion_c6" ,
49- "elem" : "symbol" ,
50- "atnum" : "atnum" ,
51- "name" : "name" ,
52- }
41+ ELEMENTS_H5FILE = pt .open_file (elements_hdf5_file , mode = "r" )
42+
43+ PROPERTY_NAME_MAP = [
44+ "atmass" ,
45+ "cov_radius" ,
46+ "vdw_radius" ,
47+ "at_radius" ,
48+ "polarizability" ,
49+ "dispersion_c6" ,
50+ "elem" ,
51+ "atnum" ,
52+ "name"
53+ ]
5354
5455__all__ = [
5556 "Species" ,
@@ -116,6 +117,42 @@ def default_matrix():
116117# return wrapper
117118
118119
120+ # def scalar(method):
121+ # r"""Expose a SpeciesData field."""
122+ # name = method.__name__
123+ #
124+ # @property
125+ # def wrapper(self):
126+ # print("hi")
127+ #
128+ # # Map the name of the method in the SpeciesData class to the name in the Elements class
129+ # # This dict can be removed if the Elements csv file uses the same names as the SpeciesData class.
130+ # namemap = {
131+ # "cov_radius": "cov_radius",
132+ # "vdw_radius": "vdw_radius",
133+ # "at_radius": "at_radius",
134+ # "polarizability": "pold",
135+ # "dispersion_c6": "c6",
136+ # "atmass": "mass",
137+ # }
138+ #
139+ # if name == "atmass":
140+ # print(f"inside atmass {getattr(Element(self._data.elem), namemap[name])}")
141+ # return getattr(Element(self._data.elem), namemap[name])
142+ # if name in namemap:
143+ # # Only return Element property if neutral, otherwise None
144+ # charge = self._data.atnum - self._data.nelec
145+ # print(f"charge {charge}")
146+ # print(f"inside the other {getattr(Element(self._data.elem), namemap[name])}")
147+ # return getattr(Element(self._data.elem), namemap[name]) if charge == 0 else None
148+ #
149+ # return getattr(self._data, name)
150+ #
151+ # # conserve the docstring of the method
152+ # wrapper.__doc__ = method.__doc__
153+ # return wrapper
154+
155+
119156def scalar (method ):
120157 r"""Expose a SpeciesData field."""
121158 name = method .__name__
@@ -128,39 +165,37 @@ def wrapper(self):
128165
129166 # calculate charge then if charge is not zero (ions) --> return none
130167 charge = self ._data .atnum - self ._data .nelec
131- if charge != 0 :
168+ if charge != 0 and name not in [ "atmass" , "elem" , "atnum" , "name" ] :
132169 return None
133170
134- # open the HDF5 file in read mode
135- with pt .open_file (elements_hdf5_file , mode = "r" ) as h5file :
136- # get the element group
137- element_group = f"/Elements/{ self ._data .atnum :03d} "
138-
139- table_name = PROPERTY_NAME_MAP [name ]
140- table_path = f"{ element_group } /{ table_name } "
141-
142- # get the table node from the HDF5 file
143- table = h5file .get_node (table_path )
144-
145- # Handle basic properties (single row)
146- if table .nrows == 1 :
147- value = table [0 ]["value" ]
148- # if the value is an int, return it as an int
149- if isinstance (value , Integral ):
150- return int (value )
151- # if the value is a string, decode from bytes
152- elif isinstance (value , bytes ):
153- return value .decode ("utf-8" )
154- else :
155- # handle properties with multiple sources
156- result = {}
157- for row in table :
158- source = row ["source" ].decode ("utf-8" )
159- value = row ["value" ]
160- # exclude none values
161- if not np .isnan (value ):
162- result [source ] = float (value )
163- return result if result else None
171+ # get the element group
172+ element_group = f"/Elements/{ self ._data .atnum :03d} "
173+
174+ table_name = name #PROPERTY_NAME_MAP[name]
175+ table_path = f"{ element_group } /{ table_name } "
176+
177+ # get the table node from the HDF5 file
178+ table = ELEMENTS_H5FILE .get_node (table_path )
179+
180+ # Handle basic properties (single column --> no sources)
181+ if len (table .colnames ) == 1 and table .colnames [0 ] == "value" :
182+ value = table [0 ]["value" ]
183+ # if the value is an int, return it as an int
184+ if isinstance (value , Integral ):
185+ return int (value )
186+ # if the value is a string, decode from bytes
187+ elif isinstance (value , bytes ):
188+ return value .decode ("utf-8" )
189+ else :
190+ # handle properties with multiple sources
191+ result = {}
192+ for row in table :
193+ source = row ["source" ].decode ("utf-8" )
194+ value = row ["value" ]
195+ # exclude none values
196+ if not np .isnan (value ):
197+ result [source ] = float (value )
198+ return result if result else None
164199
165200 wrapper .__doc__ = method .__doc__
166201 return wrapper
0 commit comments