15
15
16
16
r"""AtomDB, a database of atomic and ionic properties."""
17
17
18
- from dataclasses import dataclass , field , asdict
19
-
20
- from glob import glob
21
-
22
- from importlib import import_module
23
-
24
18
import json
25
-
19
+ import re
20
+ from dataclasses import asdict , dataclass , field
21
+ from importlib import import_module
26
22
from numbers import Integral
27
-
28
23
from os import makedirs , path
29
24
30
- from msgpack import packb , unpackb
31
-
32
- from msgpack_numpy import encode , decode
33
-
34
25
import numpy as np
35
-
36
- from numpy import ndarray
37
-
38
26
import pooch
39
- import re
40
27
import requests
41
-
28
+ from msgpack import packb , unpackb
29
+ from msgpack_numpy import decode , encode
30
+ from numpy import ndarray
42
31
from scipy .interpolate import CubicSpline
43
32
44
- from atomdb .utils import DEFAULT_DATASET , DEFAULT_DATAPATH , DEFAULT_REMOTE
45
- from atomdb .periodic import element_symbol , Element
46
-
33
+ from atomdb .periodic import Element , element_symbol
34
+ from atomdb .utils import DEFAULT_DATAPATH , DEFAULT_DATASET , DEFAULT_REMOTE
47
35
48
36
__all__ = [
49
37
"Species" ,
@@ -166,7 +154,9 @@ def __init__(self, x, y, log=False):
166
154
self ._log = log
167
155
self ._obj = CubicSpline (
168
156
x ,
169
- np .log (y ) if log else y ,
157
+ # Clip y values to >= ε^2 if using log because they have to be above 0;
158
+ # having them be at least ε^2 seems to work based on my testing
159
+ np .log (y .clip (min = np .finfo (float ).eps ** 2 )) if log else y ,
170
160
axis = 0 ,
171
161
bc_type = "not-a-knot" ,
172
162
extrapolate = True ,
@@ -192,7 +182,9 @@ def __call__(self, x, deriv=0):
192
182
if not (0 <= deriv <= 2 ):
193
183
raise ValueError (f"Invalid derivative order { deriv } ; must be 0 <= `deriv` <= 2" )
194
184
elif self ._log :
195
- y = np .exp (self ._obj (x ))
185
+ # Get y = exp(log y). We'll handle errors from small log y values later.
186
+ with np .errstate (over = "ignore" ):
187
+ y = np .exp (self ._obj (x ))
196
188
if deriv == 1 :
197
189
# d(ρ(r)) = d(log(ρ(r))) * ρ(r)
198
190
dlogy = self ._obj (x , nu = 1 )
@@ -201,9 +193,13 @@ def __call__(self, x, deriv=0):
201
193
# d^2(ρ(r)) = d^2(log(ρ(r))) * ρ(r) + [d(ρ(r))]^2/ρ(r)
202
194
dlogy = self ._obj (x , nu = 1 )
203
195
d2logy = self ._obj (x , nu = 2 )
204
- y = d2logy .flatten () * y + dlogy .flatten () ** 2 * y
196
+ y = d2logy .flatten () * y + dlogy .flatten () ** 2 / y
205
197
else :
206
198
y = self ._obj (x , nu = deriv )
199
+ # Handle errors from the y = exp(log y) operation -- set NaN to zero
200
+ np .nan_to_num (y , nan = 0. , copy = False )
201
+ # Cutoff value: assume y(x) is zero where x > final given point x_n
202
+ y [x > self ._obj .x [- 1 ]] = 0
207
203
return y
208
204
209
205
@@ -218,7 +214,7 @@ def default(self, obj):
218
214
return JSONEncoder .default (self , obj )
219
215
220
216
221
- class _AtomicOrbitals ( object ) :
217
+ class _AtomicOrbitals :
222
218
"""Atomic orbitals class."""
223
219
224
220
def __init__ (self , data ) -> None :
@@ -883,13 +879,13 @@ def datafile(
883
879
url = f"{ remotepath } { dataset .lower ()} /db/repodata.txt" ,
884
880
known_hash = None ,
885
881
path = path .join (datapath , dataset .lower (), "db" ),
886
- fname = f "repo_data.txt" ,
882
+ fname = "repo_data.txt" ,
887
883
)
888
884
# if the file is not found or remote was not valid, use the local repodata file
889
885
except (requests .exceptions .HTTPError , ValueError ):
890
886
repodata = path .join (datapath , dataset .lower (), "db" , "repo_data.txt" )
891
887
892
- with open (repodata , "r" ) as f :
888
+ with open (repodata ) as f :
893
889
data = f .read ()
894
890
files = re .findall (rf"\b{ elem } +_{ charge } +_{ mult } +_{ nexc } \.msg\b" , data )
895
891
species_list = []
0 commit comments