Changeset 1230 for branches/4.2/bindings/python/nxs/napi.py
- Timestamp:
- 14/04/09 18:56:40 (3 years ago)
- File:
-
- 1 edited
-
branches/4.2/bindings/python/nxs/napi.py (modified) (22 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/4.2/bindings/python/nxs/napi.py
r1205 r1230 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" 579 if self._indata: 580 raise NeXusError, "Close data before group at %s"%(self._loc()) 578 581 status = nxlib.nxiclosegroup_(self.handle) 579 582 if status == ERROR: 580 raise NeXusError, "Could not close group at %s"%( name,self._loc())583 raise NeXusError, "Could not close group at %s"%(self._loc()) 581 584 self._path.pop() 582 585 … … 603 606 if status == ERROR: 604 607 raise ValueError, "Could not get group info: %s"%(self._loc()) 605 #print "g roup info",nxclass.value,name.value,n.value608 #print "getgroupinfo",self._loc(),nxclass.value,name.value,n.value 606 609 name = path.value.split('/')[-1] # Protect against HDF5 returning path 607 610 return n.value,name,nxclass.value … … 655 658 #if nxclass == 'SDS': 656 659 # dtype = _pytype_code(storage.value) 657 #print " group next",nxclass.value, name.value, storage.value660 #print "nextentry",nxclass.value, name.value, storage.value 658 661 return name.value,nxclass.value 659 662 … … 728 731 729 732 # ==== 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):733 nxlib.nxigetrawinfo_.restype = c_int 734 nxlib.nxigetrawinfo_.argtypes = [c_void_p, c_int_p, c_void_p, c_int_p] 735 def getrawinfo(self): 733 736 """ 734 737 Returns the tuple dimensions,type for the currently open dataset. … … 740 743 complex values. 741 744 745 Unlike getinfo(), the size of the string storage area is 746 returned rather than the length of the stored string. 747 748 Raises NeXusError if this fails. 749 750 Corresponds to NXgetrawinfo(handle, &rank, dims, &storage), 751 but with storage converted from HDF values to numpy compatible 752 strings, and rank implicit in the length of the returned dimensions. 753 """ 754 rank = c_int(0) 755 shape = numpy.zeros(MAXRANK, 'i') 756 storage = c_int(0) 757 status = nxlib.nxigetrawinfo_(self.handle, _ref(rank), shape.ctypes.data, 758 _ref(storage)) 759 if status == ERROR: 760 raise NeXusError, "Could not get data info: %s"%(self._loc()) 761 shape = shape[:rank.value]+0 762 dtype = _pytype_code[storage.value] 763 #print "getrawinfo",self._loc(),"->",shape,dtype 764 return shape,dtype 765 766 nxlib.nxigetinfo_.restype = c_int 767 nxlib.nxigetinfo_.argtypes = [c_void_p, c_int_p, c_void_p, c_int_p] 768 def getinfo(self): 769 """ 770 Returns the tuple dimensions,type for the currently open dataset. 771 Dimensions is an integer array whose length corresponds to the rank 772 of the dataset and whose elements are the size of the individual 773 dimensions. Storage type is returned as a string, with 'char' for 774 a stored string, '[u]int[8|16|32]' for various integer values or 775 'float[32|64]' for floating point values. No support for 776 complex values. 777 778 Unlike getrawinfo(), the length of the stored string is 779 returned rather than the size of the string storage area. 780 742 781 Raises NeXusError if this fails. 743 782 … … 758 797 shape = shape[:rank.value]+0 759 798 dtype = _pytype_code[storage.value] 760 #print " data info",shape,dtype799 #print "getinfo",self._loc(),"->",shape,dtype 761 800 return shape,dtype 762 801 … … 771 810 Corresponds to NXopendata(handle, name) 772 811 """ 773 #print "opening data",name 774 status = nxlib.nxiopendata_(self.handle, name) 812 #print "opendata",self._loc(),name 813 if self._indata: 814 status = ERROR 815 else: 816 status = nxlib.nxiopendata_(self.handle, name) 775 817 if status == ERROR: 776 818 raise ValueError, "Could not open data %s: %s"%(name, self._loc()) … … 789 831 Corresponds to NXclosedata(handle) 790 832 """ 791 #print "clos ingdata"833 #print "closedata" 792 834 status = nxlib.nxiclosedata_(self.handle) 793 835 if status == ERROR: 794 836 raise NeXusError,\ 795 "Could not close data at %s"%( name,self._loc())837 "Could not close data at %s"%(self._loc()) 796 838 self._path.pop() 797 839 self._indata = False … … 815 857 # TODO: With keywords for value and attr, this can be used for 816 858 # TODO: makedata, opendata, putdata, putattr, putattr, ..., closedata 817 #print " Data",name,dtype,shape859 #print "makedata",self._loc(),name,shape,dtype 818 860 storage = _nxtype_code[str(dtype)] 819 861 shape = numpy.array(shape,'i') … … 865 907 Return the data. If data is a string (1-D char array), a python 866 908 string is returned. If data is a scalar (1-D numeric array of 867 length 1), a python numeric scalar is returned. 909 length 1), a python scalar is returned. If data is a string 910 array, a numpy array of type 'S#' where # is the maximum string 911 length is returned. If data is a numeric array, a numpy array 912 is returned. 868 913 869 914 Raises ValueError if this fails. … … 873 918 # TODO: consider accepting preallocated data so we don't thrash memory 874 919 shape,dtype = self.getinfo() 875 data fn,pdata,size= self._poutput(dtype,shape)920 data,pdata,size,datafn = self._poutput(dtype,shape) 876 921 status = nxlib.nxigetdata_(self.handle,pdata) 877 922 if status == ERROR: 878 923 raise ValueError, "Could not read data: %s"%(self._loc()) 879 #print " data",ret()924 #print "getdata",self._loc(),shape,dtype 880 925 return datafn() 881 926 … … 894 939 """ 895 940 # 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)941 shape,dtype = self.getrawinfo() 942 data,pdata,size,datafn = self._poutput(dtype,slab_shape) 898 943 slab_offset = numpy.array(slab_offset,'i') 899 944 slab_shape = numpy.array(slab_shape,'i') … … 916 961 Corresponds to NXputdata(handle, data) 917 962 """ 918 shape,dtype = self.getinfo() 963 shape,dtype = self.getrawinfo() 964 #print "putdata",self._loc(),shape,dtype 919 965 data,pdata = self._pinput(data,dtype,shape) 920 966 status = nxlib.nxiputdata_(self.handle,pdata) … … 935 981 Corresponds to NXputslab(handle,data,offset,shape) 936 982 """ 937 shape,dtype = self.get info()983 shape,dtype = self.getrawinfo() 938 984 data,pdata = self._pinput(data,dtype,slab_shape) 939 985 slab_offset = numpy.array(slab_offset,'i') … … 1011 1057 raise NeXusError, "Could not get next attr: %s"%(self._loc()) 1012 1058 dtype = _pytype_code[storage.value] 1013 #print " nextattr",name.value,length.value,dtype1059 #print "getnextattr",name.value,length.value,dtype 1014 1060 return name.value, length.value, dtype 1015 1061 … … 1027 1073 """ 1028 1074 if dtype is 'char': length += 1 # HDF4 needs zero-terminator 1029 data fn,pdata,size= self._poutput(str(dtype),[length])1075 data,pdata,size,datafn = self._poutput(str(dtype),[length]) 1030 1076 storage = c_int(_nxtype_code[str(dtype)]) 1031 #print " retrieving",name,length,dtype,size1077 #print "getattr",self._loc(),name,length,size,dtype 1032 1078 size = c_int(size) 1033 1079 status = nxlib.nxigetattr_(self.handle,name,pdata,_ref(size),_ref(storage)) 1034 1080 if status == ERROR: 1035 1081 raise ValueError, "Could not read attr %s: %s" % (name,self._loc()) 1036 #print " attr",name,datafn(),size1082 #print "getattr",self._loc(),name,datafn() 1037 1083 return datafn() 1038 1084 … … 1304 1350 """ 1305 1351 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 *)1352 Returns data,pdata,size,datafn where 1353 - data is a python type to hold the returned data 1354 - pdata is the pointer to the start of the data 1309 1355 - size is the number of bytes in the data block 1310 Note that ret can return a string, a scalar or an array depending 1356 - datafn is a lamba expression to extract the return value from data 1357 Note that datafn can return a string, a scalar or an array depending 1311 1358 on the data type and shape of the data group. 1312 1359 """ … … 1314 1361 # string - use ctypes allocator 1315 1362 size = int(shape[0]) 1316 pdata = ctypes.create_string_buffer(size) 1317 datafn = lambda: pdata.value 1363 data = ctypes.create_string_buffer(size) 1364 pdata = data 1365 datafn = lambda: data.value 1318 1366 else: 1319 # numeric - use numpy array 1320 if dtype=='char': dtype = 'uint8' 1321 data = numpy.zeros(shape,dtype) 1367 # scalar, array or string list - use numpy array 1368 if dtype=='char': 1369 data = numpy.zeros(shape[:-1], dtype='S%i'%shape[-1]) 1370 else: 1371 data = numpy.zeros(shape, dtype) 1322 1372 if len(shape) == 1 and shape[0] == 1: 1323 1373 datafn = lambda: data[0] … … 1326 1376 pdata = data.ctypes.data 1327 1377 size = data.nbytes 1328 return data fn,pdata,size1378 return data,pdata,size,datafn 1329 1379 1330 1380 def _pinput(self, data, dtype, shape): 1331 1381 """ 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. 1382 Convert an input array to a C pointer to a dense array. 1383 1384 Returns data, pdata where 1385 - data is a possibly new copy of the array 1386 - pdata is a pointer to the beginning of the array. 1387 Note that you must hold a reference to data for as long 1388 as you need pdata to keep the memory from being released to the heap. 1335 1389 """ 1336 1390 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)) 1391 data = numpy.asarray(data, dtype='S%d'%(shape[-1])) 1342 1392 else: 1343 1393 # Convert scalars to vectors of length one 1344 1394 if numpy.prod(shape) == 1 and not hasattr(data,'shape'): 1345 data = numpy.array([data], dtype=dtype)1395 data = numpy.array([data], dtype=dtype) 1346 1396 # Check that dimensions match 1347 1397 # Ick! need to exclude dimensions of length 1 in order to catch … … 1349 1399 input_shape = numpy.array([i for i in data.shape if i != 1]) 1350 1400 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(): 1401 if len(input_shape) != len(target_shape) \ 1402 or (input_shape != target_shape).any(): 1352 1403 raise ValueError,\ 1353 "Shape mismatch %s!=%s: %s"%(data.shape,shape,self.filename) 1404 "Shape mismatch %s!=%s: %s"%(data_shape,shape,self._loc()) 1405 # Check data type 1354 1406 if str(data.dtype) != dtype: 1355 1407 raise ValueError,\ 1356 1408 "Type mismatch %s!=%s: %s"%(dtype,data.dtype,self._loc()) 1357 1409 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 1410 data = numpy.ascontiguousarray(data) 1411 pdata = data.ctypes.data 1412 1367 1413 return data,pdata 1368 1414
Note: See TracChangeset
for help on using the changeset viewer.
