Coverage for larch/xafs/feffutils.py: 11%

97 statements  

« prev     ^ index     » next       coverage.py v7.6.0, created at 2024-10-16 21:04 +0000

1import os 

2from pathlib import Path 

3from datetime import datetime 

4from collections import namedtuple 

5from larch.utils import read_textfile 

6 

7FPathInfo = namedtuple('FeffPathInfo', 

8 ('filename', 'absorber', 'shell', 'reff', 'nleg', 

9 'degen', 'cwratio', 'geom', 'geometry')) 

10class FeffCalcResults: 

11 def __init__(self, folder=None, header=None, ipots=None, 

12 paths=None, datetime=None, absorber=None, 

13 shell=None, input_text=None): 

14 self.folder = Path(folder).absolute().as_posix() 

15 self.header = header 

16 self.ipots = ipots 

17 self.paths = paths 

18 self.datetime = datetime 

19 self.absorber = absorber 

20 self.shell = shell 

21 self.input_text = input_text 

22 

23 def __getstate__(self): 

24 """Get state for pickle.""" 

25 return (self.folder, self.absorber, self.shell, self.header, 

26 self.ipots, self.paths, self.datetime, self.input_text) 

27 

28 def __setstate__(self, state): 

29 """Set state from pickle.""" 

30 (self.folder, self.absorber, self.shell, self.header, 

31 self.ipots, self.paths, self.datetime, self.input_text) = state 

32 

33 

34def get_feff_pathinfo(folder): 

35 """get list of Feff path info for a Feff folder 

36 """ 

37 fdat = Path(folder, 'files.dat') 

38 pdat = Path(folder, 'paths.dat') 

39 f001 = Path(folder, 'feff0001.dat') 

40 finp = Path(folder, 'feff.inp') 

41 

42 # check for valid, complete calculation 

43 if (not fdat.exists() or not pdat.exists() or 

44 not f001.exists() or not finp.exists()): 

45 return FeffCalcResults(folder, absorber=None, 

46 shell=None, ipots=[], header='', 

47 paths=[], datetime=None) 

48 

49 

50 dtime = datetime.fromtimestamp(os.stat(fdat).st_mtime).isoformat() 

51 fdatlines = read_textfile(fdat).split('\n') 

52 pathslines = read_textfile(pdat).split('\n') 

53 

54 xpaths = {} 

55 paths = {} 

56 geoms = {} 

57 header = [] 

58 shell = 'K' 

59 waiting_for_dashes = True 

60 for xline in fdatlines: 

61 xline = xline.strip() 

62 if xline.startswith('----'): 

63 waiting_for_dashes = False 

64 if waiting_for_dashes: 

65 header.append(xline) 

66 

67 if (xline.startswith('Abs ') and 'Rmt=' in xline and 

68 'Rnm=' in xline and 'shell' in xline): 

69 words = xline.replace('shell', '').strip().split() 

70 shell = words[-1] 

71 continue 

72 if xline.startswith('feff0'): 

73 w = xline.split() 

74 index = int(w[0].replace('feff', '').replace('.dat', '')) 

75 paths[index] = [w[0], w[5], w[4], w[3], w[2]] 

76 geoms[index] = [] 

77 

78 ipots = ['']*12 

79 waiting_for_dashes = True 

80 for i, xline in enumerate(pathslines): 

81 xline = xline.strip() 

82 if xline.startswith('----'): 

83 waiting_for_dashes = False 

84 if waiting_for_dashes: 

85 continue 

86 if 'index, nleg' in xline: 

87 words = xline.split() 

88 index = int(words[0]) 

89 nleg = int(words[1]) 

90 elems = [] 

91 pgeom = [] 

92 for j in range(nleg+1): 

93 xline = pathslines[j+i+1].strip().replace("'", '') 

94 if xline.startswith('x '): 

95 continue 

96 words = xline.split() 

97 atname = words[4].strip() 

98 ipot = int(words[3]) 

99 if ipot not in ipots: 

100 ipots[ipot] = atname 

101 elems.append(ipot) 

102 r, x, y, z, beta, eta = [float(words[i]) for i in (5, 0, 1, 2, 6, 7)] 

103 pgeom.append((atname, ipot, r, x, y, z, beta, eta)) 

104 if j == nleg: 

105 pgeom.insert(0, (atname, ipot, r, x, y, z, beta, eta)) 

106 if index in paths: 

107 paths[index].append(elems) 

108 geoms[index] = pgeom 

109 

110 ipots = [i for i in ipots if len(i) > 0] 

111 absorber = ipots[0] 

112 ipots[0] = '[%s]' % ipots[0] 

113 opaths = [] 

114 for pindex, pinfo in paths.items(): 

115 pots = [0] + pinfo[5] 

116 geom = ' > '.join([ipots[i] for i in pots]) 

117 opaths.append(FPathInfo(filename=pinfo[0], 

118 absorber=absorber, 

119 shell=shell, 

120 reff=float(pinfo[1]), 

121 nleg=int(float(pinfo[2])), 

122 degen=float(pinfo[3]), 

123 cwratio=float(pinfo[4]), 

124 geom=geom, 

125 geometry=geoms[pindex])) 

126 

127 

128 # read absorbing shell 

129 for line in header: 

130 line = line.strip() 

131 

132 # read input 

133 try: 

134 input_text = read_textfile(fin) 

135 except: 

136 input_text = '<not available>' 

137 

138 return FeffCalcResults(folder, 

139 absorber=absorber, 

140 shell=shell, 

141 ipots=ipots, 

142 header='\n'.join(header), 

143 paths=opaths, 

144 input_text=input_text, 

145 datetime=dtime)