def getinfo(self): """ Returns the tuple dimensions,type for the currently open dataset. Dimensions is an integer array whose length corresponds to the rank of the dataset and whose elements are the size of the individual dimensions. Storage type is returned as a string, with 'char' for a stored string, '[u]int[8|16|32]' for various integer values or 'float[32|64]' for floating point values. No support for complex values. Raises RuntimeError if this fails. Note that this is the recommended way to establish if you have a dataset open. Corresponds to NXgetinfo(handle, &rank, dims, &storage), but with storage converted from HDF values to numpy compatible strings, and rank implicit in the length of the returned dimensions. """ rank = c_int(0) shape = numpy.zeros(MAXRANK, 'i') storage = c_int(0) status = self.lib.nxigetinfo_(self.handle, _ref(rank), shape.ctypes.data, _ref(storage)) if status == ERROR: raise RuntimeError, "Could not get data info: %s"%(self._loc()) shape = shape[:rank.value]+0 dtype = _pytype_code[storage.value] #print "data info",shape,dtype return shape,dtype
def getnextattr(self): """ Returns the name, length, and data type for the next attribute. Call getattrinfo to determine the number of attributes before calling getnextattr. Data type is returned as a string. See getinfo for details. Length is the number of elements in the attribute. Raises RuntimeError if NeXus returns ERROR or EOD. Corresponds to NXgetnextattr(handle,name,&length,&storage) but with storage converted from HDF values to numpy compatible strings. Note: NeXus API documentation seems to say that length is the number of bytes required to store the entire attribute. """ name = ctypes.create_string_buffer(MAXNAMELEN) length = c_int(0) storage = c_int(0) status = self.lib.nxigetnextattr_(self.handle,name,_ref(length),_ref(storage)) if status == ERROR or status == EOD: raise RuntimeError, "Could not get next attr: %s"%(self._loc()) dtype = _pytype_code[storage.value] #print "next attr",name.value,length.value,dtype return name.value, length.value, dtype
def sameID(self, ID1, ID2): """ Return True of ID1 and ID2 point to the same group/data. This should not raise any errors. Corresponds to NXsameID(handle,&ID1,&ID2) """ status = self.lib.nxisameid_(self.handle, _ref(ID1), _ref(ID2)) return status == OK
def __init__(self, filename, mode='r'): """ Open the NeXus file returning a handle. mode can be one of the following: nxs.ACC_READ 'r' nxs.ACC_RDWR 'rw' nxs.ACC_CREATE 'w' nxs.ACC_CREATE4 'w4' nxs.ACC_CREATE5 'w5' nxs.ACC_CREATEXML 'wx' Raises RuntimeError if the file could not be opened, with the filename as part of the error message. Corresponds to NXopen(filename,mode,&handle) """ self.isopen = False # Convert open mode from string to integer and check it is valid if mode in _nxopen_mode: mode = _nxopen_mode[mode] if mode not in _nxopen_mode.values(): raise ValueError, "Invalid open mode %s",str(mode) self.filename, self.mode = filename, mode self.handle = c_void_p(None) self.path = [] status = self.lib.nxiopen_(filename,mode,_ref(self.handle)) if status == ERROR: if mode in [ACC_READ, ACC_RDWR]: op = 'open' else: op = 'create' raise RuntimeError, "Could not %s %s"%(op,filename) self.isopen = True
def getattr(self, name, length, dtype): """ Returns the value of the named attribute. Requires length and data type from getnextattr to allocate the appropriate amount of space for the attribute. Corresponds to NXgetattr(handle,name,data,&length,&storage) """ datafn,pdata,size = self._poutput(str(dtype),[length]) storage = c_int(_nxtype_code[str(dtype)]) #print "retrieving",name,length,dtype,size size = c_int(size) status = self.lib.nxigetattr_(self.handle,name,pdata,_ref(size),_ref(storage)) if status == ERROR: raise ValueError, "Could not read attr %s: %s" % (name,self._loc()) #print "attr",name,datafn(),size return datafn()
def open(self): """ Opens the NeXus file handle if it is not already open. """ if self.isopen: return mode = ACC_READ if self.mode==ACC_READ else ACC_RDWR status = self.lib.nxiopen_(self.filename,mode,_ref(self.handle)) if status == ERROR: raise RuntimeError, "Could not open %s"%(self.filename) self.path = []
def flush(self): """ Flush all data to the NeXus file. Raises RuntimeError if this fails. Corresponds to NXflush(&handle) """ status = self.lib.nxiflush_(_ref(self.handle)) if status == ERROR: raise RuntimeError, "Could not flush NeXus file %s"%(self.filename)
def makenamedlink(self,name,ID): """ Link the previously captured group/data ID into the currently open group, but under a different name. Raises RuntimeError Corresponds to NXmakenamedlink(handle,name,&ID) """ status = self.lib.nximakenamedlink_(self.handle,name,_ref(ID)) if status == ERROR: raise RuntimeError, "Could not make link %s: %s"%(name,self._loc())
def getgroupID(self): """ Return the id of the current group so we can link to it later. Raises RuntimeError Corresponds to NXgetgroupID(handle, &ID) """ ID = _NXlink() status = self.lib.nxigetgroupid_(self.handle, _ref(ID)) if status == ERROR: raise RuntimeError, "Could not link to group: %s" % (self._loc()) return ID
def getdataID(self): """ Return the id of the current data so we can link to it later. Raises RuntimeError Corresponds to NXgetdataID(handle, &ID) """ ID = _NXlink() status = self.lib.nxigetdataid_(self.handle,_ref(ID)) if status == ERROR: raise RuntimeError, "Could not link to data: %s"%(self._loc()) return ID
def open(self): """ Opens the NeXus file handle if it is not already open. """ if self.isopen: return if self.mode == ACC_READ: mode = ACC_READ else: mode = ACC_RDWR status = self.lib.nxiopen_(self.filename, mode, _ref(self.handle)) if status == ERROR: raise RuntimeError, "Could not open %s" % (self.filename) self.path = []
def close(self): """ Close the NeXus file associated with handle. Raises RuntimeError if file could not be opened. Corresponds to NXclose(&handle) """ if self.isopen: self.isopen = False status = self.lib.nxiclose_(_ref(self.handle)) if status == ERROR: raise RuntimeError, "Could not close NeXus file %s"%(self.filename) self.path = []
def getattrinfo(self): """ Returns the number of attributes for the currently open group/data object. Do not call getnextattr() more than this number of times. Raises RuntimeError if this fails. Corresponds to NXgetattrinfo(handl, &n) """ n = c_int(0) status = self.lib.nxigetattrinfo_(self.handle, _ref(n)) if status == ERROR: raise RuntimeError, "Could not get attr info: %s" % (self._loc()) #print "num attrs",n.value return n.value
def getattrinfo(self): """ Returns the number of attributes for the currently open group/data object. Do not call getnextattr() more than this number of times. Raises RuntimeError if this fails. Corresponds to NXgetattrinfo(handl, &n) """ n = c_int(0) status = self.lib.nxigetattrinfo_(self.handle,_ref(n)) if status == ERROR: raise RuntimeError, "Could not get attr info: %s"%(self._loc()) #print "num attrs",n.value return n.value
def getgroupinfo(self): """ Query the currently open group returning the tuple numentries, path, nxclass. The path consists of names of subgroups starting at the root separated by "/". Raises ValueError if the group could not be opened. Corresponds to NXgetgroupinfo(handle) """ # Space for the returned strings path = ctypes.create_string_buffer(MAXPATHLEN) nxclass = ctypes.create_string_buffer(MAXNAMELEN) n = c_int(0) status = self.lib.nxigetgroupinfo_(self.handle, _ref(n), path, nxclass) if status == ERROR: raise ValueError, "Could not get group info: %s" % (self._loc()) #print "group info",nxclass.value,name.value,n.value return n.value, path.value, nxclass.value
def getgroupinfo(self): """ Query the currently open group returning the tuple numentries, path, nxclass. The path consists of names of subgroups starting at the root separated by "/". Raises ValueError if the group could not be opened. Corresponds to NXgetgroupinfo(handle) """ # Space for the returned strings path = ctypes.create_string_buffer(MAXPATHLEN) nxclass = ctypes.create_string_buffer(MAXNAMELEN) n = c_int(0) status = self.lib.nxigetgroupinfo_(self.handle,_ref(n),path,nxclass) if status == ERROR: raise ValueError, "Could not get group info: %s"%(self._loc()) #print "group info",nxclass.value,name.value,n.value return n.value,path.value,nxclass.value
def __init__(self, filename, mode='r'): """ Open the NeXus file returning a handle. Raises RuntimeError if the file could not be opened, with the filename as part of the error message. Corresponds to NXopen(filename,mode,&handle) """ # Convert open mode from string to integer and check it is valid self.isopen = False if mode in _nxopen_mode: mode = _nxopen_mode[mode] if mode not in _nxopen_mode.values(): raise ValueError, "Invalid open mode %s",str(mode) self.filename, self.mode = filename, mode self.handle = c_void_p(None) self.path = [] status = self.lib.nxiopen_(filename,mode,_ref(self.handle)) if status == ERROR: op = 'open' if mode in [ACC_READ, ACC_RDWR] else 'create' raise RuntimeError, "Could not %s %s"%(op,filename) self.isopen = True
def getnextentry(self): """ Return the next entry in the group as name,nxclass tuple. Raises RuntimeError if this fails, or if there is no next entry. Corresponds to NXgetnextentry(handle,name,nxclass,&storage). This function doesn't return the storage class for data entries since getinfo returns shape and storage, both of which are required to read the data. """ name = ctypes.create_string_buffer(MAXNAMELEN) nxclass = ctypes.create_string_buffer(MAXNAMELEN) storage = c_int(0) status = self.lib.nxigetnextentry_(self.handle,name,nxclass,_ref(storage)) if status == ERROR or status ==EOD: raise RuntimeError, \ "Could not get next entry: %s"%(self._loc()) ## Note: ignoring storage --- it is useless without dimensions #if nxclass == 'SDS': # dtype = _pytype_code(storage.value) #print "group next",nxclass.value, name.value, storage.value return name.value,nxclass.value
def getnextentry(self): """ Return the next entry in the group as name,nxclass tuple. Raises RuntimeError if this fails, or if there is no next entry. Corresponds to NXgetnextentry(handle,name,nxclass,&storage). This function doesn't return the storage class for data entries since getinfo returns shape and storage, both of which are required to read the data. """ name = ctypes.create_string_buffer(MAXNAMELEN) nxclass = ctypes.create_string_buffer(MAXNAMELEN) storage = c_int(0) status = self.lib.nxigetnextentry_(self.handle,name,nxclass,_ref(storage)) if status == ERROR or status == EOD: raise RuntimeError, \ "Could not get next entry: %s"%(self._loc()) ## Note: ignoring storage --- it is useless without dimensions #if nxclass == 'SDS': # dtype = _pytype_code(storage.value) #print "group next",nxclass.value, name.value, storage.value return name.value,nxclass.value