Ignore:
Timestamp:
14/04/09 18:56:40 (3 years ago)
Author:
Freddie Akeroyd
Message:

Merg in r1212:r1222 from trunk. Refs #115.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/4.2/bindings/python/nxs/napi.py

    r1205 r1230  
    419419        Corresponds to NXmakegroup(handle, name, nxclass) 
    420420        """ 
     421        #print "makegroup",self._loc(),name,nxclass 
    421422        status = nxlib.nximakegroup_(self.handle, name, nxclass) 
    422423        if status == ERROR: 
     
    556557        Corresponds to NXopengroup(handle, name, nxclass) 
    557558        """ 
    558         #print "open group",nxclass,name 
     559        #print "opengroup",self._loc(),name,nxclass 
    559560        if nxclass is None: 
    560561            nxclass = self.__getnxclass(name) 
     
    575576        Corresponds to NXclosegroup(handle) 
    576577        """ 
    577         #print "close group" 
     578        #print "closegroup" 
     579        if self._indata: 
     580            raise NeXusError, "Close data before group at %s"%(self._loc()) 
    578581        status = nxlib.nxiclosegroup_(self.handle) 
    579582        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()) 
    581584        self._path.pop() 
    582585 
     
    603606        if status == ERROR: 
    604607            raise ValueError, "Could not get group info: %s"%(self._loc()) 
    605         #print "group info",nxclass.value,name.value,n.value 
     608        #print "getgroupinfo",self._loc(),nxclass.value,name.value,n.value 
    606609        name = path.value.split('/')[-1]  # Protect against HDF5 returning path 
    607610        return n.value,name,nxclass.value 
     
    655658        #if nxclass == 'SDS': 
    656659        #    dtype = _pytype_code(storage.value) 
    657         #print "group next",nxclass.value, name.value, storage.value 
     660        #print "nextentry",nxclass.value, name.value, storage.value 
    658661        return name.value,nxclass.value 
    659662 
     
    728731 
    729732    # ==== Data ==== 
    730     nxlib.nxigetinfo_.restype = c_int 
    731     nxlib.nxigetinfo_.argtypes = [c_void_p, c_int_p, c_void_p, c_int_p] 
    732     def getinfo(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): 
    733736        """ 
    734737        Returns the tuple dimensions,type for the currently open dataset. 
     
    740743        complex values. 
    741744 
     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 
    742781        Raises NeXusError if this fails. 
    743782 
     
    758797        shape = shape[:rank.value]+0 
    759798        dtype = _pytype_code[storage.value] 
    760         #print "data info",shape,dtype 
     799        #print "getinfo",self._loc(),"->",shape,dtype 
    761800        return shape,dtype 
    762801 
     
    771810        Corresponds to NXopendata(handle, name) 
    772811        """ 
    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) 
    775817        if status == ERROR: 
    776818            raise ValueError, "Could not open data %s: %s"%(name, self._loc()) 
     
    789831        Corresponds to NXclosedata(handle) 
    790832        """ 
    791         #print "closing data" 
     833        #print "closedata" 
    792834        status = nxlib.nxiclosedata_(self.handle) 
    793835        if status == ERROR: 
    794836            raise NeXusError,\ 
    795                 "Could not close data at %s"%(name,self._loc()) 
     837                "Could not close data at %s"%(self._loc()) 
    796838        self._path.pop() 
    797839        self._indata = False 
     
    815857        # TODO: With keywords for value and attr, this can be used for 
    816858        # TODO: makedata, opendata, putdata, putattr, putattr, ..., closedata 
    817         #print "Data",name,dtype,shape 
     859        #print "makedata",self._loc(),name,shape,dtype 
    818860        storage = _nxtype_code[str(dtype)] 
    819861        shape = numpy.array(shape,'i') 
     
    865907        Return the data.  If data is a string (1-D char array), a python 
    866908        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. 
    868913 
    869914        Raises ValueError if this fails. 
     
    873918        # TODO: consider accepting preallocated data so we don't thrash memory 
    874919        shape,dtype = self.getinfo() 
    875         datafn,pdata,size = self._poutput(dtype,shape) 
     920        data,pdata,size,datafn = self._poutput(dtype,shape) 
    876921        status = nxlib.nxigetdata_(self.handle,pdata) 
    877922        if status == ERROR: 
    878923            raise ValueError, "Could not read data: %s"%(self._loc()) 
    879         #print "data",ret() 
     924        #print "getdata",self._loc(),shape,dtype 
    880925        return datafn() 
    881926 
     
    894939        """ 
    895940        # TODO: consider accepting preallocated data so we don't thrash memory 
    896         shape,dtype = self.getinfo() 
    897         datafn,pdata,size = self._poutput(dtype,slab_shape) 
     941        shape,dtype = self.getrawinfo() 
     942        data,pdata,size,datafn = self._poutput(dtype,slab_shape) 
    898943        slab_offset = numpy.array(slab_offset,'i') 
    899944        slab_shape = numpy.array(slab_shape,'i') 
     
    916961        Corresponds to NXputdata(handle, data) 
    917962        """ 
    918         shape,dtype = self.getinfo() 
     963        shape,dtype = self.getrawinfo() 
     964        #print "putdata",self._loc(),shape,dtype 
    919965        data,pdata = self._pinput(data,dtype,shape) 
    920966        status = nxlib.nxiputdata_(self.handle,pdata) 
     
    935981        Corresponds to NXputslab(handle,data,offset,shape) 
    936982        """ 
    937         shape,dtype = self.getinfo() 
     983        shape,dtype = self.getrawinfo() 
    938984        data,pdata = self._pinput(data,dtype,slab_shape) 
    939985        slab_offset = numpy.array(slab_offset,'i') 
     
    10111057            raise NeXusError, "Could not get next attr: %s"%(self._loc()) 
    10121058        dtype = _pytype_code[storage.value] 
    1013         #print "next attr",name.value,length.value,dtype 
     1059        #print "getnextattr",name.value,length.value,dtype 
    10141060        return name.value, length.value, dtype 
    10151061 
     
    10271073        """ 
    10281074        if dtype is 'char': length += 1  # HDF4 needs zero-terminator 
    1029         datafn,pdata,size = self._poutput(str(dtype),[length]) 
     1075        data,pdata,size,datafn = self._poutput(str(dtype),[length]) 
    10301076        storage = c_int(_nxtype_code[str(dtype)]) 
    1031         #print "retrieving",name,length,dtype,size 
     1077        #print "getattr",self._loc(),name,length,size,dtype 
    10321078        size = c_int(size) 
    10331079        status = nxlib.nxigetattr_(self.handle,name,pdata,_ref(size),_ref(storage)) 
    10341080        if status == ERROR: 
    10351081            raise ValueError, "Could not read attr %s: %s" % (name,self._loc()) 
    1036         #print "attr",name,datafn(),size 
     1082        #print "getattr",self._loc(),name,datafn() 
    10371083        return datafn() 
    10381084 
     
    13041350        """ 
    13051351        Build space to collect a nexus data element. 
    1306         Returns datafn,data,size where 
    1307         - datafn 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 
    13091355        - 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 
    13111358        on the data type and shape of the data group. 
    13121359        """ 
     
    13141361            # string - use ctypes allocator 
    13151362            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 
    13181366        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) 
    13221372            if len(shape) == 1 and shape[0] == 1: 
    13231373                datafn = lambda: data[0] 
     
    13261376            pdata = data.ctypes.data 
    13271377            size = data.nbytes 
    1328         return datafn,pdata,size 
     1378        return data,pdata,size,datafn 
    13291379 
    13301380    def _pinput(self, data, dtype, shape): 
    13311381        """ 
    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. 
    13351389        """ 
    13361390        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])) 
    13421392        else: 
    13431393            # Convert scalars to vectors of length one 
    13441394            if numpy.prod(shape) == 1 and not hasattr(data,'shape'): 
    1345                 data = numpy.array([data],dtype=dtype) 
     1395                data = numpy.array([data], dtype=dtype) 
    13461396            # Check that dimensions match 
    13471397            # Ick! need to exclude dimensions of length 1 in order to catch 
     
    13491399            input_shape = numpy.array([i for i in data.shape if i != 1]) 
    13501400            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(): 
    13521403                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 
    13541406            if str(data.dtype) != dtype: 
    13551407                raise ValueError,\ 
    13561408                    "Type mismatch %s!=%s: %s"%(dtype,data.dtype,self._loc()) 
    13571409 
    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             
    13671413        return data,pdata 
    13681414 
Note: See TracChangeset for help on using the changeset viewer.