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
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
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
38 """
39 doc = minidom.parse(fname)
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]]
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])
53 # extract the basis_specs
54 name = doc.getElementsByTagName("basis_specs")
55 ion["basis_specs"] = getNodeText(name[0])
57 extract_pao_elements(ion, doc)
58 return ion
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)
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')
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 """
114 name_npts = doc.getElementsByTagName("npts")
115 name_delta = doc.getElementsByTagName("delta")
116 name_cutoff = doc.getElementsByTagName("cutoff")
117 name_data = doc.getElementsByTagName("data")
119 name_orbital = doc.getElementsByTagName("orbital")
120 name_projector = doc.getElementsByTagName("projector")
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]))
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)))
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"] = []
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))
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]
163 return orb
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]
175 return pro
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)
191 nb = rx.findall(string)
192 for i in enumerate(nb):
193 nb[i[0]] = float(i[1])
195 return np.array(nb)
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)
211 nb = rx.findall(string)
212 for i in enumerate(nb):
213 nb[i[0]] = int(i[1])
215 return np.array(nb)