Changeset 1221 for trunk/bindings/python/nxs
- Timestamp:
- 08/04/09 01:07:17 (3 years ago)
- File:
-
- 1 edited
-
trunk/bindings/python/nxs/napi.py (modified) (22 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/bindings/python/nxs/napi.py
r1203 r1221 419 419 Corresponds to NXmakegroup(handle, name, nxclass) 420 420 """ 421 #print "makegroup",self._loc(),name,nxclass 421 422 status = nxlib.nximakegroup_(self.handle, name, nxclass) 422 423 if status == ERROR: … … 556 557 Corresponds to NXopengroup(handle, name, nxclass) 557 558 """ 558 #print "open group",nxclass,name559 #print "opengroup",self._loc(),name,nxclass 559 560 if nxclass is None: 560 561 nxclass = self.__getnxclass(name) … … 575 576 Corresponds to NXclosegroup(handle) 576 577 """ 577 #print "close group"578 #print "closegroup" 578 579 status = nxlib.nxiclosegroup_(self.handle) 579 580 if status == ERROR: … … 603 604 if status == ERROR: 604 605 raise ValueError, "Could not get group info: %s"%(self._loc()) 605 #print "g roup info",nxclass.value,name.value,n.value606 #print "getgroupinfo",self._loc(),nxclass.value,name.value,n.value 606 607 name = path.value.split('/')[-1] # Protect against HDF5 returning path 607 608 return n.value,name,nxclass.value … … 655 656 #if nxclass == 'SDS': 656 657 # dtype = _pytype_code(storage.value) 657 #print " group next",nxclass.value, name.value, storage.value658 #print "nextentry",nxclass.value, name.value, storage.value 658 659 return name.value,nxclass.value 659 660 … … 728 729 729 730 # ==== Data ==== 730 nxlib.nxiget info_.restype = c_int731 nxlib.nxiget info_.argtypes = [c_void_p, c_int_p, c_void_p, c_int_p]732 def get info(self):731 nxlib.nxigetrawinfo_.restype = c_int 732 nxlib.nxigetrawinfo_.argtypes = [c_void_p, c_int_p, c_void_p, c_int_p] 733 def getrawinfo(self): 733 734 """ 734 735 Returns the tuple dimensions,type for the currently open dataset. … … 740 741 complex values. 741 742 743 Unlike getinfo(), the size of the string storage area is 744 returned rather than the length of the stored string. 745 746 Raises NeXusError if this fails. 747 748 Corresponds to NXgetrawinfo(handle, &rank, dims, &storage), 749 but with storage converted from HDF values to numpy compatible 750 strings, and rank implicit in the length of the returned dimensions. 751 """ 752 rank = c_int(0) 753 shape = numpy.zeros(MAXRANK, 'i') 754 storage = c_int(0) 755 status = nxlib.nxigetrawinfo_(self.handle, _ref(rank), shape.ctypes.data, 756 _ref(storage)) 757 if status == ERROR: 758 raise NeXusError, "Could not get data info: %s"%(self._loc()) 759 shape = shape[:rank.value]+0 760 dtype = _pytype_code[storage.value] 761 #print "getrawinfo",self._loc(),"->",shape,dtype 762 return shape,dtype 763 764 nxlib.nxigetinfo_.restype = c_int 765 nxlib.nxigetinfo_.argtypes = [c_void_p, c_int_p, c_void_p, c_int_p] 766 def getinfo(self): 767 """ 768 Returns the tuple dimensions,type for the currently open dataset. 769 Dimensions is an integer array whose length corresponds to the rank 770 of the dataset and whose elements are the size of the individual 771 dimensions. Storage type is returned as a string, with 'char' for 772 a stored string, '[u]int[8|16|32]' for various integer values or 773 'float[32|64]' for floating point values. No support for 774 complex values. 775 776 Unlike getrawinfo(), the length of the stored string is 777 returned rather than the size of the string storage area. 778 742 779 Raises NeXusError if this fails. 743 780 … … 758 795 shape = shape[:rank.value]+0 759 796 dtype = _pytype_code[storage.value] 760 #print " data info",shape,dtype797 #print "getinfo",self._loc(),"->",shape,dtype 761 798 return shape,dtype 762 799 … … 771 808 Corresponds to NXopendata(handle, name) 772 809 """ 773 #print "open ing data",name810 #print "opendata",self._loc(),name 774 811 status = nxlib.nxiopendata_(self.handle, name) 775 812 if status == ERROR: … … 789 826 Corresponds to NXclosedata(handle) 790 827 """ 791 #print "clos ingdata"828 #print "closedata" 792 829 status = nxlib.nxiclosedata_(self.handle) 793 830 if status == ERROR: … … 815 852 # TODO: With keywords for value and attr, this can be used for 816 853 # TODO: makedata, opendata, putdata, putattr, putattr, ..., closedata 817 #print " Data",name,dtype,shape854 #print "makedata",self._loc(),name,shape,dtype 818 855 storage = _nxtype_code[str(dtype)] 819 856 shape = numpy.array(shape,'i') … … 865 902 Return the data. If data is a string (1-D char array), a python 866 903 string is returned. If data is a scalar (1-D numeric array of 867 length 1), a python numeric scalar is returned. 904 length 1), a python scalar is returned. If data is a string 905 array, a numpy array of type 'S#' where # is the maximum string 906 length is returned. If data is a numeric array, a numpy array 907 is returned. 868 908 869 909 Raises ValueError if this fails. … … 873 913 # TODO: consider accepting preallocated data so we don't thrash memory 874 914 shape,dtype = self.getinfo() 875 data fn,pdata,size= self._poutput(dtype,shape)915 data,pdata,size,datafn = self._poutput(dtype,shape) 876 916 status = nxlib.nxigetdata_(self.handle,pdata) 877 917 if status == ERROR: 878 918 raise ValueError, "Could not read data: %s"%(self._loc()) 879 #print " data",ret()919 #print "getdata",self._loc(),shape,dtype 880 920 return datafn() 881 921 … … 894 934 """ 895 935 # TODO: consider accepting preallocated data so we don't thrash memory 896 shape,dtype = self.get info()897 data fn,pdata,size= self._poutput(dtype,slab_shape)936 shape,dtype = self.getrawinfo() 937 data,pdata,size,datafn = self._poutput(dtype,slab_shape) 898 938 slab_offset = numpy.array(slab_offset,'i') 899 939 slab_shape = numpy.array(slab_shape,'i') … … 916 956 Corresponds to NXputdata(handle, data) 917 957 """ 918 shape,dtype = self.getinfo() 958 shape,dtype = self.getrawinfo() 959 #print "putdata",self._loc(),shape,dtype 919 960 data,pdata = self._pinput(data,dtype,shape) 920 961 status = nxlib.nxiputdata_(self.handle,pdata) … … 935 976 Corresponds to NXputslab(handle,data,offset,shape) 936 977 """ 937 shape,dtype = self.get info()978 shape,dtype = self.getrawinfo() 938 979 data,pdata = self._pinput(data,dtype,slab_shape) 939 980 slab_offset = numpy.array(slab_offset,'i') … … 1011 1052 raise NeXusError, "Could not get next attr: %s"%(self._loc()) 1012 1053 dtype = _pytype_code[storage.value] 1013 #print " nextattr",name.value,length.value,dtype1054 #print "getnextattr",name.value,length.value,dtype 1014 1055 return name.value, length.value, dtype 1015 1056 … … 1027 1068 """ 1028 1069 if dtype is 'char': length += 1 # HDF4 needs zero-terminator 1029 data fn,pdata,size= self._poutput(str(dtype),[length])1070 data,pdata,size,datafn = self._poutput(str(dtype),[length]) 1030 1071 storage = c_int(_nxtype_code[str(dtype)]) 1031 #print " retrieving",name,length,dtype,size1072 #print "getattr",self._loc(),name,length,size,dtype 1032 1073 size = c_int(size) 1033 1074 status = nxlib.nxigetattr_(self.handle,name,pdata,_ref(size),_ref(storage)) 1034 1075 if status == ERROR: 1035 1076 raise ValueError, "Could not read attr %s: %s" % (name,self._loc()) 1036 #print " attr",name,datafn(),size1077 #print "getattr",self._loc(),name,datafn() 1037 1078 return datafn() 1038 1079 … … 1304 1345 """ 1305 1346 Build space to collect a nexus data element. 1306 Returns data fn,data,sizewhere1307 - data fn is a lamba expression to extract the value out of the element.1308 - pdata is the value to pass to C (effectively a void *)1347 Returns data,pdata,size,datafn where 1348 - data is a python type to hold the returned data 1349 - pdata is the pointer to the start of the data 1309 1350 - size is the number of bytes in the data block 1310 Note that ret can return a string, a scalar or an array depending 1351 - datafn is a lamba expression to extract the return value from data 1352 Note that datafn can return a string, a scalar or an array depending 1311 1353 on the data type and shape of the data group. 1312 1354 """ … … 1314 1356 # string - use ctypes allocator 1315 1357 size = int(shape[0]) 1316 pdata = ctypes.create_string_buffer(size) 1317 datafn = lambda: pdata.value 1358 data = ctypes.create_string_buffer(size) 1359 pdata = data 1360 datafn = lambda: data.value 1318 1361 else: 1319 # numeric - use numpy array 1320 if dtype=='char': dtype = 'uint8' 1321 data = numpy.zeros(shape,dtype) 1362 # scalar, array or string list - use numpy array 1363 if dtype=='char': 1364 data = numpy.zeros(shape[:-1], dtype='S%i'%shape[-1]) 1365 else: 1366 data = numpy.zeros(shape, dtype) 1322 1367 if len(shape) == 1 and shape[0] == 1: 1323 1368 datafn = lambda: data[0] … … 1326 1371 pdata = data.ctypes.data 1327 1372 size = data.nbytes 1328 return data fn,pdata,size1373 return data,pdata,size,datafn 1329 1374 1330 1375 def _pinput(self, data, dtype, shape): 1331 1376 """ 1332 Convert an input array to a C pointer to a dense array. This may 1333 require conversion of the array, so the new array is returned along 1334 with its pointer. 1377 Convert an input array to a C pointer to a dense array. 1378 1379 Returns data, pdata where 1380 - data is a possibly new copy of the array 1381 - pdata is a pointer to the beginning of the array. 1382 Note that you must hold a reference to data for as long 1383 as you need pdata to keep the memory from being released to the heap. 1335 1384 """ 1336 1385 if dtype == "char": 1337 # Character data - pad with zeros to the right length 1338 if not _is_string_like(data): 1339 raise ValueError,"Expected character data: %s"%(self._loc()) 1340 if len(data) < shape[0]: 1341 data += '\000'*(shape[0]-len(data)) 1386 data = numpy.asarray(data, dtype='S%d'%(shape[-1])) 1342 1387 else: 1343 1388 # Convert scalars to vectors of length one 1344 1389 if numpy.prod(shape) == 1 and not hasattr(data,'shape'): 1345 data = numpy.array([data], dtype=dtype)1390 data = numpy.array([data], dtype=dtype) 1346 1391 # Check that dimensions match 1347 1392 # Ick! need to exclude dimensions of length 1 in order to catch … … 1349 1394 input_shape = numpy.array([i for i in data.shape if i != 1]) 1350 1395 target_shape = numpy.array([i for i in shape if i != 1]) 1351 if len(input_shape) != len(target_shape) or (input_shape != target_shape).any(): 1396 if len(input_shape) != len(target_shape) \ 1397 or (input_shape != target_shape).any(): 1352 1398 raise ValueError,\ 1353 "Shape mismatch %s!=%s: %s"%(data.shape,shape,self.filename) 1399 "Shape mismatch %s!=%s: %s"%(data_shape,shape,self._loc()) 1400 # Check data type 1354 1401 if str(data.dtype) != dtype: 1355 1402 raise ValueError,\ 1356 1403 "Type mismatch %s!=%s: %s"%(dtype,data.dtype,self._loc()) 1357 1404 1358 if dtype == 'char': 1359 # String: hand it over as usual for strings. Assumes the string 1360 # is the correct length for the storage area. 1361 pdata = data 1362 else: 1363 # Vector: assume it is of the correct storage class and size 1364 data = numpy.ascontiguousarray(data) 1365 pdata = data.ctypes.data 1366 1405 data = numpy.ascontiguousarray(data) 1406 pdata = data.ctypes.data 1407 1367 1408 return data,pdata 1368 1409
Note: See TracChangeset
for help on using the changeset viewer.
