6
6
import ctypes
7
7
import ctypes .util
8
8
9
- __version__ = '1.0 .0'
9
+ __version__ = '1.1 .0'
10
10
11
11
try :
12
- from numpy import array , pi , exp , log , sin , arcsin
12
+ from numpy import array , exp , log , sin , arcsin
13
13
HAS_NUMPY = True
14
- RAD2DEG = 180.0 / pi
15
- # from NIST.GOV CODATA:
16
- # Planck constant over 2 pi times c: 197.3269718 (0.0000044) MeV fm
17
- PLANCK_hc = 1973.269718 * 2 * pi # hc in eV * Ang = 12398.4193
18
14
except ImportError :
19
15
HAS_NUMPY = False
20
16
17
+ PI = 3.14159265358979323846
18
+ RAD2DEG = 180.0 / PI
19
+
20
+ # from NIST.GOV CODATA:
21
+ # Planck constant over 2 pi times c: 197.3269718 (0.0000044) MeV fm
22
+ PLANCK_HC = 1973.269718 * 2 * PI # hc in eV * Ang = 12398.4193
23
+
21
24
class XDIFileStruct (ctypes .Structure ):
22
25
"emulate XDI File"
23
26
_fields_ = [('nmetadata' , ctypes .c_long ),
24
27
('narrays' , ctypes .c_long ),
25
28
('npts' , ctypes .c_long ),
26
29
('narray_labels' , ctypes .c_long ),
30
+ ('nouter' , ctypes .c_long ),
31
+ ('error_lineno' , ctypes .c_long ),
27
32
('dspacing' , ctypes .c_double ),
28
- ('xdi_libversion' , ctypes .c_char_p ),
33
+ ('xdi_libversion' ,ctypes .c_char_p ),
29
34
('xdi_version' , ctypes .c_char_p ),
30
35
('extra_version' , ctypes .c_char_p ),
31
36
('filename' , ctypes .c_char_p ),
32
37
('element' , ctypes .c_char_p ),
33
38
('edge' , ctypes .c_char_p ),
34
39
('comments' , ctypes .c_char_p ),
40
+ ('error_line' , ctypes .c_char_p ),
35
41
('array_labels' , ctypes .c_void_p ),
42
+ ('outer_label' , ctypes .c_char_p ),
36
43
('array_units' , ctypes .c_void_p ),
37
44
('meta_families' , ctypes .c_void_p ),
38
45
('meta_keywords' , ctypes .c_void_p ),
39
46
('meta_values' , ctypes .c_void_p ),
40
- ('array' , ctypes .c_void_p )]
47
+ ('array' , ctypes .c_void_p ),
48
+ ('outer_array' , ctypes .c_void_p ),
49
+ ('outer_breakpts' , ctypes .c_void_p )]
41
50
42
51
def add_dot2path ():
43
52
"""add this folder to begninng of PATH environmental variable"""
@@ -88,9 +97,11 @@ class XDIFile(object):
88
97
def __init__ (self , filename = None ):
89
98
self .filename = filename
90
99
self .xdi_pyversion = __version__
100
+ self .xdilib = get_xdilib ()
91
101
self .comments = []
92
102
self .rawdata = []
93
103
self .attrs = {}
104
+ self .status = None
94
105
if self .filename :
95
106
self .read (self .filename )
96
107
@@ -103,12 +114,11 @@ def read(self, filename=None):
103
114
"""
104
115
if filename is None and self .filename is not None :
105
116
filename = self .filename
106
- XDILIB = get_xdilib ()
107
117
108
118
pxdi = ctypes .pointer (XDIFileStruct ())
109
- out = XDILIB .XDI_readfile (filename , pxdi )
110
- if out != 0 :
111
- msg = XDILIB .XDI_errorstring (out )
119
+ self . status = out = self . xdilib .XDI_readfile (filename , pxdi )
120
+ if out < 0 :
121
+ msg = self . xdilib .XDI_errorstring (out )
112
122
msg = 'Error reading XDIFile %s\n %s' % (filename , msg )
113
123
raise XDIFileException (msg )
114
124
@@ -119,7 +129,7 @@ def read(self, filename=None):
119
129
pchar = ctypes .c_char_p
120
130
self .array_labels = (self .narrays * pchar ).from_address (xdi .array_labels )[:]
121
131
self .array_units = (self .narrays * pchar ).from_address (xdi .array_units )[:]
122
-
132
+
123
133
mfams = (self .nmetadata * pchar ).from_address (xdi .meta_families )[:]
124
134
mkeys = (self .nmetadata * pchar ).from_address (xdi .meta_keywords )[:]
125
135
mvals = (self .nmetadata * pchar ).from_address (xdi .meta_values )[:]
@@ -133,7 +143,18 @@ def read(self, filename=None):
133
143
134
144
parrays = (xdi .narrays * ctypes .c_void_p ).from_address (xdi .array )[:]
135
145
rawdata = [(xdi .npts * ctypes .c_double ).from_address (p )[:] for p in parrays ]
136
-
146
+
147
+ nout = xdi .nouter
148
+ outer , breaks = [], []
149
+ if nout > 1 :
150
+ outer = (nout * ctypes .c_double ).from_address (xdi .outer_array )[:]
151
+ breaks = (nout * ctypes .c_long ).from_address (xdi .outer_breakpts )[:]
152
+ for attr in ('outer_array' , 'outer_breakpts' , 'nouter' ):
153
+ delattr (self , attr )
154
+ self .outer_array = array (outer )
155
+ self .outer_breakpts = array (breaks )
156
+
157
+
137
158
if HAS_NUMPY :
138
159
rawdata = array (rawdata )
139
160
rawdata .shape = (self .narrays , self .npts )
@@ -169,13 +190,13 @@ def _assign_arrays(self):
169
190
xunits = units
170
191
171
192
if not HAS_NUMPY :
172
- print '%s: not calculating derived values: install numpy!' % (self .filename )
173
193
return
174
194
175
195
# convert energy to angle, or vice versa
176
196
if ix >= 0 and 'd_spacing' in self .attrs ['mono' ]:
177
197
dspace = float (self .attrs ['mono' ]['d_spacing' ])
178
- omega = PLANCK_hc / (2 * dspace )
198
+ if dspace < 0 : dspace = 0.001
199
+ omega = PLANCK_HC / (2 * dspace )
179
200
if xname == 'energy' and not hasattr (self , 'angle' ):
180
201
energy_ev = self .energy
181
202
if xunits .lower () == 'kev' :
0 commit comments