def save_scan(self, nxentry, scan): '''*internal*: save the data from each SPEC scan to its own NXentry group''' scan.interpret() # ensure interpretation is complete eznx.addAttributes(nxentry, default="data") eznx.write_dataset(nxentry, "title", str(scan)) eznx.write_dataset(nxentry, "scan_number", scan.scanNum) eznx.write_dataset(nxentry, "command", scan.scanCmd) for func in scan.header.h5writers.values(): # ask the header plugins to save their part func(nxentry, self, scan.header, nxclass=CONTAINER_CLASS) for func in scan.h5writers.values(): # ask the scan plugins to save their part func(nxentry, self, scan, nxclass=CONTAINER_CLASS)
def save_data(self, nxdata, scan): '''*internal*: store the scan data''' scan_type = scan.scanCmd.split()[0] signal, axes = '', [ '', ] if scan_type in ('mesh', 'hklmesh'): # hklmesh H 1.9 2.1 100 K 1.9 2.1 100 -800000 signal, axes = self.mesh(nxdata, scan) elif scan_type in ('hscan', 'kscan', 'lscan', 'hklscan'): # hklscan 1.00133 1.00133 1.00133 1.00133 2.85 3.05 200 -400000 h_0, h_N, k_0, k_N, l_0, l_N = scan.scanCmd.split()[1:7] if h_0 != h_N: axes = [ 'H', ] elif k_0 != k_N: axes = [ 'K', ] elif l_0 != l_N: axes = [ 'L', ] signal, axes = self.oneD(nxdata, scan) else: signal, axes = self.oneD(nxdata, scan) # these locations suggested to NIAC, easier to parse than attached to dataset! if len(signal) == 0: pass # Syntax of axes attribute (http://wiki.nexusformat.org/2014_axes_and_uncertainties): # @axes="H:K" INCOREECT # @axes="H", "K" CORRECT if axes.find(':') >= 0: axes = axes.split(':') eznx.addAttributes(nxdata, signal=signal, axes=axes) #eznx.addAttributes(nxdata[signal], signal=1, axes=axes) # deprecated now # assume here that "axis_name" has rank=1 # TODO: test that scan.data[axis_name] has rank=1 indices = [ 0, ] # 0-based reference if isinstance(axes, str): eznx.addAttributes(nxdata, **{axes + '_indices': indices}) else: for axis_name in axes: eznx.addAttributes(nxdata, **{axis_name + '_indices': indices})
def save_data(self, nxdata, scan): '''*internal*: store the scan data''' scan_type = scan.scanCmd.split()[0] signal, axes = '', ['',] if scan_type in ('mesh', 'hklmesh'): # hklmesh H 1.9 2.1 100 K 1.9 2.1 100 -800000 signal, axes = self.mesh(nxdata, scan) elif scan_type in ('hscan', 'kscan', 'lscan', 'hklscan'): # hklscan 1.00133 1.00133 1.00133 1.00133 2.85 3.05 200 -400000 h_0, h_N, k_0, k_N, l_0, l_N = scan.scanCmd.split()[1:7] if h_0 != h_N: axes = ['H',] elif k_0 != k_N: axes = ['K',] elif l_0 != l_N: axes = ['L',] signal, axes = self.oneD(nxdata, scan) else: signal, axes = self.oneD(nxdata, scan) # these locations suggested to NIAC, easier to parse than attached to dataset! if len(signal) == 0: pass # Syntax of axes attribute (http://wiki.nexusformat.org/2014_axes_and_uncertainties): # @axes="H:K" INCOREECT # @axes="H", "K" CORRECT if axes.find(':') >= 0: axes = axes.split(':') eznx.addAttributes(nxdata, signal=signal, axes=axes) #eznx.addAttributes(nxdata[signal], signal=1, axes=axes) # deprecated now # assume here that "axis_name" has rank=1 # TODO: test that scan.data[axis_name] has rank=1 indices = [0,] # 0-based reference if isinstance(axes, str): eznx.addAttributes(nxdata, **{axes+'_indices': indices}) else: for axis_name in axes: eznx.addAttributes(nxdata, **{axis_name+'_indices': indices})
def save(self, hdf_file, scan_list=[]): ''' save the information in this SPEC data file to a NeXus HDF5 file Each scan in scan_list will be converted to a **NXentry** group. Scan data will be placed in a **NXdata** group where the attribute **signal=1** is the last column and the corresponding attribute **axes=<name of the first column>**. There are variations on this for 2-D and higher dimensionality data, such as mesh scans. In general, the tree structure of the NeXus HDF5 file is:: hdf5_file: NXroot @default="S1" definition="NXspecdata" # attributes S1:NXentry @default="data" # attributes and metadata fields data:NXdata @signal=<name of signal field> @axes=<name(s) of axes of signal> @<axis>_indices=<list of indices in "axis1"> <signal_is_the_last_column>:NX_NUMBER[number of points] = ... data ... @signal=1 @axes='<axis_is_name_of_first_column>' @<axis>_indices=<list of indices in "axis1" used as dimension scales of the "signal"> <axis_is_name_of_first_column>:NX_NUMBER[number of points] = ... data ... # other columns from the scan :param str hdf_file: name of NeXus/HDF5 file to be written :param [int] scanlist: list of scan numbers to be read ''' root = eznx.makeFile(hdf_file, **self.root_attributes()) pick_first_entry = True for key in scan_list: nxentry = eznx.makeGroup(root, 'S'+str(key), 'NXentry') eznx.makeDataset(nxentry, 'definition', 'NXspecdata', description='NeXus application definition (status pending)') self.save_scan(nxentry, self.spec.getScan(key)) if pick_first_entry: pick_first_entry = False eznx.addAttributes(root, default='S'+str(key)) if 'data' not in nxentry: # NXentry MUST have a NXdata group with data for default plot nxdata = eznx.makeGroup(nxentry, 'data', 'NXdata', signal='no_y_data', axes='no_x_data', no_x_data_indices=[0,], ) eznx.makeDataset(nxdata, "no_x_data", (0, 1), units='none', long_name='no data points in this scan') eznx.makeDataset(nxdata, "no_y_data", (0, 1), units='none', long_name='no data points in this scan') root.close() # be CERTAIN to close the file
def save(self, hdf_file, scan_list=[]): ''' save the information in this SPEC data file to a NeXus HDF5 file Each scan in scan_list will be converted to a **NXentry** group. Scan data will be placed in a **NXdata** group where the attribute **signal=1** is the last column and the corresponding attribute **axes=<name of the first column>**. There are variations on this for 2-D and higher dimensionality data, such as mesh scans. In general, the tree structure of the NeXus HDF5 file is:: hdf5_file: NXroot @default="S1" definition="NXspecdata" # attributes S1:NXentry @default="data" # attributes and metadata fields data:NXdata @signal=<name of signal field> @axes=<name(s) of axes of signal> @<axis>_indices=<list of indices in "axis1"> <signal_is_the_last_column>:NX_NUMBER[number of points] = ... data ... @signal=1 @axes='<axis_is_name_of_first_column>' @<axis>_indices=<list of indices in "axis1" used as dimension scales of the "signal"> <axis_is_name_of_first_column>:NX_NUMBER[number of points] = ... data ... # other columns from the scan :param str hdf_file: name of NeXus/HDF5 file to be written :param [int] scanlist: list of scan numbers to be read ''' root = eznx.makeFile(hdf_file, **self.root_attributes()) pick_first_entry = True for key in scan_list: nxentry = eznx.makeGroup(root, 'S' + str(key), 'NXentry') eznx.makeDataset( nxentry, 'definition', 'NXspecdata', description='NeXus application definition (status pending)') self.save_scan(nxentry, self.spec.getScan(key)) if pick_first_entry: pick_first_entry = False eznx.addAttributes(root, default='S' + str(key)) if 'data' not in nxentry: # NXentry MUST have a NXdata group with data for default plot nxdata = eznx.makeGroup( nxentry, 'data', 'NXdata', signal='no_y_data', axes='no_x_data', no_x_data_indices=[ 0, ], ) eznx.makeDataset(nxdata, "no_x_data", (0, 1), units='none', long_name='no data points in this scan') eznx.makeDataset(nxdata, "no_y_data", (0, 1), units='none', long_name='no data points in this scan') root.close() # be CERTAIN to close the file