Skip to content

Commit f976d2b

Browse files
committed
Merge pull request #43 from newville/master
update python XDI module for latest version
2 parents 1a741fd + 38dfb9a commit f976d2b

File tree

3 files changed

+53
-67
lines changed

3 files changed

+53
-67
lines changed

python/lib/__init__.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,22 @@
22
Xas Data Interchange Format
33
44
Matthew Newville <[email protected]>
5-
last update: 2011-Dec-01
6-
5+
last update: 2015-Mar-24
6+
77
== License:
88
To the extent possible, the authors have waived all rights
99
granted by copyright law and related laws for the code and
1010
documentation that make up the XAS Data Library. While
1111
information about Authorship may be retained in some files
1212
for historical reasons, this work is hereby placed in the
1313
Public Domain. This work is published from: United States.
14-
14+
1515
== Overview:
1616
The xdi module provides a way to read/write files in the
1717
XAS Data Interchange format
18-
18+
1919
"""
20-
__version__ = '0.2.0'
20+
__version__ = '0.2.1'
2121

2222
from . import xdi
2323
XDIFile = xdi.XDIFile

python/lib/xdi.py

Lines changed: 34 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,9 @@
66
import ctypes
77
import ctypes.util
88

9-
__version__ = '1.1.0'
9+
__version__ = '1.2.0'
1010

11-
try:
12-
from numpy import array, exp, log, sin, arcsin
13-
HAS_NUMPY = True
14-
except ImportError:
15-
HAS_NUMPY = False
11+
from numpy import array, exp, log, sin, arcsin
1612

1713
PI = 3.14159265358979323846
1814
RAD2DEG = 180.0/PI
@@ -38,8 +34,9 @@ class XDIFileStruct(ctypes.Structure):
3834
('edge', ctypes.c_char_p),
3935
('comments', ctypes.c_char_p),
4036
('error_line', ctypes.c_char_p),
37+
('error_message', ctypes.c_char_p),
4138
('array_labels', ctypes.c_void_p),
42-
('outer_label', ctypes.c_char_p),
39+
('outer_label', ctypes.c_char_p),
4340
('array_units', ctypes.c_void_p),
4441
('meta_families', ctypes.c_void_p),
4542
('meta_keywords', ctypes.c_void_p),
@@ -62,7 +59,6 @@ def get_xdilib():
6259
"""make initial connection to XDI dll"""
6360
global XDILIB
6461
if XDILIB is None:
65-
add_dot2path()
6662
dllpath = ctypes.util.find_library('xdifile')
6763
load_dll = ctypes.cdll.LoadLibrary
6864
if os.name == 'nt':
@@ -71,6 +67,7 @@ def get_xdilib():
7167
XDILIB.XDI_errorstring.restype = ctypes.c_char_p
7268
return XDILIB
7369

70+
7471
class XDIFileException(Exception):
7572
"""XDI File Exception: General Errors"""
7673
def __init__(self, msg, **kws):
@@ -107,29 +104,36 @@ def __init__(self, filename=None):
107104

108105
def write(self, filename):
109106
"write out an XDI File"
110-
print 'Writing XDI file not currently supported'
107+
print( 'Writing XDI file not currently supported')
111108

112109
def read(self, filename=None):
113110
"""read validate and parse an XDI datafile into python structures
114111
"""
115112
if filename is None and self.filename is not None:
116113
filename = self.filename
117-
118114
pxdi = ctypes.pointer(XDIFileStruct())
119115
self.status = out = self.xdilib.XDI_readfile(filename, pxdi)
120116
if out < 0:
121-
msg = self.xdilib.XDI_errorstring(out)
117+
msg = self.xdilib.XDI_errorstring(out)
118+
self.xdilib.XDI_cleanup(pxdi, out)
122119
msg = 'Error reading XDIFile %s\n%s' % (filename, msg)
123120
raise XDIFileException(msg)
124121

125122
xdi = pxdi.contents
126123
for attr in dict(xdi._fields_):
127124
setattr(self, attr, getattr(xdi, attr))
128-
129125
pchar = ctypes.c_char_p
130126
self.array_labels = (self.narrays*pchar).from_address(xdi.array_labels)[:]
131-
self.array_units = (self.narrays*pchar).from_address(xdi.array_units)[:]
132-
127+
arr_units = (self.narrays*pchar).from_address(xdi.array_units)[:]
128+
self.array_units = []
129+
self.array_addrs = []
130+
for unit in arr_units:
131+
addr = ''
132+
if '||' in unit:
133+
unit, addr = [x.strip() for x in unit.split('||', 1)]
134+
self.array_units.append(unit)
135+
self.array_addrs.append(addr)
136+
133137
mfams = (self.nmetadata*pchar).from_address(xdi.meta_families)[:]
134138
mkeys = (self.nmetadata*pchar).from_address(xdi.meta_keywords)[:]
135139
mvals = (self.nmetadata*pchar).from_address(xdi.meta_values)[:]
@@ -143,7 +147,7 @@ def read(self, filename=None):
143147

144148
parrays = (xdi.narrays*ctypes.c_void_p).from_address(xdi.array)[:]
145149
rawdata = [(xdi.npts*ctypes.c_double).from_address(p)[:] for p in parrays]
146-
150+
147151
nout = xdi.nouter
148152
outer, breaks = [], []
149153
if nout > 1:
@@ -153,17 +157,16 @@ def read(self, filename=None):
153157
delattr(self, attr)
154158
self.outer_array = array(outer)
155159
self.outer_breakpts = array(breaks)
156-
157-
158-
if HAS_NUMPY:
159-
rawdata = array(rawdata)
160-
rawdata.shape = (self.narrays, self.npts)
160+
161+
162+
rawdata = array(rawdata)
163+
rawdata.shape = (self.narrays, self.npts)
161164
self.rawdata = rawdata
162165
self._assign_arrays()
163-
164166
for attr in ('nmetadata', 'narray_labels', 'meta_families',
165167
'meta_keywords', 'meta_values', 'array'):
166168
delattr(self, attr)
169+
self.xdilib.XDI_cleanup(pxdi, 0)
167170

168171
def _assign_arrays(self):
169172
"""assign data arrays for principle data attributes:
@@ -173,14 +176,10 @@ def _assign_arrays(self):
173176
xunits = 'eV'
174177
xname = None
175178
ix = -1
176-
if HAS_NUMPY:
177-
self.rawdata = array(self.rawdata)
179+
self.rawdata = array(self.rawdata)
178180

