Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1import re 

2import numpy as np 

3from xml.dom import minidom 

4 

5 

6def get_ion(fname): 

7 """ 

8 Read the ion.xml file of a specie 

9 Input parameters: 

10 ----------------- 

11 fname (str): name of the ion file 

12 Output Parameters: 

13 ------------------ 

14 ion (dict): The ion dictionary contains all the data 

15 from the ion file. Each field of the xml file give 

16 one key. 

17 The different keys are: 

18 'lmax_basis': int 

19 'self_energy': float 

20 'z': int 

21 'symbol': str 

22 'label': str 

23 'mass': flaot 

24 'lmax_projs': int 

25 'basis_specs': str 

26 'norbs_nl': int 

27 'valence': float 

28 'nprojs_nl: int 

29 

30 The following keys give the pao field, 

31 'npts': list of int 

32 'delta':list of float 

33 'cutoff': list of float 

34 'data':list of np.arrayof shape (npts[i], 2) 

35 'orbital': list of dictionary 

36 'projector': list of dictionary 

37 

38 """ 

39 doc = minidom.parse(fname) 

40 

41 # the elements from the header 

42 elements_headers = [['symbol', str], ['label', str], ['z', int], 

43 ['valence', float], ['mass', float], 

44 ['self_energy', float], ['lmax_basis', int], 

45 ['norbs_nl', int], ['lmax_projs', int], 

46 ['nprojs_nl', int]] 

47 

48 ion = {} 

49 for i, elname in enumerate(elements_headers): 

50 name = doc.getElementsByTagName(elname[0]) 

51 ion[elname[0]] = get_data_elements(name[0], elname[1]) 

52 

53 # extract the basis_specs 

54 name = doc.getElementsByTagName("basis_specs") 

55 ion["basis_specs"] = getNodeText(name[0]) 

56 

57 extract_pao_elements(ion, doc) 

58 return ion 

59 

60 

61def getNodeText(node): 

62 nodelist = node.childNodes 

63 result = [] 

64 for node in nodelist: 

65 if node.nodeType == node.TEXT_NODE: 

66 result.append(node.data) 

67 return ''.join(result) 

68 

69 

70def get_data_elements(name, dtype): 

71 """ 

72 return the right type of the element value 

73 """ 

74 if dtype is int: 

75 data = str2int(getNodeText(name)) 

76 if len(data) > 1: 

77 return np.array(data) 

78 elif len(data) == 1: 

79 return data[0] 

80 else: 

81 raise ValueError("len(data)<1 ??") 

82 elif dtype is float: 

83 data = str2float(getNodeText(name)) 

84 if len(data) > 1: 

85 return np.array(data) 

86 elif len(data) == 1: 

87 return data[0] 

88 else: 

89 raise ValueError("len(data)<1 ??") 

90 elif dtype is str: 

91 return getNodeText(name) 

92 else: 

93 raise ValueError('not implemented') 

94 

95 

96def extract_pao_elements(ion, doc): 

97 """ 

98 extract the different pao element of the xml file 

99 Input Parameters: 

100 ----------------- 

101 ion (dict) 

102 doc (minidom.parse) 

103 Output Parameters: 

104 ------------------ 

105 ion (dict): the following keys are added to the ion dict: 

106 npts 

107 delta 

108 cutoff 

109 data 

110 orbital 

111 projector 

112 """ 

113 

114 name_npts = doc.getElementsByTagName("npts") 

115 name_delta = doc.getElementsByTagName("delta") 

116 name_cutoff = doc.getElementsByTagName("cutoff") 

117 name_data = doc.getElementsByTagName("data") 

118 

119 name_orbital = doc.getElementsByTagName("orbital") 

120 name_projector = doc.getElementsByTagName("projector") 

121 

122 ion["orbital"] = [] 

123 ion["projector"] = [] 

124 for i in range(len(name_orbital)): 

