Changeset 1804 for trunk/bindings/python/nxs
- Timestamp:
- 19/01/12 21:46:58 (4 months ago)
- File:
-
- 1 edited
-
trunk/bindings/python/nxs/tree.py (modified) (142 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/bindings/python/nxs/tree.py
r1803 r1804 9 9 1. To provide convenient access to existing data contained in NeXus files. 10 10 2. To enable new NeXus data to be created and manipulated interactively. 11 11 12 12 These goals are achieved by mapping hierarchical NeXus data structures directly 13 13 into python objects, which either represent NeXus groups or NeXus fields. … … 75 75 >>> X,Y=np.meshgrid(y,x) 76 76 >>> z=np.sin(X)*np.sin(Y) 77 78 Then a NeXus data groups are created and the data inserted to produce a 77 78 Then a NeXus data groups are created and the data inserted to produce a 79 79 NeXus-compliant structure that can be saved to a file. 80 80 … … 147 147 * nxdata attribute data 148 148 149 There is a subclass of NXgroup for each group class defined by the NeXus standard, 149 There is a subclass of NXgroup for each group class defined by the NeXus standard, 150 150 so it is possible to create an NXgroup of NeXus class NXsample directly using: 151 151 152 152 >>> sample = NXsample() 153 153 154 The default group name will be the class name following the 'NX', so the above 155 group will have an nxname of 'sample'. However, this is overridden by the 154 The default group name will be the class name following the 'NX', so the above 155 group will have an nxname of 'sample'. However, this is overridden by the 156 156 attribute name when it is assigned as a group attribute, e.g., 157 157 … … 164 164 specify which one to use. For example, 165 165 166 tree.NXentry[0].NXinstrument[0].NXdetector[0].distance 167 168 references the first detector of the first instrument of the first entry. 166 tree.NXentry[0].NXinstrument[0].NXdetector[0].distance 167 168 references the first detector of the first instrument of the first entry. 169 169 Unfortunately, there is no guarantee regarding the order of the entries, and it 170 170 may vary from call to call, so this is mainly useful in iterative searches. … … 225 225 """ 226 226 227 __all__ = ['NeXusTree', 'NXobject', 'NXfield', 'NXgroup', 'NXattr', 228 'NX_MEMORY', 'setmemory', 'load', 'save', 'tree', 'centers', 227 __all__ = ['NeXusTree', 'NXobject', 'NXfield', 'NXgroup', 'NXattr', 228 'NX_MEMORY', 'setmemory', 'load', 'save', 'tree', 'centers', 229 229 'NXlink', 'NXlinkfield', 'NXlinkgroup', 'SDS', 'NXlinkdata'] 230 230 … … 288 288 Read the NeXus file structure from the file and return a tree of NXobjects. 289 289 290 Large datasets are not read until they are needed. 290 Large datasets are not read until they are needed. 291 291 """ 292 292 self.open() … … 294 294 root = self._readgroup() 295 295 self.close() 296 root._group = None 296 root._group = None 297 297 # Resolve links (not necessary now that link is set as a property) 298 298 #self._readlinks(root, root) … … 304 304 Write the NeXus file structure to a file. 305 305 306 The file is assumed to start empty. Updating individual objects can be 306 The file is assumed to start empty. Updating individual objects can be 307 307 done using the napi interface, with nx.handle as the nexus file handle. 308 308 """ … … 379 379 n,name,nxclass = self.getgroupinfo() 380 380 attrs = {} 381 attrs = self.getattrs() 381 attrs = self.getattrs() 382 382 if 'target' in attrs and attrs['target'] != self.path: 383 383 # This is a linked group; don't try to load it. … … 397 397 obj._group = group 398 398 return group 399 399 400 400 def _readlinks(self, root, group): 401 401 """ … … 413 413 elif isinstance(entry, NXgroup): 414 414 self._readlinks(root, entry) 415 415 416 416 def _writeattrs(self, attrs): 417 417 """ 418 418 Return the attributes for the currently open group/data. 419 419 420 420 If no group or data object is open, the file attributes are returned. 421 421 """ … … 446 446 if shape[-1] < 100000: 447 447 slab_dims[-1] = shape[-1] 448 else: 448 else: 449 449 slab_dims[-1] = 100000 450 450 self.compmakedata(data.nxname, data.dtype, shape, 'lzw', slab_dims) … … 493 493 """ 494 494 Create links within the NeXus file. 495 495 496 496 THese are defined by the set of pairs returned by _writegroup. 497 497 """ … … 527 527 """ 528 528 Return a list of axis names stored in the 'axes' attribute. 529 529 530 530 The delimiter separating each axis can be white space, a comma, or a colon. 531 531 """ … … 540 540 A dictionary class to assign all attributes to the NXattr class. 541 541 """ 542 542 543 543 def __setitem__(self, key, value): 544 544 if isinstance(value, NXattr): … … 552 552 """ 553 553 Class for NeXus attributes of a NXfield or NXgroup object. 554 555 This class is only used for NeXus attributes that are stored in a 556 NeXus file and helps to distinguish them from Python attributes. 554 555 This class is only used for NeXus attributes that are stored in a 556 NeXus file and helps to distinguish them from Python attributes. 557 557 There are two Python attributes for each NeXus attribute. 558 558 559 559 Python Attributes 560 560 ----------------- … … 565 565 a string attribute or the string of the corresponding Numpy data type 566 566 for a numeric attribute. 567 567 568 568 NeXus Attributes 569 569 ---------------- 570 570 NeXus attributes are stored in the 'attrs' dictionary of the parent object, 571 571 NXfield or NXgroup, but can often be referenced or assigned using the 572 attribute name as if it were an object attribute. 573 572 attribute name as if it were an object attribute. 573 574 574 For example, after assigning the NXfield, the following three attribute 575 575 assignments are all equivalent:: … … 579 579 >>> entry.sample.temperature.units = NXattr('K') 580 580 >>> entry.sample.temperature.units = 'K' 581 582 The third version above is only allowed for NXfield attributes and is 581 582 The third version above is only allowed for NXfield attributes and is 583 583 not allowed if the attribute has the same name as one of the following 584 584 internally defined attributes, i.e., 585 586 ['entries', 'attrs', 'dtype','shape'] 587 588 or if the attribute name begins with 'nx' or '_'. It is only possible to 585 586 ['entries', 'attrs', 'dtype','shape'] 587 588 or if the attribute name begins with 'nx' or '_'. It is only possible to 589 589 reference attributes with one of the proscribed names using the 'attrs' 590 590 dictionary. … … 606 606 self._data,self._dtype = str(value), 'char' 607 607 elif value is not None: 608 if isinstance(value, NXobject): 608 if isinstance(value, NXobject): 609 609 raise NeXusError, "A data attribute cannot be a NXfield or NXgroup" 610 610 else: … … 639 639 """ 640 640 return self._data 641 641 642 642 def _getdtype(self): 643 643 return self._dtype 644 644 645 645 nxdata = property(_getdata,doc="The attribute values") 646 646 dtype = property(_getdtype, "Data type of NeXus attribute") … … 652 652 """ 653 653 Abstract base class for elements in NeXus files. 654 654 655 655 The object has a subclass of NXfield, NXgroup, or one of the NXgroup 656 656 subclasses. Child nodes should be accessible directly as object attributes. 657 657 Constructors for NXobject objects are defined by either the NXfield or 658 658 NXgroup classes. 659 659 660 660 Python Attributes 661 661 ----------------- … … 664 664 be one of the NXgroup subclasses. 665 665 nxname : string 666 The name of the NXobject. Since it is possible to reference the same 666 The name of the NXobject. Since it is possible to reference the same 667 667 Python object multiple times, this is not necessarily the same as the 668 668 object name. However, if the object is part of a NeXus tree, this will 669 be the attribute name within the tree. 669 be the attribute name within the tree. 670 670 nxgroup : NXgroup 671 The parent group containing this object within a NeXus tree. If the 671 The parent group containing this object within a NeXus tree. If the 672 672 object is not part of any NeXus tree, it will be set to None. 673 673 nxpath : string 674 674 The path to this object with respect to the root of the NeXus tree. For 675 675 NeXus data read from a file, this will be a group of class NXroot, but 676 if the NeXus tree was defined interactively, it can be any valid 676 if the NeXus tree was defined interactively, it can be any valid 677 677 NXgroup. 678 678 nxroot : NXgroup 679 679 The root object of the NeXus tree containing this object. For 680 680 NeXus data read from a file, this will be a group of class NXroot, but 681 if the NeXus tree was defined interactively, it can be any valid 681 if the NeXus tree was defined interactively, it can be any valid 682 682 NXgroup. 683 683 nxfile : NeXusTree 684 The file handle of the root object of the NeXus tree containing this 684 The file handle of the root object of the NeXus tree containing this 685 685 object. 686 686 filename : string … … 693 693 dir(self, attrs=False, recursive=False): 694 694 Print the group directory. 695 695 696 696 The directory is a list of NeXus objects within this group, either NeXus 697 697 groups or NXfield data. If 'attrs' is True, NXfield attributes are … … 701 701 tree: 702 702 Print the object's tree. 703 704 It invokes the 'dir' method with both 'attrs' and 'recursive' 703 704 It invokes the 'dir' method with both 'attrs' and 'recursive' 705 705 set to True. Note that this method is defined as a property attribute and 706 706 does not require parentheses. … … 709 709 Save the NeXus group into a file 710 710 711 The object is wrapped in an NXroot group (with name 'root') and an 712 NXentry group (with name 'entry'), if necessary, in order to produce 711 The object is wrapped in an NXroot group (with name 'root') and an 712 NXentry group (with name 'entry'), if necessary, in order to produce 713 713 a valid NeXus file. 714 714 … … 725 725 def __repr__(self): 726 726 return "NXobject('%s','%s')"%(self.nxclass,self.nxname) 727 727 728 728 def _setattrs(self, attrs): 729 729 for k,v in attrs.items(): 730 730 self._attrs[k] = v 731 731 732 732 def _str_name(self,indent=0): 733 733 if self.nxclass == 'NXfield': … … 752 752 """ 753 753 result = [self._str_name(indent=indent)] 754 if attrs and self.attrs: 754 if attrs and self.attrs: 755 755 result.append(self._str_attrs(indent=indent+2)) 756 756 # Print children … … 769 769 return "\n".join(result) 770 770 771 def walk(self): 772 print "yielding",self.nxname,self.nxclass 773 if False: yield 774 775 771 776 def dir(self,attrs=False,recursive=False): 772 777 """ 773 778 Print the object directory. 774 775 The directory is a list of NeXus objects within this object, either 776 NeXus groups or NXfields. If 'attrs' is True, NXfield attributes are 777 displayed. If 'recursive' is True, the contents of child groups are 779 780 The directory is a list of NeXus objects within this object, either 781 NeXus groups or NXfields. If 'attrs' is True, NXfield attributes are 782 displayed. If 'recursive' is True, the contents of child groups are 778 783 also displayed. 779 784 """ … … 784 789 """ 785 790 Print the directory tree. 786 787 The tree contains all child objects of this object and their children. 788 It invokes the 'dir' method with both 'attrs' and 'recursive' set 791 792 The tree contains all child objects of this object and their children. 793 It invokes the 'dir' method with both 'attrs' and 'recursive' set 789 794 to True. 790 795 """ 791 print self._str_tree(attrs=True,recursive=True) 792 793 def treestr(self, attrs=True): 796 return self._str_tree(attrs=False,recursive=True) 797 798 @property 799 def tree_with_attrs(self, attrs=True): 794 800 """Return directory tree string""" 795 return self._str_tree(attrs= attrs,recursive=True)796 801 return self._str_tree(attrs=True,recursive=True) 802 797 803 def save(self, filename=None, format='w5'): 798 804 """ 799 805 Save the NeXus object to a data file. 800 801 An error is raised if the object is an NXroot group from an external file 802 that has been opened as readonly and no file name is specified. 803 804 The object is wrapped in an NXroot group (with name 'root') and an 805 NXentry group (with name 'entry'), if necessary, in order to produce 806 807 An error is raised if the object is an NXroot group from an external file 808 that has been opened as readonly and no file name is specified. 809 810 The object is wrapped in an NXroot group (with name 'root') and an 811 NXentry group (with name 'entry'), if necessary, in order to produce 806 812 a valid NeXus file. 807 813 """ 808 814 if self.nxclass == "NXroot": 809 tree= self815 root = self 810 816 if filename is None: 811 817 if self._file: … … 817 823 elif filename: 818 824 if self.nxclass == "NXentry": 819 tree= NXroot(self)825 root = NXroot(self) 820 826 else: 821 tree= NXroot(NXentry(self))827 root = NXroot(NXentry(self)) 822 828 823 829 if filename is None: 824 830 raise NeXusError, "No output file specified" 825 831 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() 826 837 file = NeXusTree(filename, format) 827 file.writefile( tree)838 file.writefile(root) 828 839 file.close() 829 tree._file = file 830 tree._file.open() 831 tree._file.openpath('/') 832 tree._setattrs(tree._file.getattrs()) 833 tree._file.close() 834 return tree 840 841 return load(filename, 'rw') 835 842 836 843 def _getclass(self): 837 844 return self._class 838 845 839 846 def _getname(self): 840 847 return self._name 841 848 842 849 def _getgroup(self): 843 850 return self._group 844 851 845 852 def _getpath(self): 846 853 if self.nxgroup is None: … … 850 857 else: 851 858 return self.nxgroup._getpath()+"/"+self.nxname 852 859 853 860 def _getroot(self): 854 861 if self.nxgroup is None: … … 858 865 else: 859 866 return self.nxgroup._getroot() 860 867 861 868 def _getfile(self): 862 869 return self.nxroot._file 863 870 864 871 def _getfilename(self): 865 872 return self.nxroot._file.filename 866 873 867 874 def _getattrs(self): 868 875 return self._attrs … … 882 889 """ 883 890 A NeXus data field. 884 891 885 892 This is a subclass of NXobject that contains scalar, array, or string data 886 and associated NeXus attributes. 887 888 NXfield(value=None, name='unknown', dtype='', shape=[], attrs={}, file=None, 893 and associated NeXus attributes. 894 895 NXfield(value=None, name='unknown', dtype='', shape=[], attrs={}, file=None, 889 896 path=None, group=None, **attr) 890 897 … … 911 918 shape : list of ints 912 919 The dimensions of the NXfield data, which is accessible as the NXfield 913 attribute 'shape'. This corresponds to the shape of the Numpy array. 920 attribute 'shape'. This corresponds to the shape of the Numpy array. 914 921 Scalars (numeric or string) are stored as Numpy zero-rank arrays, 915 922 for which shape=[]. … … 920 927 The file from which the NXfield has been read. 921 928 path : string 922 The path to this object with respect to the root of the NeXus tree, 929 The path to this object with respect to the root of the NeXus tree, 923 930 using the convention for unix file paths. 924 931 group : NXgroup or subclass of NXgroup … … 931 938 The class of the NXobject. 932 939 nxname : string 933 The name of the NXfield. Since it is possible to reference the same 940 The name of the NXfield. Since it is possible to reference the same 934 941 Python object multiple times, this is not necessarily the same as the 935 942 object name. However, if the field is part of a NeXus tree, this will 936 be the attribute name within the tree. 943 be the attribute name within the tree. 937 944 nxgroup : NXgroup 938 The parent group containing this field within a NeXus tree. If the 945 The parent group containing this field within a NeXus tree. If the 939 946 field is not part of any NeXus tree, it will be set to None. 940 947 dtype : string or Numpy dtype 941 948 The data type of the NXfield value. If the NXfield has been initialized 942 949 but the data values have not been read in or defined, this is a string. 943 Otherwise, it is set to the equivalent Numpy dtype. 950 Otherwise, it is set to the equivalent Numpy dtype. 944 951 shape : list or tuple of ints 945 952 The dimensions of the NXfield data. If the NXfield has been initialized … … 949 956 for which shape=(). 950 957 attrs : dict 951 A dictionary of all the NeXus attributes associated with the field. 958 A dictionary of all the NeXus attributes associated with the field. 952 959 These are objects with class NXattr. 953 960 nxdata : scalar, Numpy array or string 954 The data value of the NXfield. This is normally initialized using the 955 'value' parameter (see above). If the NeXus data is contained 956 in a file and the size of the NXfield array is too large to be stored 961 The data value of the NXfield. This is normally initialized using the 962 'value' parameter (see above). If the NeXus data is contained 963 in a file and the size of the NXfield array is too large to be stored 957 964 in memory, the value is not read in until this attribute is directly 958 965 accessed. Even then, if there is insufficient memory, a value of None 959 will be returned. In this case, the NXfield array should be read as a 960 series of smaller slabs using 'get'. 966 will be returned. In this case, the NXfield array should be read as a 967 series of smaller slabs using 'get'. 961 968 nxdata_as('units') : scalar value or Numpy array 962 969 If the NXfield 'units' attribute has been set, the data values, stored … … 965 972 The path to this object with respect to the root of the NeXus tree. For 966 973 NeXus data read from a file, this will be a group of class NXroot, but 967 if the NeXus tree was defined interactively, it can be any valid 974 if the NeXus tree was defined interactively, it can be any valid 968 975 NXgroup. 969 976 nxroot : NXgroup 970 977 The root object of the NeXus tree containing this object. For 971 978 NeXus data read from a file, this will be a group of class NXroot, but 972 if the NeXus tree was defined interactively, it can be any valid 979 if the NeXus tree was defined interactively, it can be any valid 973 980 NXgroup. 974 981 … … 983 990 attributes always be referenced using the 'attrs' dictionary if there is 984 991 any doubt. 985 992 986 993 a) Assigning a NeXus attribute 987 994 988 995 In the example below, after assigning the NXfield, the following three 989 996 NeXus attribute assignments are all equivalent: … … 993 1000 >>> entry.sample.temperature.units = NXattr('K') 994 1001 >>> entry.sample.temperature.units = 'K' 995 1002 996 1003 b) Referencing a NeXus attribute 997 1004 998 1005 If the name of the NeXus attribute is not the same as any of the Python 999 attributes listed above, or one of the methods listed below, or any of the 1006 attributes listed above, or one of the methods listed below, or any of the 1000 1007 attributes defined for Numpy arrays, they can be referenced as if they were 1001 1008 a Python attribute of the NXfield. However, it is only possible to reference 1002 1009 attributes with one of the proscribed names using the 'attrs' dictionary. 1003 1010 1004 1011 >>> entry.sample.temperature.tree = 10.0 1005 1012 >>> entry.sample.temperature.tree … … 1019 1026 most Numpy operations work on NXfields, returning either another NXfield or, 1020 1027 in some cases, an ndarray that can easily be converted to an NXfield. 1021 1028 1022 1029 >>> x = NXfield((1.0,2.0,3.0,4.0)) 1023 1030 >>> print x+1 … … 1043 1050 1044 1051 All these operations return valid NXfield objects containing the same 1045 attributes as the first NXobject in the expression. The 'reshape' and 1052 attributes as the first NXobject in the expression. The 'reshape' and 1046 1053 'transpose' methods also return NXfield objects. 1047 1054 1048 1055 It is possible to use the standard slice syntax. 1049 1056 … … 1053 1060 >>> x[2:5] 1054 1061 NXfield([ 2. 3. 4.]) 1055 1062 1056 1063 In addition, it is possible to use floating point numbers as the slice 1057 1064 indices. If one of the indices is not integer, both indices are used to 1058 1065 extract elements in the array with values between the two index values. 1059 1066 1060 1067 >>> x=NXfield(np.linspace(0,100.,11)) 1061 1068 >>> x … … 1063 1070 >>> x[20.:50.] 1064 1071 NXfield([ 20. 30. 40. 50.]) 1065 1066 The standard Numpy ndarray attributes and methods will also work with 1072 1073 The standard Numpy ndarray attributes and methods will also work with 1067 1074 NXfields, but will return scalars or Numpy arrays. 1068 1075 1069 1076 >>> x.size 1070 1077 4 … … 1079 1086 >>> x.reshape((2,2)).sum(1) 1080 1087 array([ 3., 7.]) 1081 1088 1082 1089 Finally, NXfields are cast as ndarrays for operations that require them. 1083 The returned value will be the same as for the equivalent ndarray 1090 The returned value will be the same as for the equivalent ndarray 1084 1091 operation, e.g., 1085 1092 1086 1093 >>> np.sin(x) 1087 1094 array([ 0.84147098, 0.90929743, 0.14112001, -0.7568025 ]) 1088 1095 >>> np.sqrt(x) 1089 1096 array([ 1. , 1.41421356, 1.73205081, 2. ]) 1090 1097 1091 1098 Methods 1092 1099 ------- 1093 1100 dir(self, attrs=False): 1094 1101 Print the NXfield specification. 1095 1096 This outputs the name, dimensions and data type of the NXfield. 1102 1103 This outputs the name, dimensions and data type of the NXfield. 1097 1104 If 'attrs' is True, NXfield attributes are displayed. 1098 1105 1099 1106 tree: 1100 1107 Print the NXfield's tree. 1101 1102 It invokes the 'dir' method with both 'attrs' and 'recursive' 1108 1109 It invokes the 'dir' method with both 'attrs' and 'recursive' 1103 1110 set to True. Note that this method is defined as a property attribute and 1104 1111 does not require parentheses. 1105 1106 1112 1113 1107 1114 save(self, filename, format='w5') 1108 1115 Save the NXfield into a file wrapped in a NXroot group and NXentry group 1109 with default names. This is equivalent to 1110 1116 with default names. This is equivalent to 1117 1111 1118 >>> NXroot(NXentry(NXfield(...))).save(filename) 1112 1119 … … 1116 1123 >>> phi = x.nxdata_as(units='radian') 1117 1124 >>> y = NXfield(np.sin(phi)) 1118 1125 1119 1126 # Read a Ni x Nj x Nk array one vector at a time 1120 1127 >>> with root.NXentry[0].data.data as slab: … … 1127 1134 """ 1128 1135 1129 def __init__(self, value=None, name='unknown', dtype=None, shape=(), attrs={}, group=None, 1136 def __init__(self, value=None, name='unknown', dtype=None, shape=(), attrs={}, group=None, 1130 1137 **attr): 1131 1138 if isinstance(value, list) or isinstance(value, tuple): … … 1166 1173 else: 1167 1174 return "NXfield(dtype=%s,shape=%s)" % (self.dtype,self.shape) 1168 1175 1169 1176 def __getattr__(self, name): 1170 1177 """ … … 1193 1200 """ 1194 1201 Returns a slice from the NXfield. 1195 1202 1196 1203 In most cases, the slice values are applied to the NXfield nxdata array 1197 1204 and returned within an NXfield object with the same metadata. However, 1198 if the array is one-dimensional and the index start and stop values 1205 if the array is one-dimensional and the index start and stop values 1199 1206 are real, the nxdata array is returned with values between those limits. 1200 1207 This is to allow axis arrays to be limited by their actual value. This … … 1229 1236 result = self.nxdata.__getitem__(index) 1230 1237 return NXfield(result, name=self.nxname, attrs=self.attrs) 1231 1238 1232 1239 def __setitem__(self, index, value): 1233 1240 """ … … 1238 1245 else: 1239 1246 raise NeXusError, "NXfield dataspace not yet allocated" 1240 1247 1241 1248 def __deepcopy__(self, memo): 1242 1249 dpcpy = self.__class__() … … 1254 1261 Return the length of the NXfield data. 1255 1262 """ 1256 return np.prod(self.shape) 1257 1263 return np.prod(self.shape) 1264 1258 1265 def index(self, value, max=False): 1259 1266 """ 1260 1267 Return the index of the NXfield nxdata array that is greater than or equal to the value. 1261 1268 1262 1269 If max, then return the index that is less than or equal to the value. 1263 1270 This should only be used on one-dimensional monotonically increasing arrays. … … 1273 1280 """ 1274 1281 return self.nxdata 1275 1282 1276 1283 def __eq__(self, other): 1277 1284 """ … … 1304 1311 try: 1305 1312 if isinstance(other, NXfield): 1306 return NXfield(value=self.nxdata+other.nxdata, name=self.nxname, 1313 return NXfield(value=self.nxdata+other.nxdata, name=self.nxname, 1307 1314 attrs=self.attrs) 1308 1315 else: 1309 return NXfield(value=self.nxdata+other, name=self.nxname, 1316 return NXfield(value=self.nxdata+other, name=self.nxname, 1310 1317 attrs=self.attrs) 1311 1318 except TypeError, message: … … 1315 1322 """ 1316 1323 Return the sum of the NXfield and another NXfield or number. 1317 1324 1318 1325 This variant makes __add__ commutative. 1319 1326 """ … … 1326 1333 try: 1327 1334 if isinstance(other, NXfield): 1328 return NXfield(value=self.nxdata-other.nxdata, name=self.nxname, 1335 return NXfield(value=self.nxdata-other.nxdata, name=self.nxname, 1329 1336 attrs=self.attrs) 1330 1337 else: 1331 return NXfield(value=self.nxdata-other, name=self.nxname, 1338 return NXfield(value=self.nxdata-other, name=self.nxname, 1332 1339 attrs=self.attrs) 1333 1340 except TypeError, message: … … 1340 1347 try: 1341 1348 if isinstance(other, NXfield): 1342 return NXfield(value=self.nxdata*other.nxdata, name=self.nxname, 1349 return NXfield(value=self.nxdata*other.nxdata, name=self.nxname, 1343 1350 attrs=self.attrs) 1344 1351 else: 1345 return NXfield(value=self.nxdata*other, name=self.nxname, 1352 return NXfield(value=self.nxdata*other, name=self.nxname, 1346 1353 attrs=self.attrs) 1347 1354 except TypeError, message: … … 1351 1358 """ 1352 1359 Return the product of the NXfield and another NXfield or number. 1353 1360 1354 1361 This variant makes __mul__ commutative. 1355 1362 """ … … 1362 1369 try: 1363 1370 if isinstance(other, NXfield): 1364 return NXfield(value=self.nxdata/other.nxdata, name=self.nxname, 1371 return NXfield(value=self.nxdata/other.nxdata, name=self.nxname, 1365 1372 attrs=self.attrs) 1366 1373 else: 1367 return NXfield(value=self.nxdata/other, name=self.nxname, 1374 return NXfield(value=self.nxdata/other, name=self.nxname, 1368 1375 attrs=self.attrs) 1369 1376 except TypeError, message: … … 1376 1383 try: 1377 1384 if isinstance(other, NXfield): 1378 return NXfield(value=other.nxdata/self.nxdata, name=self.nxname, 1385 return NXfield(value=other.nxdata/self.nxdata, name=self.nxname, 1379 1386 attrs=self.attrs) 1380 1387 else: 1381 return NXfield(value=other/self.nxdata, name=self.nxname, 1388 return NXfield(value=other/self.nxdata, name=self.nxname, 1382 1389 attrs=self.attrs) 1383 1390 except TypeError, message: … … 1389 1396 """ 1390 1397 try: 1391 return NXfield(value=pow(self.nxdata,power), name=self.nxname, 1398 return NXfield(value=pow(self.nxdata,power), name=self.nxname, 1392 1399 attrs=self.attrs) 1393 1400 except TypeError, message: … … 1404 1411 def transpose(self,shape=None):#added shape variable here 9/8/2010 1405 1412 """ 1406 Returns an NXfield containing the transpose of the data array. Equivalent 1413 Returns an NXfield containing the transpose of the data array. Equivalent 1407 1414 to the Numpy ndarray.transpose. 1408 1415 """ 1409 1416 # error, no shape variable in this scope 1410 return NXfield(value=self.nxdata.transpose(shape), name=self.nxname, 1417 return NXfield(value=self.nxdata.transpose(shape), name=self.nxname, 1411 1418 attrs=self.attrs) 1412 1419 1413 1420 def centers(self): 1414 1421 """ 1415 Returns an NXfield with the centers of a single axis 1422 Returns an NXfield with the centers of a single axis 1416 1423 assuming it contains bin boundaries. 1417 1424 """ … … 1424 1431 1425 1432 Note: the results are undefined if you try accessing 1426 more than one slab at a time. Don't nest your 1433 more than one slab at a time. Don't nest your 1427 1434 "with data" statements! 1428 1435 """ … … 1450 1457 Offsets are 0-origin. Shape can be inferred from the data. 1451 1458 Offset and shape must each have one entry per dimension. 1452 1459 1453 1460 This operation should be performed in a "with group.data" 1454 1461 context. … … 1486 1493 self.__enter__() 1487 1494 if isinstance(data, NXfield): 1488 self.nxroot._file.putslab(data.nxdata.astype(self.dtype), offset, 1495 self.nxroot._file.putslab(data.nxdata.astype(self.dtype), offset, 1489 1496 data.shape) 1490 1497 else: 1491 1498 data = np.array(data) 1492 self.nxroot._file.putslab(data.astype(self.dtype), offset, 1499 self.nxroot._file.putslab(data.astype(self.dtype), offset, 1493 1500 data.shape) 1494 1501 self.__exit__() … … 1496 1503 else: 1497 1504 raise NeXusError, "No output file specified for NXputslab" 1498 1505 1499 1506 def add(self, data, offset): 1500 1507 """ … … 1506 1513 """ 1507 1514 if isinstance(data, NXfield): 1508 value = self.get(offset, data.shape) 1515 value = self.get(offset, data.shape) 1509 1516 self.put(data.nxdata.astype(self.dtype)+value, offset) 1510 1517 else: 1511 1518 value = self.get(offset, data.shape) 1512 1519 self.put(data.astype(self.dtype)+value, offset) 1513 1520 1514 1521 def refresh(self): 1515 1522 """ … … 1518 1525 Calls net to read in data again. If put has been called, then 1519 1526 nxdata is no longer synchronized with the file making a refresh 1520 necessary. This will only be performed if nxdata already stores the 1527 necessary. This will only be performed if nxdata already stores the 1521 1528 data. 1522 1529 """ … … 1526 1533 else: 1527 1534 raise NeXusError, "No file specified for reads" 1528 1535 1529 1536 def convert(self, units=""): 1530 1537 """ … … 1539 1546 else: 1540 1547 return None 1541 1548 1542 1549 def __str__(self): 1543 1550 """ … … 1565 1572 return "\n".join(v) 1566 1573 1574 def walk(self): 1575 yield self 1576 1567 1577 def _getaxes(self): 1568 1578 """ 1569 1579 Return a list of NXfields containing axes. 1570 1580 1571 1581 Only works if the NXfield has the 'axes' attribute 1572 1582 """ … … 1590 1600 else: 1591 1601 return None 1592 1602 1593 1603 return self._value 1594 1604 1595 1605 def _setdata(self, value): 1596 1606 if value is not None: … … 1609 1619 def _getdtype(self): 1610 1620 return self._dtype 1611 1621 1612 1622 def _getshape(self): 1613 1623 return self._shape 1614 1624 1615 1625 def _getsize(self): 1616 1626 return len(self) … … 1644 1654 """ 1645 1655 Plot the data entry. 1646 1656 1647 1657 Raises NeXusError if the data cannot be plotted. 1648 1658 """ … … 1657 1667 over = False 1658 1668 if not over: pylab.clf() 1659 1669 1660 1670 if "log" in opts.keys(): 1661 1671 logplot = True … … 1665 1675 1666 1676 # Provide a new view of the data if there is a dimension of length 1 1667 if 1 in signal.shape: 1677 if 1 in signal.shape: 1668 1678 data, axes = _fixaxes(signal, axes) 1669 1679 else: … … 1681 1691 data = np.log10(np.clip(data,0,1e8)) 1682 1692 if errors: ebars = np.log10(errors) 1683 elif errors: 1693 elif errors: 1684 1694 ebars = errors.nxdata 1685 1695 if errors: … … 1695 1705 pylab.ylabel(label(signal)) 1696 1706 pylab.title(title) 1697 1707 1698 1708 #Two dimensional plot 1699 1709 else: … … 1709 1719 gridplot = imshow_irregular 1710 1720 if logplot: 1711 gridplot(axis_data[0], axis_data[1], 1721 gridplot(axis_data[0], axis_data[1], 1712 1722 np.log10(np.clip(data,0.,1e8)+1).T, **opts) 1713 1723 else: … … 1720 1730 def show(): 1721 1731 import pylab 1722 pylab.show() 1732 pylab.show() 1723 1733 1724 1734 … … 1727 1737 """ 1728 1738 A NeXus group object. 1729 1739 1730 1740 This is a subclass of NXobject and is the base class for the specific 1731 NeXus group classes, e.g., NXentry, NXsample, NXdata. 1732 1741 NeXus group classes, e.g., NXentry, NXsample, NXdata. 1742 1733 1743 NXgroup(*items, **opts) 1734 1744 1735 1745 Parameters 1736 1746 ---------- 1737 The NXgroup parameters consist of a list of positional and/or keyword 1747 The NXgroup parameters consist of a list of positional and/or keyword 1738 1748 arguments. 1739 1740 Positional Arguments : These must be valid NeXus objects, either an NXfield 1741 or a NeXus group. These are added without modification as children of this 1742 group. 1743 1744 Keyword Arguments : Apart from a list of special keywords shown below, 1749 1750 Positional Arguments : These must be valid NeXus objects, either an NXfield 1751 or a NeXus group. These are added without modification as children of this 1752 group. 1753 1754 Keyword Arguments : Apart from a list of special keywords shown below, 1745 1755 keyword arguments are used to add children to the group using the keywords 1746 as attribute names. The values can either be valid NXfields or NXgroups, 1747 in which case the 'name' attribute is changed to the keyword, or they 1756 as attribute names. The values can either be valid NXfields or NXgroups, 1757 in which case the 'name' attribute is changed to the keyword, or they 1748 1758 can be numerical or string data, which are converted to NXfield objects. 1749 1759 1750 1760 Special Keyword Arguments: 1751 1761 1752 1762 name : string 1753 The name of the NXgroup, which is directly accessible as the NXgroup 1754 attribute 'name'. If the NXgroup is initialized as the attribute of 1755 a parent group, the name is automatically set to the name of this 1763 The name of the NXgroup, which is directly accessible as the NXgroup 1764 attribute 'name'. If the NXgroup is initialized as the attribute of 1765 a parent group, the name is automatically set to the name of this 1756 1766 attribute. If 'nxclass' is specified and has the usual prefix 'NX', 1757 1767 the default name is the class name without this prefix. 1758 1768 nxclass : string 1759 The class of the NXgroup. 1769 The class of the NXgroup. 1760 1770 entries : dict 1761 A dictionary containing a list of group entries. This is an 1762 alternative way of adding group entries to the use of keyword 1771 A dictionary containing a list of group entries. This is an 1772 alternative way of adding group entries to the use of keyword 1763 1773 arguments. 1764 1774 file : filename 1765 1775 The file from which the NXfield has been read. 1766 1776 path : string 1767 The path to this object with respect to the root of the NeXus tree, 1777 The path to this object with respect to the root of the NeXus tree, 1768 1778 using the convention for unix file paths. 1769 1779 group : NXobject (NXgroup or subclass of NXgroup) 1770 The parent NeXus group, which is accessible as the group attribute 1771 'group'. If the group is initialized as the attribute of 1780 The parent NeXus group, which is accessible as the group attribute 1781 'group'. If the group is initialized as the attribute of 1772 1782 a parent group, this is set to the parent group. 1773 1783 … … 1777 1787 The class of the NXobject. 1778 1788 nxname : string 1779 The name of the NXfield. 1789 The name of the NXfield. 1780 1790 entries : dictionary 1781 1791 A dictionary of all the NeXus objects contained within an NXgroup. … … 1790 1800 The path to this object with respect to the root of the NeXus tree. For 1791 1801 NeXus data read from a file, this will be a group of class NXroot, but 1792 if the NeXus tree was defined interactively, it can be any valid 1802 if the NeXus tree was defined interactively, it can be any valid 1793 1803 NXgroup. 1794 1804 nxroot : NXgroup 1795 1805 The root object of the NeXus tree containing this object. For 1796 1806 NeXus data read from a file, this will be a group of class NXroot, but 1797 if the NeXus tree was defined interactively, it can be any valid 1807 if the NeXus tree was defined interactively, it can be any valid 1798 1808 NXgroup. 1799 1809 … … 1807 1817 dictionary name directly as the group attribute name, as long as this name 1808 1818 is not the same as one of the Python attributes defined above or as one of 1809 the NXfield Python attributes. 1810 1819 the NXfield Python attributes. 1820 1811 1821 a) Assigning a NeXus object to a NeXus group 1812 1822 1813 1823 In the example below, after assigning the NXgroup, the following three 1814 1824 NeXus object assignments to entry.sample are all equivalent: … … 1820 1830 >>> entry.sample.temperature 1821 1831 NXfield(40.0) 1822 1823 If the assigned value is not a valid NXobject, then it is cast as an NXfield 1832 1833 If the assigned value is not a valid NXobject, then it is cast as an NXfield 1824 1834 with a type determined from the Python data type. 1825 1835 1826 1836 >>> entry.sample.temperature = 40.0 1827 1837 >>> entry.sample.temperature … … 1830 1840 >>> entry.data.data.x 1831 1841 NXfield([ 0. 1. 2. ..., 8. 9. 10.]) 1832 1842 1833 1843 b) Referencing a NeXus object in a NeXus group 1834 1844 1835 1845 If the name of the NeXus object is not the same as any of the Python 1836 1846 attributes listed above, or the methods listed below, they can be referenced 1837 as if they were a Python attribute of the NXgroup. However, it is only possible 1838 to reference attributes with one of the proscribed names using the group 1847 as if they were a Python attribute of the NXgroup. However, it is only possible 1848 to reference attributes with one of the proscribed names using the group 1839 1849 dictionary, i.e., 1840 1850 … … 1845 1855 >>> entry.sample['tree'] 1846 1856 NXfield(100.0) 1847 1857 1848 1858 For this reason, it is recommended to use the group dictionary to reference 1849 1859 all group objects within Python scripts. … … 1871 1881 insert(self, NXobject, name='unknown'): 1872 1882 Insert a valid NXobject (NXfield or NXgroup) into the group. 1873 1883 1874 1884 If NXobject has a 'name' attribute and the 'name' keyword is not given, 1875 1885 then the object is inserted with the NXobject name. 1876 1886 1877 1887 makelink(self, NXobject): 1878 1888 Add the NXobject to the group entries as a link (NXlink). … … 1880 1890 dir(self, attrs=False, recursive=False): 1881 1891 Print the group directory. 1882 1892 1883 1893 The directory is a list of NeXus objects within this group, either NeXus 1884 1894 groups or NXfield data. If 'attrs' is True, NXfield attributes are … … 1888 1898 tree: 1889 1899 Print the group tree. 1890 1891 It invokes the 'dir' method with both 'attrs' and 'recursive' 1900 1901 It invokes the 'dir' method with both 'attrs' and 'recursive' 1892 1902 set to True. Note that this method is defined as a property attribute and 1893 1903 does not require parentheses. 1894 1904 1895 1905 save(self, filename, format='w5') 1896 1906 Save the NeXus group into a file 1897 1907 1898 The object is wrapped in an NXroot group (with name 'root') and an 1899 NXentry group (with name 'entry'), if necessary, in order to produce 1908 The object is wrapped in an NXroot group (with name 'root') and an 1909 NXentry group (with name 'entry'), if necessary, in order to produce 1900 1910 a valid NeXus file. 1901 1911 … … 1912 1922 1913 1923 Note: All the currently defined NeXus classes are defined as subclasses 1914 of the NXgroup class. It is recommended that these are used 1924 of the NXgroup class. It is recommended that these are used 1915 1925 directly, so that the above examples become: 1916 1926 1917 1927 >>> entry = NXentry(x) 1918 1928 >>> entry.sample = NXsample(temperature=NXfield(40.0,units='K')) 1919 1929 1920 1930 or 1921 1931 1922 1932 >>> entry.sample.temperature = 40.0 1923 1933 >>> entry.sample.temperature.units='K' 1924 1934 1925 1935 """ 1926 1936 … … 1951 1961 self.__class__ = globals()[self.nxclass] 1952 1962 except KeyError: 1953 pass 1963 pass 1954 1964 for item in items: 1955 1965 try: … … 1967 1977 def __repr__(self): 1968 1978 return "%s('%s')" % (self.__class__.__name__,self.nxname) 1969 1979 1970 1980 def _str_value(self,indent=0): 1971 1981 return "" 1982 1983 def walk(self): 1984 yield self 1985 for node in self.entries.values(): 1986 for child in node.walk(): 1987 yield child 1972 1988 1973 1989 def __getattr__(self, key): … … 1986 2002 """ 1987 2003 Set an attribute as an object or regular Python attribute. 1988 1989 It is assumed that attributes starting with 'nx' or '_' are regular 2004 2005 It is assumed that attributes starting with 'nx' or '_' are regular 1990 2006 Python attributes. All other attributes are converted to valid NXobjects, 1991 2007 with class NXfield, NXgroup, or a sub-class of NXgroup, depending on the 1992 2008 assigned value. 1993 1994 The internal value of the attribute name, i.e., 'name', is set to the 1995 attribute name used in the assignment. The parent group of the 2009 2010 The internal value of the attribute name, i.e., 'name', is set to the 2011 attribute name used in the assignment. The parent group of the 1996 2012 attribute, i.e., 'group', is set to the parent group of the attribute. 1997 2013 1998 2014 If the assigned value is a numerical (scalar or array) or string object, 1999 it is converted to an object of class NXfield, whose attribute, 'nxdata', 2015 it is converted to an object of class NXfield, whose attribute, 'nxdata', 2000 2016 is set to the assigned value. 2001 2017 """ … … 2005 2021 self._attrs[name] = value 2006 2022 else: 2007 self[name] = value 2023 self[name] = value 2008 2024 2009 2025 def __getitem__(self, index): 2010 2026 """ 2011 2027 Returns a slice from the NXgroup nxsignal attribute (if it exists) as 2012 a new NXdata group, if the index is a slice object. 2013 2028 a new NXdata group, if the index is a slice object. 2029 2014 2030 In most cases, the slice values are applied to the NXfield nxdata array 2015 2031 and returned within an NXfield object with the same metadata. However, 2016 if the array is one-dimensional and the index start and stop values 2032 if the array is one-dimensional and the index start and stop values 2017 2033 are real, the nxdata array is returned with values between the limits 2018 2034 set by those axis values. … … 2024 2040 return self._entries[index] 2025 2041 2026 if not self.nxsignal: 2042 if not self.nxsignal: 2027 2043 raise NeXusError, "No plottable signal" 2028 2044 if not hasattr(self,"nxclass"): … … 2037 2053 axes[0] = axes[0][index] 2038 2054 if isinstance(index.start, float) or isinstance(index.stop, float): 2039 index = slice(self.nxaxes[0].index(index.start), 2055 index = slice(self.nxaxes[0].index(index.start), 2040 2056 self.nxaxes[0].index(index.stop,max=True)+1) 2041 2057 result = NXdata(self.nxsignal[index], axes) … … 2074 2090 self._entries[key] = value 2075 2091 elif isinstance(value, NXobject): 2076 if value.nxgroup is not None: 2092 if value.nxgroup is not None: 2077 2093 memo = {} 2078 2094 value = deepcopy(value, memo) … … 2082 2098 self._entries[key] = value 2083 2099 else: 2084 self._entries[key] = NXfield(value=value, name=key, group=self) 2100 self._entries[key] = NXfield(value=value, name=key, group=self) 2085 2101 2086 2102 def __deepcopy__(self, memo): … … 2091 2107 dpcpy[k] = deepcopy(v, memo) 2092 2108 else: 2093 dpcpy[k] = copy(v) 2109 dpcpy[k] = copy(v) 2094 2110 for k, v in self.attrs.items(): 2095 2111 dpcpy.attrs[k] = copy(v) … … 2107 2123 """ 2108 2124 return self._entries.values() 2109 2125 2110 2126 def items(self): 2111 2127 """ … … 2113 2129 """ 2114 2130 return self._entries.items() 2115 2131 2116 2132 def has_key(self, name): 2117 2133 """ … … 2123 2139 """ 2124 2140 Adds an attribute to the group. 2125 2126 If it is not a valid NeXus object (NXfield or NXgroup), the attribute 2127 is converted to an NXfield. 2141 2142 If it is not a valid NeXus object (NXfield or NXgroup), the attribute 2143 is converted to an NXfield. 2128 2144 """ 2129 2145 if isinstance(value, NXobject): … … 2139 2155 """ 2140 2156 Creates a linked NXobject within the group. 2141 2157 2142 2158 All attributes are inherited from the parent object including the name 2143 2159 """ … … 2147 2163 raise NeXusError, "Link target must be an NXobject" 2148 2164 2149 2165 2150 2166 def sum(self, axis=None): 2151 2167 """ … … 2154 2170 2155 2171 The result contains a copy of all the metadata contained in 2156 the NXdata group. 2157 """ 2158 if not self.nxsignal: 2172 the NXdata group. 2173 """ 2174 if not self.nxsignal: 2159 2175 raise NeXusError, "No signal to sum" 2160 2176 if not hasattr(self,"nxclass"): … … 2178 2194 if self.nxtitle: 2179 2195 result.title = self.nxtitle 2180 return result 2196 return result 2181 2197 2182 2198 def moment(self, order=1): 2183 2199 """ 2184 Return an NXfield containing the moments of the NXdata group 2200 Return an NXfield containing the moments of the NXdata group 2185 2201 assuming the signal is one-dimensional. 2186 2187 Currently, only the first moment has been defined. Eventually, the 2202 2203 Currently, only the first moment has been defined. Eventually, the 2188 2204 order of the moment will be defined by the 'order' parameter. 2189 2205 """ 2190 if not self.nxsignal: 2206 if not self.nxsignal: 2191 2207 raise NeXusError, "No signal to calculate" 2192 2208 elif len(self.nxsignal.shape) > 1: … … 2208 2224 """ 2209 2225 Return a dictionary of NXfield's containing signal data. 2210 2226 2211 2227 The key is the value of the signal attribute. 2212 2228 """ … … 2215 2231 if 'signal' in obj.attrs: 2216 2232 signals[obj.nxsignal.nxdata] = obj 2217 return signals 2233 return signals 2218 2234 2219 2235 def _signal(self): … … 2254 2270 """ 2255 2271 Return the title as a string. 2256 2257 If there is no title attribute in the string, the parent 2272 2273 If there is no title attribute in the string, the parent 2258 2274 NXentry group in the group's path is searched. 2259 2275 """ … … 2269 2285 pass 2270 2286 obj = obj.nxgroup 2271 return self.nxpath 2287 return self.nxpath 2272 2288 2273 2289 def _getentries(self): … … 2278 2294 nxerrors = property(_errors, "Errors NXfield within group") 2279 2295 nxtitle = property(_title, "Title for group plot") 2280 entries = property(_getentries,doc="NeXus objects within group") 2281 2282 2296 entries = property(_getentries,doc="NeXus objects within group") 2297 2298 2283 2299 def plot(self, **opts): 2284 2300 """ 2285 2301 Plot data contained within the group. 2286 2302 2287 2303 Raises NeXusError if the data could not be plotted. 2288 2304 """ 2289 2305 2290 2306 group = self 2291 2307 if self.nxclass == "NXroot": … … 2296 2312 except IndexError: 2297 2313 raise NeXusError('No NXdata group found') 2298 2314 2299 2315 # Find a plottable signal 2300 2316 signal = group.nxsignal … … 2304 2320 # Find errors 2305 2321 errors= group.nxerrors 2306 2322 2307 2323 # Find the associated axes 2308 2324 axes = group.nxaxes 2309 2325 2310 2326 # Construct title 2311 2327 title = group.nxtitle 2312 2328 2313 2329 # Plot with the available plotter 2314 2330 group._plotter.plot(signal, axes, title, errors, **opts) … … 2319 2335 """ 2320 2336 Class for NeXus linked objects. 2321 2337 2322 2338 The real object will be accessible by following the link attribute. 2323 2339 """ … … 2380 2396 nxlink = property(_getlink, "Linked object") 2381 2397 attrs = property(_getattrs,doc="NeXus attributes for object") 2382 entries = property(_getentries,doc="NeXus objects within group") 2398 entries = property(_getentries,doc="NeXus objects within group") 2383 2399 2384 2400 … … 2387 2403 """ 2388 2404 Class for a NeXus linked field. 2389 2405 2390 2406 The real field will be accessible by following the link attribute. 2391 2407 """ … … 2405 2421 Offsets are 0-origin. Shape can be inferred from the data. 2406 2422 Offset and shape must each have one entry per dimension. 2407 2423 2408 2424 This operation should be performed in a "with group.data" 2409 2425 conext. … … 2419 2435 else: 2420 2436 raise NeXusError, "No input file specified for NXgetslab" 2421 2437 2422 2438 NXlinkdata = NXlinkfield # For backward compatibility 2423 2439 … … 2426 2442 """ 2427 2443 Class for a NeXus linked group. 2428 2444 2429 2445 The real group will be accessible by following the link attribute. 2430 2446 """ … … 2449 2465 2450 2466 Each NXdata and NXmonitor object of the same name will be added 2451 together, raising an NeXusError if any of the groups do not exist 2452 in both NXentry groups or if any of the NXdata additions fail. 2453 The resulting NXentry group contains a copy of all the other metadata 2454 contained in the first group. Note that other extensible data, such 2455 as the run duration, are not currently added together. 2467 together, raising an NeXusError if any of the groups do not exist 2468 in both NXentry groups or if any of the NXdata additions fail. 2469 The resulting NXentry group contains a copy of all the other metadata 2470 contained in the first group. Note that other extensible data, such 2471 as the run duration, are not currently added together. 2456 2472 2457 2473 See the NXgroup documentation for more details. … … 2464 2480 def __add__(self, other): 2465 2481 """ 2466 Add two NXentry objects 2482 Add two NXentry objects 2467 2483 """ 2468 2484 result = NXentry(entries=self.entries, attrs=self.attrs) … … 2524 2540 """ 2525 2541 NXdata group. This is a subclass of the NXgroup class. 2526 2542 2527 2543 The constructor assumes that the first argument contains the signal and 2528 2544 the second contains either the axis, for one-dimensional data, or a list 2529 of axes, for multidimensional data. These arguments can either be NXfield 2530 objects or Numpy arrays, which are converted to NXfield objects with default 2545 of axes, for multidimensional data. These arguments can either be NXfield 2546 objects or Numpy arrays, which are converted to NXfield objects with default 2531 2547 names. 2532 2533 Various arithmetic operations (addition, subtraction, multiplication, 2548 2549 Various arithmetic operations (addition, subtraction, multiplication, 2534 2550 and division) have been defined for combining NXdata groups with other 2535 NXdata groups, Numpy arrays, or constants, raising a NeXusError if the 2536 shapes don't match. Data errors are propagated in quadrature if 2537 they are defined, i.e., if the 'nexerrors' attribute is not None, 2551 NXdata groups, Numpy arrays, or constants, raising a NeXusError if the 2552 shapes don't match. Data errors are propagated in quadrature if 2553 they are defined, i.e., if the 'nexerrors' attribute is not None, 2538 2554 2539 2555 Attributes … … 2547 2563 plot(self, over=False, log=False, **opts) 2548 2564 Plot the NXdata group using the defined signal and axes. Valid 2549 Matplotlib parameters, specifying markers, colors, etc, can be 2550 specified using the 'opts' dictionary. 2551 2565 Matplotlib parameters, specifying markers, colors, etc, can be 2566 specified using the 'opts' dictionary. 2567 2552 2568 moment(self, order=1) 2553 Calculate moments of the NXdata group. This assumes that the 2554 signal is one-dimenional. Currently, only the first moment is 2569 Calculate moments of the NXdata group. This assumes that the 2570 signal is one-dimenional. Currently, only the first moment is 2555 2571 implemented. 2556 2572 … … 2575 2591 intensity = float64(101x101) 2576 2592 @axes = axis1:axis2 2577 @signal = 1 2593 @signal = 1 2578 2594 2579 2595 See the NXgroup documentation for more details. … … 2608 2624 self[axisname] = axis 2609 2625 axisnames[i] = axisname 2610 self[signalname].axes = ":".join(axisnames.values()) 2626 self[signalname].axes = ":".join(axisnames.values()) 2611 2627 2612 2628 def __add__(self, other): … … 2616 2632 2617 2633 The result contains a copy of all the metadata contained in 2618 the first NXdata group. The module checks that the dimensions are 2634 the first NXdata group. The module checks that the dimensions are 2619 2635 compatible, but does not check that the NXfield names or values are 2620 2636 identical. This is so that spelling variations or rounding errors 2621 do not make the operation fail. However, it is up to the user to 2637 do not make the operation fail. However, it is up to the user to 2622 2638 ensure that the results make sense. 2623 2639 """ … … 2638 2654 result.entries[self.nxsignal.nxname].nxname = self.nxsignal.nxname 2639 2655 return result 2640 2656 2641 2657 def __sub__(self, other): 2642 2658 """ 2643 Define a method for subtracting a NXdata group or a number from 2659 Define a method for subtracting a NXdata group or a number from 2644 2660 the NXdata group. Only the signal data is affected. 2645 2661 2646 2662 The result contains a copy of all the metadata contained in 2647 the first NXdata group. The module checks that the dimensions are 2663 the first NXdata group. The module checks that the dimensions are 2648 2664 compatible, but does not check that the NXfield names or values are 2649 2665 identical. This is so that spelling variations or rounding errors 2650 do not make the operation fail. However, it is up to the user to 2666 do not make the operation fail. However, it is up to the user to 2651 2667 ensure that the results make sense. 2652 2668 """ … … 2667 2683 result.entries[self.nxsignal.nxname].nxname = self.nxsignal.nxname 2668 2684 return result 2669 2685 2670 2686 def __mul__(self, other): 2671 2687 """ … … 2674 2690 2675 2691 The result contains a copy of all the metadata contained in 2676 the first NXdata group. The module checks that the dimensions are 2692 the first NXdata group. The module checks that the dimensions are 2677 2693 compatible, but does not check that the NXfield names or values are 2678 2694 identical. This is so that spelling variations or rounding errors 2679 do not make the operation fail. However, it is up to the user to 2695 do not make the operation fail. However, it is up to the user to 2680 2696 ensure that the results make sense. 2681 2697 """ … … 2710 2726 """ 2711 2727 return self.__mul__(other) 2712 2728 2713 2729 def __div__(self, other): 2714 2730 """ … … 2717 2733 2718 2734 The result contains a copy of all the metadata contained in 2719 the first NXdata group. The module checks that the dimensions are 2735 the first NXdata group. The module checks that the dimensions are 2720 2736 compatible, but does not check that the NXfield names or values are 2721 2737 identical. This is so that spelling variations or rounding errors 2722 do not make the operation fail. However, it is up to the user to 2738 do not make the operation fail. However, it is up to the user to 2723 2739 ensure that the results make sense. 2724 2740 """ … … 2732 2748 if self.nxerrors: 2733 2749 if other.nxerrors: 2734 result.errors = (np.sqrt(self.errors.nxdata**2 + 2750 result.errors = (np.sqrt(self.errors.nxdata**2 + 2735 2751 (resultvalues*other.errors.nxdata)**2) 2736 / other.nxsignal) 2752 / other.nxsignal) 2737 2753 else: 2738 2754 result.errors = self.errors … … 2751 2767 """ 2752 2768 NXmonitor group. This is a subclass of the NXdata class. 2753 2769 2754 2770 See the NXdata and NXgroup documentation for more details. 2755 2771 """ … … 2766 2782 """ 2767 2783 NXlog group. This is a subclass of the NXgroup class. 2768 2784 2769 2785 Methods 2770 2786 ------- 2771 2787 plot(self, **opts) 2772 2788 Plot the logged values against the elapsed time. Valid 2773 Matplotlib parameters, specifying markers, colors, etc, can be 2789 Matplotlib parameters, specifying markers, colors, etc, can be 2774 2790 specified using the 'opts' dictionary. 2775 2791 2776 2792 See the NXgroup documentation for more details. 2777 2793 """ … … 2780 2796 self._class = "NXlog" 2781 2797 NXgroup.__init__(self, *items, **opts) 2782 2798 2783 2799 def plot(self, **opts): 2784 2800 axis = [self.time] … … 2794 2810 docstring = """ 2795 2811 %s group. This is a subclass of the NXgroup class. 2796 2812 2797 2813 See the NXgroup documentation for more details. 2798 2814 """ % _class … … 2807 2823 """ 2808 2824 Return the centers of the axes. 2809 2825 2810 2826 This works regardless if the axes contain bin boundaries or centers. 2811 2827 """ … … 2852 2868 """ 2853 2869 Read a NeXus file returning a tree of objects. 2854 2870 2855 2871 This is aliased to 'read' because of potential name clashes with Numpy 2856 2872 """ … … 2887 2903 def demo(argv): 2888 2904 """ 2889 Process a list of command line commands. 2890 2905 Process a list of command line commands. 2906 2891 2907 'argv' should contain program name, command, arguments, where command is one 2892 2908 of the following: … … 2909 2925 tree.plot() 2910 2926 tree._plotter.show() 2911 2927 2912 2928 else: 2913 2929 usage = """ … … 2918 2934 """%(argv[0],) 2919 2935 print usage 2920 2936 2921 2937 2922 2938 if __name__ == "__main__":
Note: See TracChangeset
for help on using the changeset viewer.