179181
for idx, name in enumerate(self.array_labels):
180-
if HAS_NUMPY:
181-
dat = self.rawdata[idx,:]
182-
else:
183-
dat = [d[idx] for d in self.rawdata]
182+
dat = self.rawdata[idx,:]
184183
setattr(self, name, dat)
185184
if name in ('energy', 'angle'):
186185
ix = idx
@@ -189,12 +188,15 @@ def _assign_arrays(self):
189188
if units is not None:
190189
xunits = units
191190

192-
if not HAS_NUMPY:
193-
return
194-
195191
# convert energy to angle, or vice versa
196-
if ix >= 0 and 'd_spacing' in self.attrs['mono']:
197-
dspace = float(self.attrs['mono']['d_spacing'])
192+
monodat = {}
193+
if 'mono' in self.attrs:
194+
monodat = self.attrs['mono']
195+
elif 'monochromator' in self.attrs:
196+
monodat = self.attrs['monochromator']
197+
198+
if ix >= 0 and 'd_spacing' in monodat:
199+
dspace = float(monodat['d_spacing'])
198200
if dspace < 0: dspace = 0.001
199201
omega = PLANCK_HC/(2*dspace)
200202
if xname == 'energy' and not hasattr(self, 'angle'):

python/tests/test1.py

Lines changed: 14 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,39 +3,23 @@
33
sys.path.insert(0, '../')
44
import lib as xdi
55

6-
testfile = os.path.join('..', '..', 'perl', 't', 'xdi.aps10id')
6+
testfile = os.path.join('..', '..', 'data', 'cu_metal_10k.xdi')
77
if len(sys.argv) > 1:
88
testfile = sys.argv[1]
9-
10-
f = xdi.XDIFile(testfile)
11-
12-
print( 'Read file ', f.fname, ' Version: ', f.file_version)
13-
# print( '==Pre-Defined Fields==')
14-
# for key in sorted(xdi.DEFINED_FIELDS):
15-
# attr = key.lower().replace('-','_')
16-
# if hasattr(f, attr):
17-
# print( ' %s: %s' % (key, getattr(f, attr)))
18-
#
19-
# print( '==Extra Fields')
20-
# for key, val in f.attributes.items():
21-
# print( ' %s: %s' % (key, val))
22-
23-
print( '==User Comments:')
24-
print( '\n'.join(f.comments))
25-
print( '==Labels:')
26-
print( f.labels, f.has_numpy)
279

28-
if f.has_numpy:
29-
print( '==Data: numeric array', f.data.shape)
30-
31-
else:
32-
print( '==Data: lists', len(f.data))
33-
34-
for key in sorted(f.columns):
35-
out = None
36-
if f.column_data[key] is not None:
37-
print key, f.columns[key], len(f.column_data[key]), f.column_data[key][:3]
10+
f = xdi.XDIFile(testfile)
3811

12+
print( 'Read file ', f.filename)
3913

14+
#print( '==Extra Fields')
15+
#for key in dir(f):
16+
# if not key.startswith('_'):
17+
# print( ' %s: %s' % (key, getattr(f, key)))
4018

41-
f.write('out3.xdi')
19+
print( '==File:', f.filename)
20+
print( '==Element, Edge: ', f.element, f.edge)
21+
print( '==Extra Version:', f.extra_version)
22+
print( '==User Comments:', f.comments)
23+
print( '==Array Labels:', f.array_labels)
24+
print( '==Array Npts:', f.npts)
25+
print( '==Data: array shape, type:', f.rawdata.shape, f.rawdata.dtype)

0 commit comments

Comments
 (0)