Coverage for /Users/Newville/Codes/xraylarch/larch/xafs/feffutils.py: 10%
96 statements
« prev ^ index » next coverage.py v7.3.2, created at 2023-11-09 10:08 -0600
« prev ^ index » next coverage.py v7.3.2, created at 2023-11-09 10:08 -0600
1import os
2from datetime import datetime
3from collections import namedtuple
4from larch.utils import read_textfile
6FPathInfo = namedtuple('FeffPathInfo',
7 ('filename', 'absorber', 'shell', 'reff', 'nleg',
8 'degen', 'cwratio', 'geom', 'geometry'))
9class FeffCalcResults:
10 def __init__(self, folder=None, header=None, ipots=None,
11 paths=None, datetime=None, absorber=None,
12 shell=None, input_text=None):
13 self.folder = folder
14 self.header = header
15 self.ipots = ipots
16 self.paths = paths
17 self.datetime = datetime
18 self.absorber = absorber
19 self.shell = shell
20 self.input_text = input_text
22 def __getstate__(self):
23 """Get state for pickle."""
24 return (self.folder, self.absorber, self.shell, self.header,
25 self.ipots, self.paths, self.datetime, self.input_text)
27 def __setstate__(self, state):
28 """Set state from pickle."""
29 (self.folder, self.absorber, self.shell, self.header,
30 self.ipots, self.paths, self.datetime, self.input_text) = state
33def get_feff_pathinfo(folder):
34 """get list of Feff path info for a Feff folder
35 """
36 fdat = os.path.join(folder, 'files.dat')
37 pdat = os.path.join(folder, 'paths.dat')
38 f001 = os.path.join(folder, 'feff0001.dat')
39 finp = os.path.join(folder, 'feff.inp')
41 # check for valid, complete calculation
42 if (not os.path.exists(fdat) or not os.path.exists(pdat) or
43 not os.path.exists(f001) or not os.path.exists(finp)):
44 return FeffCalcResults(os.path.abspath(folder), absorber=None,
45 shell=None, ipots=[], header='',
46 paths=[], datetime=None)
49 dtime = datetime.fromtimestamp(os.stat(fdat).st_mtime).isoformat()
50 fdatlines = read_textfile(fdat).split('\n')
51 pathslines = read_textfile(pdat).split('\n')
53 xpaths = {}
54 paths = {}
55 geoms = {}
56 header = []
57 shell = 'K'
58 waiting_for_dashes = True
59 for xline in fdatlines:
60 xline = xline.strip()
61 if xline.startswith('----'):
62 waiting_for_dashes = False
63 if waiting_for_dashes:
64 header.append(xline)
66 if (xline.startswith('Abs ') and 'Rmt=' in xline and
67 'Rnm=' in xline and 'shell' in xline):
68 words = xline.replace('shell', '').strip().split()
69 shell = words[-1]
70 continue
71 if xline.startswith('feff0'):
72 w = xline.split()
73 index = int(w[0].replace('feff', '').replace('.dat', ''))
74 paths[index] = [w[0], w[5], w[4], w[3], w[2]]
75 geoms[index] = []
77 ipots = ['']*12
78 waiting_for_dashes = True
79 for i, xline in enumerate(pathslines):
80 xline = xline.strip()
81 if xline.startswith('----'):
82 waiting_for_dashes = False
83 if waiting_for_dashes:
84 continue
85 if 'index, nleg' in xline:
86 words = xline.split()
87 index = int(words[0])
88 nleg = int(words[1])
89 elems = []
90 pgeom = []
91 for j in range(nleg+1):
92 xline = pathslines[j+i+1].strip().replace("'", '')
93 if xline.startswith('x '):
94 continue
95 words = xline.split()
96 atname = words[4].strip()
97 ipot = int(words[3])
98 if ipot not in ipots:
99 ipots[ipot] = atname
100 elems.append(ipot)
101 r, x, y, z, beta, eta = [float(words[i]) for i in (5, 0, 1, 2, 6, 7)]
102 pgeom.append((atname, ipot, r, x, y, z, beta, eta))
103 if j == nleg:
104 pgeom.insert(0, (atname, ipot, r, x, y, z, beta, eta))
105 if index in paths:
106 paths[index].append(elems)
107 geoms[index] = pgeom
109 ipots = [i for i in ipots if len(i) > 0]
110 absorber = ipots[0]
111 ipots[0] = '[%s]' % ipots[0]
112 opaths = []
113 for pindex, pinfo in paths.items():
114 pots = [0] + pinfo[5]
115 geom = ' > '.join([ipots[i] for i in pots])
116 opaths.append(FPathInfo(filename=pinfo[0],
117 absorber=absorber,
118 shell=shell,
119 reff=float(pinfo[1]),
120 nleg=int(float(pinfo[2])),
121 degen=float(pinfo[3]),
122 cwratio=float(pinfo[4]),
123 geom=geom,
124 geometry=geoms[pindex]))
127 # read absorbing shell
128 for line in header:
129 line = line.strip()
131 # read input
132 try:
133 input_text = read_textfile(fin)
134 except:
135 input_text = '<not available>'
137 return FeffCalcResults(os.path.abspath(folder),
138 absorber=absorber,
139 shell=shell,
140 ipots=ipots,
141 header='\n'.join(header),
142 paths=opaths,
143 input_text=input_text,
144 datetime=dtime)