125 ion["orbital"].append(extract_orbital(name_orbital[i])) 

126 for i in range(len(name_projector)): 

127 ion["projector"].append(extract_projector(name_projector[i])) 

128 

129 if len(name_data) != len(name_npts): 

130 raise ValueError("len(name_data) != len(name_npts): {0} != {1}". 

131 format(len(name_data), len(name_npts))) 

132 if len(name_data) != len(name_cutoff): 

133 raise ValueError("len(name_data) != len(name_cutoff): {0} != {1}". 

134 format(len(name_data), len(name_cutoff))) 

135 if len(name_data) != len(name_delta): 

136 raise ValueError("len(name_data) != len(name_delta): {0} != {1}". 

137 format(len(name_data), len(name_delta))) 

138 

139 ion["npts"] = np.zeros((len(name_npts)), dtype=int) 

140 ion["delta"] = np.zeros((len(name_delta)), dtype=float) 

141 ion["cutoff"] = np.zeros((len(name_cutoff)), dtype=float) 

142 ion["data"] = [] 

143 

144 for i in range(len(name_data)): 

145 ion["npts"][i] = get_data_elements(name_npts[i], int) 

146 ion["cutoff"][i] = get_data_elements(name_cutoff[i], float) 

147 ion["delta"][i] = get_data_elements(name_delta[i], float) 

148 ion["data"].append(get_data_elements(name_data[i], float). 

149 reshape(ion["npts"][i], 2)) 

150 

151 

152def extract_orbital(orb_xml): 

153 """ 

154 extract the orbital 

155 """ 

156 orb = {} 

157 orb['l'] = str2int(orb_xml.attributes['l'].value)[0] 

158 orb['n'] = str2int(orb_xml.attributes['n'].value)[0] 

159 orb['z'] = str2int(orb_xml.attributes['z'].value)[0] 

160 orb['ispol'] = str2int(orb_xml.attributes['ispol'].value)[0] 

161 orb['population'] = str2float(orb_xml.attributes['population'].value)[0] 

162 

163 return orb 

164 

165 

166def extract_projector(pro_xml): 

167 """ 

168 extract the projector 

169 """ 

170 pro = {} 

171 pro['l'] = str2int(pro_xml.attributes['l'].value)[0] 

172 pro['n'] = str2int(pro_xml.attributes['n'].value)[0] 

173 pro['ref_energy'] = str2float(pro_xml.attributes['ref_energy'].value)[0] 

174 

175 return pro 

176 

177 

178def str2float(string): 

179 numeric_const_pattern = r""" 

180 [-+]? # optional sign 

181 (?: 

182 (?: \d* \. \d+ ) # .1 .12 .123 etc 9.1 etc 98.1 etc 

183 | 

184 (?: \d+ \.? ) # 1. 12. 123. etc 1 12 123 etc 

185 ) 

186 # followed by optional exponent part if desired 

187 (?: [Ee] [+-]? \d+ ) ? 

188 """ 

189 rx = re.compile(numeric_const_pattern, re.VERBOSE) 

190 

191 nb = rx.findall(string) 

192 for i in enumerate(nb): 

193 nb[i[0]] = float(i[1]) 

194 

195 return np.array(nb) 

196 

197 

198def str2int(string): 

199 numeric_const_pattern = r""" 

200 [-+]? # optional sign 

201 (?: 

202 (?: \d* \. \d+ ) # .1 .12 .123 etc 9.1 etc 98.1 etc 

203 | 

204 (?: \d+ \.? ) # 1. 12. 123. etc 1 12 123 etc 

205 ) 

206 # followed by optional exponent part if desired 

207 (?: [Ee] [+-]? \d+ ) ? 

208 """ 

209 rx = re.compile(numeric_const_pattern, re.VERBOSE) 

210 

211 nb = rx.findall(string) 

212 for i in enumerate(nb): 

213 nb[i[0]] = int(i[1]) 

214 

215 return np.array(nb)