feffdb 0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- feffdb/__init__.py +7 -0
- feffdb/apps.py +77 -0
- feffdb/feffdat.db +0 -0
- feffdb/feffdb.py +318 -0
- feffdb/feffpath.py +559 -0
- feffdb/schema.py +80 -0
- feffdb/simpledb.py +373 -0
- feffdb/utils.py +359 -0
- feffdb/version.py +24 -0
- feffdb-0.1.dist-info/METADATA +62 -0
- feffdb-0.1.dist-info/RECORD +15 -0
- feffdb-0.1.dist-info/WHEEL +5 -0
- feffdb-0.1.dist-info/entry_points.txt +2 -0
- feffdb-0.1.dist-info/licenses/LICENSE +28 -0
- feffdb-0.1.dist-info/top_level.txt +1 -0
feffdb/utils.py
ADDED
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""
|
|
3
|
+
very simple interface to CIF file for Feff DB
|
|
4
|
+
"""
|
|
5
|
+
import json
|
|
6
|
+
import os
|
|
7
|
+
import shutil
|
|
8
|
+
import sqlite3
|
|
9
|
+
import re
|
|
10
|
+
from io import IOBase
|
|
11
|
+
from charset_normalizer import from_bytes
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
from platformdirs import user_data_dir
|
|
14
|
+
from warnings import warn
|
|
15
|
+
from xraydb import XrayDB, atomic_mass, atomic_symbol
|
|
16
|
+
from xraydb.chemparser import chemparse
|
|
17
|
+
|
|
18
|
+
from pymatgen.io.cif import CifParser
|
|
19
|
+
|
|
20
|
+
from .schema import feffdb_schema, VERSIONS
|
|
21
|
+
|
|
22
|
+
FEFFDB_NAME = 'feffdat.db'
|
|
23
|
+
FEFFDB_ENV = 'FEFFDAT_DB'
|
|
24
|
+
LARCHDIR_ENV = 'LARCHDIR '
|
|
25
|
+
LARCHDIR_DEF = '.larch'
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def is_feffdb(db: str|sqlite3.Connection) -> bool:
|
|
29
|
+
"""test if database file or open connection is a valid Feffdata DB
|
|
30
|
+
|
|
31
|
+
a valid FEFFDB file has tables 'feffdat', 'feffinp', 'cif', 'element', and 'info'
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
feffdb_tables = ("element", "info", "feffdat", "feffinp", "cif")
|
|
35
|
+
if isinstance(db, sqlite3.Connection):
|
|
36
|
+
dbconn = db
|
|
37
|
+
else:
|
|
38
|
+
try:
|
|
39
|
+
dbconn = sqlite3.connect(db)
|
|
40
|
+
except Exception:
|
|
41
|
+
return False
|
|
42
|
+
|
|
43
|
+
cursor = dbconn.cursor()
|
|
44
|
+
cursor.execute("select name from sqlite_master where type='table';")
|
|
45
|
+
tables = [row[0] for row in cursor.fetchall()]
|
|
46
|
+
return all([tab in tables for tab in feffdb_tables])
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def get_feffdb(dbname:str|None=None) -> Path:
|
|
50
|
+
"""return Path to FEFF DB file
|
|
51
|
+
|
|
52
|
+
1. if the passed dbname is a valid FeffDB, that will be used.
|
|
53
|
+
2. if the Environmental Variable FEFFDAT_DB is set (and is a valid FeffDB),
|
|
54
|
+
that will be used.
|
|
55
|
+
4. Use `platformsdir.user_data_dir()` to find a `feffdb` folder.
|
|
56
|
+
if `feffdat.db` exists there, use that.
|
|
57
|
+
5. Try to create `platformsdir.user_data_dir('feffdb')` and copy
|
|
58
|
+
the feffdat.db there, and use that if it suceeeds.
|
|
59
|
+
|
|
60
|
+
Finally, if no valid FEFF DB can be found a ValueError will be raised.
|
|
61
|
+
"""
|
|
62
|
+
if dbname is None:
|
|
63
|
+
dbname = os.environ.get(FEFFDB_ENV, None)
|
|
64
|
+
if is_feffdb(dbname):
|
|
65
|
+
return Path(dbname)
|
|
66
|
+
|
|
67
|
+
parent = Path(user_data_dir('feffdb'))
|
|
68
|
+
parent.mkdir(mode=0o755, exist_ok=True)
|
|
69
|
+
dbpath = parent / FEFFDB_NAME
|
|
70
|
+
if is_feffdb(dbpath):
|
|
71
|
+
return dbpath
|
|
72
|
+
|
|
73
|
+
else:
|
|
74
|
+
here = Path(__file__).parent / FEFFDB_NAME
|
|
75
|
+
try:
|
|
76
|
+
shutil.copy(here, dbpath)
|
|
77
|
+
if is_feffdb(dbpath):
|
|
78
|
+
return dbpath
|
|
79
|
+
except Exception:
|
|
80
|
+
warn(f'could not install {FEFFDB_NAME} to {parent}')
|
|
81
|
+
|
|
82
|
+
raise ValueError("cannot find a valid Feff Database")
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def create_feffdb(dbname=None):
|
|
86
|
+
"""create FeffData.DB"""
|
|
87
|
+
if dbname is None:
|
|
88
|
+
dbpath = get_feffdb()
|
|
89
|
+
else:
|
|
90
|
+
dbpath = Path(dbname)
|
|
91
|
+
if dbpath.exists():
|
|
92
|
+
raise IOError(f"file {dbname} already exists")
|
|
93
|
+
dbpath.parent.mkdir(parents=True, mode=0o755, exist_ok=True)
|
|
94
|
+
|
|
95
|
+
conn = sqlite3.connect(dbpath)
|
|
96
|
+
c = conn.cursor()
|
|
97
|
+
for t in feffdb_schema.split(';'):
|
|
98
|
+
c.execute(t)
|
|
99
|
+
|
|
100
|
+
for version_dat in VERSIONS:
|
|
101
|
+
c.execute('insert into version values (?, ?, ?, ?)', version_dat)
|
|
102
|
+
|
|
103
|
+
xdb = XrayDB()
|
|
104
|
+
eltab = xdb.tables['elements']
|
|
105
|
+
q = []
|
|
106
|
+
for row in xdb.query(eltab).all():
|
|
107
|
+
c.execute('insert into element values (?, ?, ?, ?)',
|
|
108
|
+
(row.atomic_number, row.element, row.name, row.molar_mass))
|
|
109
|
+
conn.commit()
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def read_textfile(filename):
|
|
113
|
+
"""read text from a file as string
|
|
114
|
+
|
|
115
|
+
Argument
|
|
116
|
+
--------
|
|
117
|
+
filename (str or file): name of file to read or file-like object
|
|
118
|
+
|
|
119
|
+
Returns
|
|
120
|
+
-------
|
|
121
|
+
text of file as string.
|
|
122
|
+
|
|
123
|
+
Notes
|
|
124
|
+
------
|
|
125
|
+
1. the encoding is detected with charset_normalizer.from_bytes
|
|
126
|
+
which is then used to decode bytes read from file.
|
|
127
|
+
2. line endings are normalized to be '\n'.
|
|
128
|
+
"""
|
|
129
|
+
|
|
130
|
+
text = ''
|
|
131
|
+
def decode(bytedata):
|
|
132
|
+
return str(from_bytes(bytedata).best())
|
|
133
|
+
|
|
134
|
+
if isinstance(filename, IOBase):
|
|
135
|
+
text = filename.read()
|
|
136
|
+
if filename.mode == 'rb':
|
|
137
|
+
text = decode(text)
|
|
138
|
+
else:
|
|
139
|
+
with open(Path(filename), 'rb') as fh:
|
|
140
|
+
text = decode(fh.read())
|
|
141
|
+
return text.replace('\r\n', '\n').replace('\r', '\n')
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def get_filename_and_text(fname):
|
|
145
|
+
if isinstance(fname, Path):
|
|
146
|
+
fname = fname.absolute().resolve().as_posix()
|
|
147
|
+
text = read_textfile(fname)
|
|
148
|
+
elif isinstance(fname, str) and len(fname) < 255:
|
|
149
|
+
fname = Path(fname).absolute().resolve().as_posix()
|
|
150
|
+
text = read_textfile(fname)
|
|
151
|
+
else:
|
|
152
|
+
text = fname
|
|
153
|
+
fname = '<unknown>'
|
|
154
|
+
return fname, text
|
|
155
|
+
|
|
156
|
+
def parse_cif(ciffile):
|
|
157
|
+
ciffile, ciftext = get_filename_and_text(ciffile)
|
|
158
|
+
|
|
159
|
+
try:
|
|
160
|
+
cif = CifParser.from_str(ciftext, occupancy_tolerance=10, site_tolerance=0.005)
|
|
161
|
+
except Exception:
|
|
162
|
+
raise ValueError(f'invalid CIF {ciffile}')
|
|
163
|
+
|
|
164
|
+
cifkey = list(cif._cif.data.keys())[0]
|
|
165
|
+
dat = cif._cif.data[cifkey].data
|
|
166
|
+
|
|
167
|
+
formula = None
|
|
168
|
+
for formname in ('_chemical_formula_sum', '_chemical_formula_moiety'):
|
|
169
|
+
if formname in dat:
|
|
170
|
+
try:
|
|
171
|
+
parsed_formula = chemparse(dat[formname])
|
|
172
|
+
formula = dat[formname].replace(' ', '')
|
|
173
|
+
except:
|
|
174
|
+
print("Could not parse ", dat[formname])
|
|
175
|
+
|
|
176
|
+
if formula is None and '_atom_site_type_symbol' in dat:
|
|
177
|
+
comps = {}
|
|
178
|
+
complist = dat['_atom_site_type_symbol']
|
|
179
|
+
for c in complist:
|
|
180
|
+
if c not in comps:
|
|
181
|
+
nx = complist.count(c)
|
|
182
|
+
comps[c] = '%s%d' % (c, nx) if nx != 1 else c
|
|
183
|
+
formula = ''.join(comps.values())
|
|
184
|
+
|
|
185
|
+
if formula is None:
|
|
186
|
+
raise ValueError(f'Cannot read chemical formula from CIF {ciffile}')
|
|
187
|
+
|
|
188
|
+
# compound
|
|
189
|
+
compound = '<missing>'
|
|
190
|
+
for compname in ('_chemical_compound_source',
|
|
191
|
+
'_chemical_name_systematic',
|
|
192
|
+
'_chemical_name_common',
|
|
193
|
+
'_chemical_name_mineral'):
|
|
194
|
+
if compname in dat:
|
|
195
|
+
compound = dat[compname]
|
|
196
|
+
|
|
197
|
+
# get spacegroup and symmetry
|
|
198
|
+
sgroup_name = dat.get('_symmetry_space_group_name_H-M', None)
|
|
199
|
+
if sgroup_name is None:
|
|
200
|
+
for key, val in dat.items():
|
|
201
|
+
if 'space_group' in key and 'H-M' in key:
|
|
202
|
+
sgroup_name = val
|
|
203
|
+
|
|
204
|
+
source_db = ''
|
|
205
|
+
source_id = -1
|
|
206
|
+
amcsd_id = dat.get('_database_code_amcsd', None)
|
|
207
|
+
if amcsd_id is not None:
|
|
208
|
+
source_db = 'amcsd'
|
|
209
|
+
source_id = amcsd_id
|
|
210
|
+
|
|
211
|
+
return {'text': ciftext, 'filename': ciffile,
|
|
212
|
+
'formula': formula, 'compound': compound,
|
|
213
|
+
'space_group': sgroup_name,
|
|
214
|
+
'source_db': source_db, 'source_id': source_id}
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
def parse_feffinp(feffinp):
|
|
218
|
+
"""parse feff.inp just enough for FeffDB"""
|
|
219
|
+
|
|
220
|
+
feffinp, text = get_filename_and_text(feffinp)
|
|
221
|
+
|
|
222
|
+
edge = ''
|
|
223
|
+
absorber = 0
|
|
224
|
+
ipots = []
|
|
225
|
+
natoms = 0
|
|
226
|
+
mode = None
|
|
227
|
+
for line in text.split('\n'):
|
|
228
|
+
line = line.strip()
|
|
229
|
+
if line.startswith('*') or line.startswith('#'):
|
|
230
|
+
continue
|
|
231
|
+
|
|
232
|
+
if line.lower().startswith('edge'):
|
|
233
|
+
words = line.split(' ')
|
|
234
|
+
edge = words[1].upper()
|
|
235
|
+
elif line.lower().startswith('potent'):
|
|
236
|
+
mode = 'pot'
|
|
237
|
+
elif line.lower().startswith('atoms'):
|
|
238
|
+
mode = 'atoms'
|
|
239
|
+
elif line.lower().startswith('end'):
|
|
240
|
+
mode = None
|
|
241
|
+
elif mode == 'pot':
|
|
242
|
+
if line.startswith('0'):
|
|
243
|
+
words = line.strip().split()
|
|
244
|
+
absorber = int(words[1])
|
|
245
|
+
elif len(line) > 6:
|
|
246
|
+
words = line.strip().split()
|
|
247
|
+
ipots.append(int(words[1]))
|
|
248
|
+
elif mode == 'atoms':
|
|
249
|
+
try:
|
|
250
|
+
words = line.strip().split()
|
|
251
|
+
w = [float(x) for x in words[:4]]
|
|
252
|
+
natoms += 1
|
|
253
|
+
except (ValueError, TypeError):
|
|
254
|
+
pass
|
|
255
|
+
|
|
256
|
+
return {'text': text, 'filename': feffinp, 'absorber': absorber,
|
|
257
|
+
'edge': edge, 'scatterers': json.dumps(ipots), 'natoms': natoms}
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
def parse_feffdat(feffdatfile):
|
|
261
|
+
"""parse feffdat just enough for FeffDB"""
|
|
262
|
+
feffdatfile, fefftext = get_filename_and_text(feffdatfile)
|
|
263
|
+
|
|
264
|
+
mode = 'header'
|
|
265
|
+
potentials, geom, data = [], [],[]
|
|
266
|
+
version, pcounter, iline = '', 0, 0
|
|
267
|
+
reff = 0.0
|
|
268
|
+
lines = fefftext.split('\n')
|
|
269
|
+
|
|
270
|
+
if 'feff' not in lines[0].lower()[:]:
|
|
271
|
+
raise ValueError(f'Not a valid feff.dat file: {feffdatfile}')
|
|
272
|
+
|
|
273
|
+
for line in lines:
|
|
274
|
+
iline += 1
|
|
275
|
+
line = line[:-1].strip()
|
|
276
|
+
if line.startswith('#'):
|
|
277
|
+
line = line[1:].strip()
|
|
278
|
+
|
|
279
|
+
if iline == 1:
|
|
280
|
+
title = line[:64].strip()
|
|
281
|
+
version = line[64:].strip()
|
|
282
|
+
continue
|
|
283
|
+
if line.startswith('k') and 'mag[feff]' in line:
|
|
284
|
+
mode = 'arrays'
|
|
285
|
+
break
|
|
286
|
+
elif '----' in line[2:10]:
|
|
287
|
+
mode = 'path'
|
|
288
|
+
continue
|
|
289
|
+
#
|
|
290
|
+
if (mode == 'header' and
|
|
291
|
+
(re.match(r'^Abs\b', line) or re.match(r'^Pot\s+\d+\b', line)) and
|
|
292
|
+
re.search(r'\bZ\s*=', line)):
|
|
293
|
+
words = line.replace('=', ' ').split()
|
|
294
|
+
ipot, z, rmt, rnm = (0, 0, 0, 0)
|
|
295
|
+
words.pop(0)
|
|
296
|
+
if re.match(r'^Pot\s+\d+\b', line):
|
|
297
|
+
ipot = int(words.pop(0))
|
|
298
|
+
iz = int(words[1])
|
|
299
|
+
rmt = float(words[3])
|
|
300
|
+
rnm = float(words[5])
|
|
301
|
+
if re.match(r'^Abs\b', line):
|
|
302
|
+
edge = words[6]
|
|
303
|
+
potentials.append((ipot, iz, rmt, rnm))
|
|
304
|
+
elif mode == 'header' and re.match(r'^Gam_ch\s*=', line):
|
|
305
|
+
pass
|
|
306
|
+
elif mode == 'header' and re.match(r'^Mu\s*=', line):
|
|
307
|
+
pass
|
|
308
|
+
elif mode == 'path':
|
|
309
|
+
pcounter += 1
|
|
310
|
+
if pcounter == 1:
|
|
311
|
+
w = [float(x) for x in line.split()[:5]]
|
|
312
|
+
nleg = int(w.pop(0))
|
|
313
|
+
degen, reff, rnorman, e_edge = w
|
|
314
|
+
elif pcounter > 2:
|
|
315
|
+
words = line.split()
|
|
316
|
+
xyz = [float(x) for x in words[:3]]
|
|
317
|
+
ipot = int(words[3])
|
|
318
|
+
iz = int(words[4])
|
|
319
|
+
if len(words) > 5:
|
|
320
|
+
lab = words[5]
|
|
321
|
+
else:
|
|
322
|
+
lab = atomic_symbol(iz)
|
|
323
|
+
amass = atomic_mass(iz)
|
|
324
|
+
this_geom = [lab, iz, ipot, amass] + xyz
|
|
325
|
+
if len(geom) == 0:
|
|
326
|
+
absorber = lab
|
|
327
|
+
geom.append(tuple(this_geom))
|
|
328
|
+
elif mode == 'arrays':
|
|
329
|
+
break
|
|
330
|
+
|
|
331
|
+
if len(geom) < 2:
|
|
332
|
+
raise ValueError(f'could not read Path from feff.dat file: {feffdatfile}')
|
|
333
|
+
|
|
334
|
+
absorber = geom[0][1]
|
|
335
|
+
scatterer = geom[1][1]
|
|
336
|
+
|
|
337
|
+
return {'text': fefftext, 'filename': feffdatfile,
|
|
338
|
+
'absorber': absorber, 'scatterer': scatterer,
|
|
339
|
+
'reff': reff, 'degen': degen, 'nleg': nleg,
|
|
340
|
+
'edge': edge, 'geometry': json.dumps(geom)}
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
if __name__ == '__main__':
|
|
345
|
+
print("CIF")
|
|
346
|
+
out = parse_cif('../fayalite.cif')
|
|
347
|
+
print(out.keys())
|
|
348
|
+
print(len(out['text']))
|
|
349
|
+
for key, val in out.items():
|
|
350
|
+
if key != 'text':
|
|
351
|
+
print(key, val)
|
|
352
|
+
|
|
353
|
+
print("FEFF:")
|
|
354
|
+
out = parse_feffdat('../feff0001.dat')
|
|
355
|
+
print(out.keys())
|
|
356
|
+
print(len(out['text']))
|
|
357
|
+
for key, val in out.items():
|
|
358
|
+
if key != 'text':
|
|
359
|
+
print(key, val)
|
feffdb/version.py
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# file generated by vcs-versioning
|
|
2
|
+
# don't change, don't track in version control
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
__all__ = [
|
|
6
|
+
"__version__",
|
|
7
|
+
"__version_tuple__",
|
|
8
|
+
"version",
|
|
9
|
+
"version_tuple",
|
|
10
|
+
"__commit_id__",
|
|
11
|
+
"commit_id",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
version: str
|
|
15
|
+
__version__: str
|
|
16
|
+
__version_tuple__: tuple[int | str, ...]
|
|
17
|
+
version_tuple: tuple[int | str, ...]
|
|
18
|
+
commit_id: str | None
|
|
19
|
+
__commit_id__: str | None
|
|
20
|
+
|
|
21
|
+
__version__ = version = '0.1'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 1)
|
|
23
|
+
|
|
24
|
+
__commit_id__ = commit_id = 'ga71d582ee'
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: feffdb
|
|
3
|
+
Version: 0.1
|
|
4
|
+
Summary: Sqlite Database for Feff.dat files, especially for 1st shell EXAFS
|
|
5
|
+
Author-email: Matthew Newville <matt.newville@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/xraypy/feffdb
|
|
8
|
+
Project-URL: Documentation, https://xraypy.github.io/feffdb
|
|
9
|
+
Project-URL: Tracker, https://github.com/xraypy/feffdb/issues
|
|
10
|
+
Keywords: Feff,EXAFS
|
|
11
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
12
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Operating System :: MacOS :: MacOS X
|
|
15
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
16
|
+
Classifier: Operating System :: POSIX
|
|
17
|
+
Classifier: Topic :: Scientific/Engineering
|
|
18
|
+
Classifier: Topic :: Scientific/Engineering :: Visualization
|
|
19
|
+
Classifier: Programming Language :: Python
|
|
20
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.15
|
|
26
|
+
Requires-Python: >=3.11
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
License-File: LICENSE
|
|
29
|
+
Requires-Dist: xraydb
|
|
30
|
+
Requires-Dist: numpy>=2.2
|
|
31
|
+
Requires-Dist: scipy
|
|
32
|
+
Requires-Dist: charset_normalizer
|
|
33
|
+
Requires-Dist: sqlalchemy>=2
|
|
34
|
+
Requires-Dist: pymatgen>=2025.6.14
|
|
35
|
+
Requires-Dist: pyshortcuts>=1.9.8
|
|
36
|
+
Requires-Dist: tabulate
|
|
37
|
+
Provides-Extra: dev
|
|
38
|
+
Requires-Dist: build; extra == "dev"
|
|
39
|
+
Requires-Dist: twine; extra == "dev"
|
|
40
|
+
Provides-Extra: doc
|
|
41
|
+
Requires-Dist: sphinx; extra == "doc"
|
|
42
|
+
Requires-Dist: sphinx-copybutton; extra == "doc"
|
|
43
|
+
Requires-Dist: sphinx-design; extra == "doc"
|
|
44
|
+
Requires-Dist: sphinxcontrib-video; extra == "doc"
|
|
45
|
+
Requires-Dist: jupyter_sphinx; extra == "doc"
|
|
46
|
+
Requires-Dist: nbsphinx; extra == "doc"
|
|
47
|
+
Provides-Extra: test
|
|
48
|
+
Requires-Dist: pytest; extra == "test"
|
|
49
|
+
Requires-Dist: pytest-cov; extra == "test"
|
|
50
|
+
Requires-Dist: coverage; extra == "test"
|
|
51
|
+
Provides-Extra: all
|
|
52
|
+
Requires-Dist: feffdb[dev,doc,test]; extra == "all"
|
|
53
|
+
Dynamic: license-file
|
|
54
|
+
|
|
55
|
+
# FeffDB
|
|
56
|
+
|
|
57
|
+
Feff DB is an SQLite3 database and Python library for the results of
|
|
58
|
+
Feff EXAFS calculations, and some support code to read and work with
|
|
59
|
+
this database and the data it contains. The initial motivation is to
|
|
60
|
+
provide "first-shell EXAFS" calculations for many common ligands or
|
|
61
|
+
atom pairs, so that these can be browsed and re-used without having to
|
|
62
|
+
setup and run Feff for many common cases.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
feffdb/__init__.py,sha256=07HjHdlM1FIAMz9OjA4DsIe_AuL9c-TEcPKyRchtY7I,323
|
|
2
|
+
feffdb/apps.py,sha256=cLhJUVudaqxilYRBe7YeIrpqwjcZKi4rmu3gx7s_d_g,2817
|
|
3
|
+
feffdb/feffdat.db,sha256=5dYiqC3Le7esrMFW_hRYyYACChPPQL0UHlJvWDsDYbs,1662976
|
|
4
|
+
feffdb/feffdb.py,sha256=de_NEqCFPcvHoRPCl2_NTySjoyFJIBXwmwABbR1bdsU,12087
|
|
5
|
+
feffdb/feffpath.py,sha256=oIR8ZBqX6JF5UaPiwYZ4kwezy63I0kBvj5w9Ra3XmLw,19040
|
|
6
|
+
feffdb/schema.py,sha256=oDAlV_uDTWKU6WqXM1ANufDYRJ2TIQ4EL4DNviYMnLk,3224
|
|
7
|
+
feffdb/simpledb.py,sha256=CQg8LcmtyVoHAcJImfqxfzKJd4DqrD1KkYFzx3HX6D8,12547
|
|
8
|
+
feffdb/utils.py,sha256=FQwRjM4vQTchp5dzEevgvyA84HjJmEYl8duDFKQW9rU,11068
|
|
9
|
+
feffdb/version.py,sha256=dG56YXWdUYnaF4XVp7VDuwKai6JwmgaruKwoXv7wy0k,523
|
|
10
|
+
feffdb-0.1.dist-info/licenses/LICENSE,sha256=NnCHEmQk-hVaiYelyQ2olHgC2-ixV_alvCBvYjNVbQU,1359
|
|
11
|
+
feffdb-0.1.dist-info/METADATA,sha256=3pSgIKoNjAk-HhBcp7mXFJYLa2EAXTS0a_8ee_r9ex4,2486
|
|
12
|
+
feffdb-0.1.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
|
|
13
|
+
feffdb-0.1.dist-info/entry_points.txt,sha256=QLUHJcPcZLQjt1O_eZ6emH2PfUCNzWvTvd7h5V6VCXY,50
|
|
14
|
+
feffdb-0.1.dist-info/top_level.txt,sha256=5lUQJfFqNkLACCVftnG7Vvb8WECZ-4DYxTPWyES4lCI,7
|
|
15
|
+
feffdb-0.1.dist-info/RECORD,,
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 FeffDB development team, including
|
|
4
|
+
- Samantha Liao, Cornell University
|
|
5
|
+
- Juanjuan Huang, Argonne National Laboratory
|
|
6
|
+
- Nina Andrejevic, Argonne National Laboratory
|
|
7
|
+
- Yanna Chen, Canadian Light Source
|
|
8
|
+
- Matthew Newville, The University of Chicago
|
|
9
|
+
- Shelly Kelly, Argonne National Laboratory
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
13
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
14
|
+
in the Software without restriction, including without limitation the rights
|
|
15
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
16
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
17
|
+
furnished to do so, subject to the following conditions:
|
|
18
|
+
|
|
19
|
+
The above copyright notice and this permission notice shall be included in all
|
|
20
|
+
copies or substantial portions of the Software.
|
|
21
|
+
|
|
22
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
23
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
24
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
25
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
26
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
27
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
28
|
+
SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
feffdb
|