Changeset 1806 for trunk/bindings
- Timestamp:
- 22/01/12 23:07:59 (4 months ago)
- File:
-
- 1 edited
-
trunk/bindings/python/nxs/tree.py (modified) (40 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/bindings/python/nxs/tree.py
r1805 r1806 215 215 For higher than two dimensions, only the top slice is plotted by default. 216 216 217 The plot() method uses matplotlib by default to plot the data. You can replace 217 The plot method accepts as arguments the standard matplotlib.pyplot.plot format 218 strings to customize one-dimensional plots, axis and scale limits, and will 219 transmit keyword arguments to the matplotlib plotting methods. 220 221 >>> a=nx.load('chopper.nxs') 222 >>> a.entry.monitor1.plot() 223 >>> a.entry.monitor2.plot('r+', xmax=2600) 224 225 It is possible to plot over the existing figure with the oplot() method and to 226 plot with logarithmic intensity scales with the logplot() method. The x- and 227 y-axes can also be rendered logarithmically using the logx and logy keywards. 228 229 Although the plot() method uses matplotlib by default to plot the data, you can replace 218 230 this with your own plotter by setting nexus.NXgroup._plotter to your own plotter 219 231 class. The plotter class has one method:: … … 225 237 title is the title of the group or the parent NXentry, if available. 226 238 """ 239 from __future__ import with_statement 240 from copy import copy, deepcopy 241 242 import numpy as np 243 import napi 244 from napi import NeXusError 245 246 #Memory in MB 247 NX_MEMORY = 500 227 248 228 249 __all__ = ['NeXusTree', 'NXobject', 'NXfield', 'NXgroup', 'NXattr', 229 250 'NX_MEMORY', 'setmemory', 'load', 'save', 'tree', 'centers', 230 251 'NXlink', 'NXlinkfield', 'NXlinkgroup', 'SDS', 'NXlinkdata'] 231 232 from copy import copy, deepcopy233 234 import numpy as np235 import napi236 from napi import NeXusError237 238 #Memory in MB239 NX_MEMORY = 500240 252 241 253 #List of defined base classes (later added to __all__) … … 340 352 if 'target' in attrs and attrs['target'] != self.path: 341 353 # This is a linked dataset; don't try to load it. 342 #print "read link %s->%s"%(path,attrs['target'].nxdata)343 354 data = NXlinkfield(target=attrs['target'], name=name) 344 355 else: … … 354 365 data = NXfield(value=value,name=name,dtype=type,shape=dims,attrs=attrs) 355 366 self.closedata() 367 data._infile = data._saved = data._changed = True 356 368 return data 357 369 … … 383 395 if 'target' in attrs and attrs['target'] != self.path: 384 396 # This is a linked group; don't try to load it. 385 group = self.NXlinkgroup(target=attrs['target'], name=name)397 group = NXlinkgroup(target=attrs['target'], name=name) 386 398 else: 387 399 children = self._readchildren(n) … … 389 401 # NXentry class name use that constructor for the group 390 402 # rather than the generic NXgroup class. 391 # if hasattr(self,nxclass):392 # factory = getattr(self,nxclass)393 # else:394 # factory = self.NXgroup395 403 group = NXgroup(nxclass=nxclass,name=name,attrs=attrs,entries=children) 396 404 # Build chain back structure 397 405 for obj in children.values(): 398 406 obj._group = group 407 group._infile = group._saved = group._changed = True 399 408 return group 400 409 … … 434 443 435 444 path = path + "/" + data.nxname 436 shape = data.shape437 if data.shape == (): shape = (1,)438 445 439 446 # If the data is linked then 440 447 if hasattr(data,'_target'): 441 448 return [(path, data._target)] 449 450 shape = data.shape 451 if shape == (): shape = (1,) 442 452 443 453 #If the array size is too large, their product needs a long integer … … 720 730 _group = None 721 731 _file = None 732 _infile = False 733 _saved = False 734 _changed = True 722 735 723 736 def __str__(self): … … 794 807 to True. 795 808 """ 796 return self._str_tree(attrs= False,recursive=True)809 return self._str_tree(attrs=True,recursive=True) 797 810 798 811 @property … … 801 814 return self._str_tree(attrs=True,recursive=True) 802 815 816 def __enter__(self): 817 """ 818 Open the datapath for reading or writing. 819 820 Note: the results are undefined if you try accessing 821 more than one slab at a time. Don't nest your 822 "with data" statements! 823 """ 824 self._close_on_exit = not self.nxfile.isopen 825 self.nxfile.open() # Force file open even if closed 826 self.nxfile.openpath(self.nxpath) 827 self._incontext = True 828 return self.nxfile 829 830 def __exit__(self, type, value, traceback): 831 """ 832 Close the file associated with the data. 833 """ 834 self._incontext = False 835 if self._close_on_exit: 836 self.nxfile.close() 837 803 838 def save(self, filename=None, format='w5'): 804 839 """ … … 811 846 NXentry group (with name 'entry'), if necessary, in order to produce 812 847 a valid NeXus file. 813 """ 814 if self.nxclass == "NXroot": 815 root = self 816 if filename is None: 817 if self._file: 818 if self._file.mode == napi.ACC_READ: 819 raise NeXusError, "NeXus file is readonly" 820 else: 821 self._file.close() 822 filename = self._file.filename 823 elif filename: 824 if self.nxclass == "NXentry": 848 849 Example 850 ------- 851 >>> data = NXdata(sin(x), x) 852 >>> data.save('file.nxs') 853 >>> print data.nxroot.tree 854 root:NXroot 855 @HDF5_Version = 1.8.2 856 @NeXus_version = 4.2.1 857 @file_name = file.nxs 858 @file_time = 2012-01-20T13:14:49-06:00 859 entry:NXentry 860 data:NXdata 861 axis1 = float64(101) 862 signal = float64(101) 863 @axes = axis1 864 @signal = 1 865 >>> root.entry.data.axis1.units = 'meV' 866 >>> root.save() 867 """ 868 if filename: 869 if self.nxclass == "NXroot": 870 root = self 871 elif self.nxclass == "NXentry": 825 872 root = NXroot(self) 826 873 else: 827 874 root = NXroot(NXentry(self)) 828 829 if filename is None: 875 if root.nxfile: root.nxfile.close() 876 file = NeXusTree(filename, format) 877 file.writefile(root) 878 file.close() 879 root._file = NeXusTree(filename, 'rw') 880 root._setattrs(root._file.getattrs()) 881 for node in root.walk(): 882 node._infile = node._saved = True 883 884 elif self.nxfile: 885 for entry in self.nxroot.values(): 886 entry.write() 887 888 else: 830 889 raise NeXusError, "No output file specified" 831 890 832 # Preload the source tree 833 for node in root.walk(): 834 #print "node",node.nxname, node 835 if isinstance(node, NXfield): node.nxdata 836 if root._file: root._file.close() 837 file = NeXusTree(filename, format) 838 file.writefile(root) 839 file.close() 840 841 return load(filename, 'rw') 842 891 @property 892 def infile(self): 893 """ 894 Returns True if the object has been created in a NeXus file. 895 """ 896 return self._infile 897 898 @property 899 def saved(self): 900 """ 901 Returns True if the object has been saved to a file. 902 """ 903 return self._saved 904 905 @property 906 def changed(self): 907 """ 908 Returns True if the object has been changed. 909 910 This property is for use by external scripts that need to track 911 which NeXus objects have been changed. 912 """ 913 return self._changed 914 915 def set_unchanged(self): 916 """ 917 Set an object's change status to unchanged. 918 """ 919 self._changed = False 920 843 921 def _getclass(self): 844 922 return self._class … … 847 925 return self._name 848 926 927 def _setname(self, value): 928 self._name = str(value) 929 849 930 def _getgroup(self): 850 931 return self._group … … 852 933 def _getpath(self): 853 934 if self.nxgroup is None: 854 return " "935 return "/" 855 936 elif isinstance(self.nxgroup, NXroot): 856 937 return "/" + self.nxname … … 876 957 877 958 nxclass = property(_getclass, doc="Class of NeXus object") 878 nxname = property(_getname, doc="Name of NeXus object")959 nxname = property(_getname, _setname, doc="Name of NeXus object") 879 960 nxgroup = property(_getgroup, doc="Parent group of NeXus object") 880 961 nxpath = property(_getpath, doc="Path to NeXus object") 881 962 nxroot = property(_getroot, doc="Root group of NeXus object's tree") 882 963 nxfile = property(_getfile, doc="File handle of NeXus object's tree") 883 filename = property(_getfilename, doc="File name of NeXus object's tree")884 964 attrs = property(_getattrs, doc="NeXus attributes for an object") 885 965 … … 1134 1214 """ 1135 1215 1136 def __init__(self, value=None, name=' unknown', dtype=None, shape=(), attrs={}, group=None,1216 def __init__(self, value=None, name='field', dtype=None, shape=(), attrs={}, group=None, 1137 1217 **attr): 1138 1218 if isinstance(value, list) or isinstance(value, tuple): … … 1164 1244 if value is not None and dtype == 'char': value = str(value) 1165 1245 self._setdata(value) 1246 self._saved = False 1247 self._changed = True 1166 1248 1167 1249 def __repr__(self): … … 1190 1272 attributes for the NXfield class. 1191 1273 """ 1192 if name.startswith('_') :1274 if name.startswith('_') or name.startswith('nx'): 1193 1275 object.__setattr__(self, name, value) 1194 1276 elif isinstance(value, NXattr): 1195 1277 self._attrs[name] = value 1278 self._saved = False 1279 self._changed = True 1196 1280 else: 1197 1281 self._attrs[name] = NXattr(value) 1282 self._saved = False 1283 self._changed = True 1198 1284 1199 1285 def __getitem__(self, index): … … 1243 1329 if self._value is not None: 1244 1330 self.nxdata[index] = value 1331 self._saved = False 1332 self._changed = True 1245 1333 else: 1246 1334 raise NeXusError, "NXfield dataspace not yet allocated" … … 1403 1491 def reshape(self, shape): 1404 1492 """ 1405 Returns an NXfield with shape. 1406 """ 1407 self.shape = list(shape) 1408 if isinstance(self.nxdata, np.ndarray): self.nxdata.shape = shape 1409 return self 1410 1411 def transpose(self,shape=None):#added shape variable here 9/8/2010 1412 """ 1413 Returns an NXfield containing the transpose of the data array. Equivalent 1414 to the Numpy ndarray.transpose. 1415 """ 1416 # error, no shape variable in this scope 1417 return NXfield(value=self.nxdata.transpose(shape), name=self.nxname, 1493 Returns an NXfield with the specified shape. 1494 """ 1495 return NXfield(value=self.nxdata.reshape(shape), name=self.nxname, 1418 1496 attrs=self.attrs) 1497 1498 def transpose(self): 1499 """ 1500 Returns an NXfield containing the transpose of the data array. 1501 """ 1502 return NXfield(value=self.nxdata.transpose(), name=self.nxname, 1503 attrs=self.attrs) 1504 1505 @property 1506 def T(self): 1507 return self.transpose() 1419 1508 1420 1509 def centers(self): … … 1426 1515 name=self.nxname,attrs=self.attrs) 1427 1516 1428 def __enter__(self): 1429 """ 1430 Open the datapath for reading slab by slab. 1431 1432 Note: the results are undefined if you try accessing 1433 more than one slab at a time. Don't nest your 1434 "with data" statements! 1435 """ 1436 # TODO: provide a file lock to prevent movement of the 1437 # file cursor when in the slab context. 1438 # TODO: if HDF allows multiple cursors, extend napi to support them 1439 self._close_on_exit = not self.nxroot._file.isopen 1440 self.nxroot._file.open() # Force file open even if closed 1441 self.nxroot._file.openpath(self.nxpath) 1442 self._incontext = True 1443 return self 1444 1445 def __exit__(self, *args): 1446 """ 1447 Close the file associated with the data after reading. 1448 """ 1449 self._incontext = False 1450 if self._close_on_exit: 1451 self.nxroot._file.close() 1517 def read(self): 1518 """ 1519 Read the NXfield, including attributes, from the NeXus file. 1520 1521 The data values are read provided they do not exceed NX_MEMORY. In that 1522 case, the data have to be read in as slabs using the get method. 1523 """ 1524 if self.nxfile: 1525 with self as path: 1526 self._setattrs(path.getattrs()) 1527 shape, dtype = path.getinfo() 1528 if dtype == 'char': 1529 self._value = path.getdata() 1530 elif np.prod(shape) * np.dtype(dtype).itemsize <= NX_MEMORY*1024*1024: 1531 self._value = path.getdata() 1532 else: 1533 raise MemoryError, 'Data size larger than NX_MEMORY=%s MB' % NX_MEMORY 1534 self._shape = tuple(shape) 1535 self._dtype = dtype 1536 if dtype == 'char': 1537 self._dtype = 'char' 1538 elif dtype in np.typeDict: 1539 self._dtype = np.dtype(dtype) 1540 self._infile = self._saved = self._changed = True 1541 else: 1542 raise IOError("Data is not attached to a file") 1543 1544 def write(self): 1545 """ 1546 Write the NXfield, including attributes, to the NeXus file. 1547 """ 1548 if self.nxfile: 1549 if self.nxfile.mode == napi.ACC_READ: 1550 raise NeXusError, "NeXus file is readonly" 1551 if not self.infile: 1552 shape = self.shape 1553 if shape == (): shape = (1,) 1554 with self.nxgroup as path: 1555 if np.prod(shape) > 10000 or np.prod(shape) < 0: 1556 # Compress the fastest moving dimension of large datasets 1557 slab_dims = np.ones(len(shape),'i') 1558 if shape[-1] < 100000: 1559 slab_dims[-1] = shape[-1] 1560 else: 1561 slab_dims[-1] = 100000 1562 path.compmakedata(self.nxname, self.dtype, shape, 'lzw', 1563 slab_dims) 1564 else: 1565 # Don't use compression for small datasets 1566 path.makedata(self.nxname, self.dtype, shape) 1567 self._infile = True 1568 if not self.saved: 1569 with self as path: 1570 path._writeattrs(self.attrs) 1571 value = self.nxdata 1572 if value is not None: 1573 path.putdata(value) 1574 self._saved = True 1575 else: 1576 raise IOError("Data is not attached to a file") 1452 1577 1453 1578 def get(self, offset, size): … … 1458 1583 Offset and shape must each have one entry per dimension. 1459 1584 1460 This operation should be performed in a "with group.data"1461 context.1462 1463 Raises ValueError cannot convert units.1464 1465 1585 Corresponds to NXgetslab(handle,data,offset,shape) 1466 1586 """ 1467 if self.nxroot._file: 1468 self.__enter__() 1469 value = self.nxroot._file.getslab(offset,size) 1470 self.__exit__() 1471 return value 1472 else: 1473 raise NeXusError, "No input file specified for NXgetslab" 1587 if self.nxfile: 1588 with self as path: 1589 value = path.getslab(offset,size) 1590 return value 1591 else: 1592 raise IOError("Data is not attached to a file") 1474 1593 1475 1594 def put(self, data, offset, refresh=True): … … 1480 1599 Offset and shape must each have one entry per dimension. 1481 1600 1482 This operation should be performed in a "with group.data"1483 context.1484 1485 Raises NeXusError if this fails. No error is raised when1486 writing to a file which is open read-only.1487 1488 1601 Corresponds to NXputslab(handle,data,offset,shape) 1489 1602 """ 1490 if self.nx root._file:1491 if self.nx root._file.mode == napi.ACC_READ:1603 if self.nxfile: 1604 if self.nxfile.mode == napi.ACC_READ: 1492 1605 raise NeXusError, "NeXus file is readonly" 1493 self.__enter__() 1494 if isinstance(data, NXfield): 1495 self.nxroot._file.putslab(data.nxdata.astype(self.dtype), offset, 1496 data.shape) 1497 else: 1498 data = np.array(data) 1499 self.nxroot._file.putslab(data.astype(self.dtype), offset, 1500 data.shape) 1501 self.__exit__() 1606 with self as path: 1607 if isinstance(data, NXfield): 1608 path.putslab(data.nxdata.astype(self.dtype), offset, data.shape) 1609 else: 1610 data = np.array(data) 1611 path.putslab(data.astype(self.dtype), offset, data.shape) 1502 1612 if refresh: self.refresh() 1503 1613 else: 1504 raise NeXusError, "No output file specified for NXputslab"1505 1506 def add(self, data, offset ):1614 raise IOError("Data is not attached to a file") 1615 1616 def add(self, data, offset, refresh=True): 1507 1617 """ 1508 1618 Add a slab into the data array. … … 1518 1628 value = self.get(offset, data.shape) 1519 1629 self.put(data.astype(self.dtype)+value, offset) 1630 if refresh: self.refresh() 1520 1631 1521 1632 def refresh(self): … … 1523 1634 Rereads the data from the file. 1524 1635 1525 Calls net to read in data again. If put has been called, then 1526 nxdata is no longer synchronized with the file making a refresh 1527 necessary. This will only be performed if nxdata already stores the 1528 data. 1636 If put has been called, then nxdata is no longer synchronized with the 1637 file making a refresh necessary. This will only be performed if nxdata 1638 already stores the data. 1529 1639 """ 1530 1640 if self._value is not None: 1531 if self.nxroot._file: 1532 self._value = self.nxroot._file.readpath(self.nxpath) 1641 if self.nxfile: 1642 self._value = self.nxfile.readpath(self.nxpath) 1643 self._infile = self._saved = True 1533 1644 else: 1534 raise NeXusError, "No file specified for reads"1645 raise IOError("Data is not attached to a file") 1535 1646 1536 1647 def convert(self, units=""): … … 1591 1702 """ 1592 1703 if self._value is None: 1593 if self.nx root._file:1704 if self.nxfile: 1594 1705 if str(self.dtype) == 'char': 1595 self._value = self.nx root._file.readpath(self.nxpath)1706 self._value = self.nxfile.readpath(self.nxpath) 1596 1707 elif np.prod(self.shape) * np.dtype(self.dtype).itemsize <= NX_MEMORY*1024*1024: 1597 self._value = self.nx root._file.readpath(self.nxpath)1708 self._value = self.nxfile.readpath(self.nxpath) 1598 1709 else: 1599 1710 raise MemoryError, 'Data size larger than NX_MEMORY=%s MB' % NX_MEMORY 1711 self._saved = True 1600 1712 else: 1601 1713 return None … … 1616 1728 self._shape = self._value.shape 1617 1729 self._dtype = self._value.dtype 1618 1730 self._saved = False 1731 self._changed = True 1732 1619 1733 def _getdtype(self): 1620 1734 return self._dtype … … 1628 1742 nxdata = property(_getdata,_setdata,doc="The data values") 1629 1743 nxaxes = property(_getaxes,doc="The plotting axes") 1630 dtype = property(_getdtype, "Data type of NeXus field")1631 shape = property(_getshape, "Shape of NeXus field")1632 size = property(_getsize, "Size of NeXus field")1744 dtype = property(_getdtype,doc="Data type of NeXus field") 1745 shape = property(_getshape,doc="Shape of NeXus field") 1746 size = property(_getsize,doc="Size of NeXus field") 1633 1747 1634 1748 SDS = NXfield # For backward compatibility … … 1721 1835 plt.title(title) 1722 1836 plt.ion() 1723 plt.show()1724 1837 1725 1838 #Two dimensional plot … … 1741 1854 z = np.clip(data,zmin,zmax).T 1742 1855 1743 ax = plt.gca()1744 extent = (x[0],x[-1],y[0],y[-1])1745 1856 if log: 1746 1857 opts["norm"] = LogNorm() … … 1748 1859 z = np.clip(z,0.1,zmax) 1749 1860 1861 ax = plt.gca() 1862 extent = (x[0],x[-1],y[0],y[-1]) 1750 1863 im = NonUniformImage(ax, extent=extent, origin=None, **opts) 1751 1864 im.set_data(x,y,z) … … 1775 1888 plt.title(title) 1776 1889 plt.colorbar(im) 1777 plt.gcf().canvas.draw_idle() 1778 1779 return plt.gcf() 1890 1891 plt.gcf().canvas.draw_idle() 1780 1892 1781 1893 @staticmethod … … 2018 2130 except AttributeError: 2019 2131 raise NeXusError, "Non-keyword arguments must be valid NXobjects" 2132 self._saved = False 2133 self._changed = True 2020 2134 2021 2135 # def __cmp__(self, other): … … 2067 2181 is set to the assigned value. 2068 2182 """ 2069 if name.startswith('_') :2183 if name.startswith('_') or name.startswith('nx'): 2070 2184 object.__setattr__(self, name, value) 2071 2185 elif isinstance(value, NXattr): 2072 2186 self._attrs[name] = value 2187 self._saved = False 2188 self._changed = True 2073 2189 else: 2074 2190 self[name] = value … … 2136 2252 def __setitem__(self, key, value): 2137 2253 """ 2138 Includes a NeXus group item by adding it to the 'entries' dictionary. 2139 """ 2254 Adds or modifies an item in the NeXus group. 2255 """ 2256 if key in self.entries: 2257 infile = self[key]._infile 2258 attrs = self[key].attrs 2259 if isinstance(self[key], NXlink): 2260 if self._entries[key].nxlink: 2261 setattr(self._entries[key].nxlink.nxgroup, key, value) 2262 return 2263 else: 2264 infile = None 2265 attrs = {} 2140 2266 if isinstance(value, NXlink): 2141 2267 self._entries[key] = value … … 2149 2275 self._entries[key] = value 2150 2276 else: 2151 self._entries[key] = NXfield(value=value, name=key, group=self) 2277 self._entries[key] = NXfield(value=value, name=key, group=self, attrs=attrs) 2278 if infile is not None: self[key]._infile = infile 2279 self._changed = True 2152 2280 2153 2281 def __deepcopy__(self, memo): … … 2210 2338 """ 2211 2339 if isinstance(target, NXobject): 2212 self .entries[target.nxname] = NXlink(target=target, name=target.nxname, group=self)2340 self[target.nxname] = NXlink(target=target, group=self) 2213 2341 else: 2214 2342 raise NeXusError, "Link target must be an NXobject" 2343 2344 def write(self): 2345 """ 2346 Write the NXgroup, including its children, to the NeXus file. 2347 """ 2348 if self.nxfile: 2349 if self.nxfile.mode == napi.ACC_READ: 2350 raise NeXusError, "NeXus file is readonly" 2351 if not self.infile: 2352 with self.nxgroup as path: 2353 path.makegroup(self.nxname, self.nxclass) 2354 self._infile = True 2355 with self as path: 2356 path._writeattrs(self.attrs) 2357 for entry in self.walk(): 2358 if entry is not self: entry.write() 2359 self._infile = self._saved = True 2360 else: 2361 raise IOError("Group is not attached to a file") 2215 2362 2216 2363 def sum(self, axis=None): … … 2423 2570 def __init__(self, target=None, name='link', group=None): 2424 2571 self._group = group 2425 self._name = name2426 2572 if isinstance(target, NXobject): 2573 self._name = target.nxname 2427 2574 self._target = target.nxpath 2575 self.nxlink.attrs["target"] = target.nxpath 2428 2576 if target.nxclass == "NXlink": 2429 2577 raise NeXusError, "Cannot link to another NXlink object" … … 2433 2581 self.__class__ = NXlinkgroup 2434 2582 else: 2583 self._name = name 2435 2584 self._target = target 2436 2585 … … 2444 2593 raise KeyError, (key+" not in %s" % self._target) 2445 2594 2595 def __setattr__(self, name, value): 2596 if name.startswith('_') or name.startswith('nx'): 2597 object.__setattr__(self, name, value) 2598 elif self.nxlink: 2599 self.nxlink.__setattr__(name, value) 2600 2446 2601 def __repr__(self): 2447 2602 return "NXlink('%s')"%(self._target) 2448 2603 2449 2604 def __str__(self): 2450 return "NXlink('%s')"%(self._target)2605 return str(self.nxlink) 2451 2606 2452 2607 def _str_tree(self, indent=0, attrs=False, recursive=False): … … 2471 2626 return self.nxlink.attrs 2472 2627 2628 nxlink = property(_getlink, "Linked object") 2629 attrs = property(_getattrs,doc="NeXus attributes for object") 2630 2631 2632 class NXlinkfield(NXlink, NXfield): 2633 2634 """ 2635 Class for a NeXus linked field. 2636 2637 The real field will be accessible by following the link attribute. 2638 """ 2639 2640 def write(self): 2641 """ 2642 Write the linked NXfield. 2643 """ 2644 self.nxlink.write() 2645 if not self.infile: 2646 with self.nxlink as path: 2647 target = path.getdataID() 2648 with self.nxgroup as path: 2649 path.makelink(target) 2650 self._infile = self._saved = True 2651 2652 2653 def get(self, offset, size): 2654 """ 2655 Get a slab from the data array. 2656 2657 Offsets are 0-origin. Shape can be inferred from the data. 2658 Offset and shape must each have one entry per dimension. 2659 2660 This operation should be performed in a "with group.data" 2661 conext. 2662 2663 Raises ValueError cannot convert units. 2664 2665 Corresponds to NXgetslab(handle,data,offset,shape) 2666 """ 2667 if self.nxfile: 2668 with self.nxlink as path: 2669 value = path.getslab(offset,size) 2670 else: 2671 raise IOError("Data is not attached to a file") 2672 2673 NXlinkdata = NXlinkfield # For backward compatibility 2674 2675 class NXlinkgroup(NXlink, NXgroup): 2676 2677 """ 2678 Class for a NeXus linked group. 2679 2680 The real group will be accessible by following the link attribute. 2681 """ 2682 2683 def write(self): 2684 """ 2685 Write the linked NXgroup. 2686 """ 2687 self.nxlink.write() 2688 if not self.infile: 2689 with self.nxlink as path: 2690 target = path.getgroupID() 2691 with self.nxgroup as path: 2692 path.makelink(target) 2693 self._infile = self._saved = True 2694 2473 2695 def _getentries(self): 2474 2696 return self.nxlink.entries 2475 2697 2476 nxlink = property(_getlink, "Linked object")2477 attrs = property(_getattrs,doc="NeXus attributes for object")2478 2698 entries = property(_getentries,doc="NeXus objects within group") 2479 2480 2481 class NXlinkfield(NXlink, NXfield):2482 2483 """2484 Class for a NeXus linked field.2485 2486 The real field will be accessible by following the link attribute.2487 """2488 2489 def __setattr__(self, name, value):2490 if name.startswith('_'):2491 object.__setattr__(self, name, value)2492 elif name == "name" or name == "nxclass" or name == "group":2493 NXfield.__setattr__(self, name, value)2494 elif self.nxlink:2495 self.nxlink.__setattr__(name, value)2496 2497 def get(self, offset, size):2498 """2499 Get a slab from the data array.2500 2501 Offsets are 0-origin. Shape can be inferred from the data.2502 Offset and shape must each have one entry per dimension.2503 2504 This operation should be performed in a "with group.data"2505 conext.2506 2507 Raises ValueError cannot convert units.2508 2509 Corresponds to NXgetslab(handle,data,offset,shape)2510 """2511 if self.nxroot._file:2512 self.nxlink.__enter__()2513 value = self.nxlink.nxroot._file.getslab(offset,size)2514 self.nxlink.__exit__()2515 else:2516 raise NeXusError, "No input file specified for NXgetslab"2517 2518 NXlinkdata = NXlinkfield # For backward compatibility2519 2520 class NXlinkgroup(NXlink, NXgroup):2521 2522 """2523 Class for a NeXus linked group.2524 2525 The real group will be accessible by following the link attribute.2526 """2527 2528 def __setattr__(self, name, value):2529 if name.startswith('_'):2530 object.__setattr__(self, name, value)2531 elif name == "name" or name == "nxclass" or name == "group":2532 NXgroup.__setattr__(self, name, value)2533 elif self.nxlink:2534 if not isinstance(value, NXobject): value = NXfield(value=value, name=name)2535 value._group = self2536 value._name = name2537 object.__setattr__(self, name, value)2538 setattr(self.nxlink, name, value)2539 2699 2540 2700
Note: See TracChangeset
for help on using the changeset viewer.
