def parser_mca_spectra(self, nxdata, scan, primary_axis_label): '''parse for optional MCA spectra''' if '_mca_' in scan.data: # check for it for mca_key, mca_data in scan.data['_mca_'].items(): key = "__" + mca_key nxdata[key] = NXfield(mca_data) nxdata[key].units = "counts" ch_key = key + "_channel" nxdata[ch_key] = NXfield(range(1, len(mca_data[0]) + 1)) nxdata[ch_key].units = 'channel' axes = (primary_axis_label, ch_key) nxdata[key].axes = ':'.join(axes)
def parser_mca_spectra(self, nxdata, scan, primary_axis_label): '''parse for optional MCA spectra''' if '_mca_' in scan.data: # check for it for mca_key, mca_data in scan.data['_mca_'].items(): key = "__" + mca_key nxdata[key] = NXfield(mca_data) nxdata[key].units = "counts" ch_key = key + "_channel" nxdata[ch_key] = NXfield(range(1, len(mca_data[0])+1)) nxdata[ch_key].units = 'channel' axes = (primary_axis_label, ch_key) nxdata[key].axes = ':'.join( axes )
def parser_mesh(self, nxdata, scan): '''data parser for 2-D mesh and hklmesh''' # 2-D parser: http://www.certif.com/spec_help/mesh.html # mesh motor1 start1 end1 intervals1 motor2 start2 end2 intervals2 time # 2-D parser: http://www.certif.com/spec_help/hklmesh.html # hklmesh Q1 start1 end1 intervals1 Q2 start2 end2 intervals2 time # mesh: nexpy/examples/33id_spec.dat scan 22 (also has MCA, thus 3-D data) # hklmesh: nexpy/examples/33bm_spec.dat scan 17 (no MCA data) from spec2nexus import utils label1, start1, end1, intervals1, label2, start2, end2, intervals2, time = scan.scanCmd.split( )[1:] if label1 not in scan.data: label1 = scan.L[0] # mnemonic v. name if label2 not in scan.data: label2 = scan.L[1] # mnemonic v. name axis1 = scan.data.get(label1) axis2 = scan.data.get(label2) intervals1, intervals2 = int(intervals1), int(intervals2) start1, end1 = float(start1), float(end1) start2, end2 = float(start2), float(end2) time = float(time) if len(axis1) < intervals1: # stopped scan before second row started self.parser_1D_columns(nxdata, scan) # fallback support # TODO: what about the MCA data in this case? else: axis1 = axis1[0:intervals1 + 1] axis2 = [ axis2[row] for row in range(len(axis2)) if row % (intervals1 + 1) == 0 ] column_labels = scan.L column_labels.remove(label1) # special handling column_labels.remove(label2) # special handling if scan.scanCmd.startswith('hkl'): # find the reciprocal space axis held constant label3 = [ key for key in ('H', 'K', 'L') if key not in (label1, label2) ][0] axis3 = scan.data.get(label3)[0] nxdata[label3] = NXfield(axis3) column_labels.remove(label3) # already handled nxdata[label1] = NXfield(axis1) # 1-D array nxdata[label2] = NXfield(axis2) # 1-D array # build 2-D data objects (do not build label1, label2, [or label3] as 2-D objects) data_shape = [len(axis2), len(axis1)] for label in column_labels: axis = np.array(scan.data.get(label)) clean_name = utils.sanitize_name(nxdata, label) nxdata[clean_name] = NXfield( utils.reshape_data(axis, data_shape)) nxdata[clean_name].original_name = label signal_axis_label = utils.sanitize_name(nxdata, scan.column_last) nxdata.nxsignal = nxdata[signal_axis_label] nxdata.nxaxes = [nxdata[label2], nxdata[label1]] if '_mca_' in scan.data: # 3-D array # TODO: ?merge with parser_mca_spectra()? for mca_key, mca_data in scan.data['_mca_'].items(): key = "__" + mca_key spectra_lengths = list(map(len, mca_data)) num_channels = max(spectra_lengths) if num_channels != min(spectra_lengths): msg = 'MCA spectra have different lengths' msg += ' in scan #' + str(scan.scanNum) msg += ' in file ' + str(scan.specFile) raise ValueError(msg) data_shape += [ num_channels, ] mca = np.array(mca_data) nxdata[key] = NXfield(utils.reshape_data(mca, data_shape)) nxdata[key].units = "counts" try: # use MCA channel numbers as known at time of scan chan1 = scan.MCA['first_saved'] chanN = scan.MCA['last_saved'] channel_range = range(chan1, chanN + 1) except: # basic indices channel_range = range(1, num_channels + 1) ch_key = key + "_channel" nxdata[ch_key] = NXfield(channel_range) nxdata[ch_key].units = 'channel' axes = (label1, label2, ch_key) nxdata[key].axes = ':'.join(axes)
def toTree(self, scan_list=[]): ''' convert scans from chosen SPEC file into NXroot object and structure called from nexpy.readers.readspec.ImportDialog.get_data__prjPySpec() after clicking <Ok> in dialog Each scan in the range from self.scanmin to self.scanmax (inclusive) will be converted to a NXentry. Scan data will go in a NXdata where the signal=1 is the last column and the corresponding axes= is the first column. :param [int] scanlist :raises: ValueError is Min or Max scan number are not given properly ''' import spec2nexus from spec2nexus import utils # check that scan_list is valid if len(scan_list) == 0: return None if self.SPECfile is None: return None complete_scan_list = list(self.SPECfile.scans) for key in [str(s) for s in scan_list]: if key not in complete_scan_list: msg = 'scan ' + str(key) + ' was not found' raise ValueError(msg) root = NXroot() root.attrs['spec2nexus'] = str(spec2nexus.__version__) header0 = self.SPECfile.headers[0] root.attrs['SPEC_file'] = self.SPECfile.fileName root.attrs['SPEC_epoch'] = header0.epoch root.attrs['SPEC_date'] = utils.iso8601(header0.date) root.attrs['SPEC_comments'] = '\n'.join(header0.comments) try: c = header0.comments[0] user = c[c.find('User = '******'=')[1].strip() root.attrs['SPEC_user'] = user except: pass root.attrs['SPEC_num_headers'] = len(self.SPECfile.headers) self.progress_bar.setVisible(True) self.progress_bar.setRange(scan_list[0], scan_list[-1]) for key in [str(s) for s in scan_list]: scan = self.SPECfile.getScan(key) scan.interpret() entry = NXentry() entry.title = str(scan) entry.date = utils.iso8601(scan.date) entry.command = scan.scanCmd entry.scan_number = NXfield(scan.scanNum) entry.comments = '\n'.join(scan.comments) entry.data = self.scan_NXdata(scan) # store the scan data entry.positioners = self.metadata_NXlog( scan.positioner, 'SPEC positioners (#P & #O lines)') if hasattr(scan, 'metadata') and len(scan.metadata) > 0: entry.metadata = self.metadata_NXlog( scan.metadata, 'SPEC metadata (UNICAT-style #H & #V lines)') if len(scan.G) > 0: entry.G = NXlog() desc = "SPEC geometry arrays, meanings defined by SPEC diffractometer support" # e.g.: SPECD/four.mac # http://certif.com/spec_manual/fourc_4_9.html entry.G.attrs['description'] = desc for item, value in scan.G.items(): entry.G[item] = NXfield(list(map(float, value.split()))) if scan.T != '': entry['counting_basis'] = NXfield( 'SPEC scan with constant counting time') entry['T'] = NXfield(float(scan.T)) entry['T'].units = 'seconds' entry[ 'T'].description = 'SPEC scan with constant counting time' elif scan.M != '': entry['counting_basis'] = NXfield( 'SPEC scan with constant monitor count') entry['M'] = NXfield(float(scan.M)) entry['M'].units = 'counts' entry[ 'M'].description = 'SPEC scan with constant monitor count' if scan.Q != '': entry['Q'] = NXfield(list(map(float, scan.Q))) entry['Q'].description = 'hkl at start of scan' root['scan_' + str(key)] = entry self.progress_bar.setValue(int(key)) self.update_progress() return root
def parser_mesh(self, nxdata, scan): '''data parser for 2-D mesh and hklmesh''' # 2-D parser: http://www.certif.com/spec_help/mesh.html # mesh motor1 start1 end1 intervals1 motor2 start2 end2 intervals2 time # 2-D parser: http://www.certif.com/spec_help/hklmesh.html # hklmesh Q1 start1 end1 intervals1 Q2 start2 end2 intervals2 time # mesh: nexpy/examples/33id_spec.dat scan 22 (also has MCA, thus 3-D data) # hklmesh: nexpy/examples/33bm_spec.dat scan 17 (no MCA data) from spec2nexus import utils label1, start1, end1, intervals1, label2, start2, end2, intervals2, time = scan.scanCmd.split()[1:] if label1 not in scan.data: label1 = scan.L[0] # mnemonic v. name if label2 not in scan.data: label2 = scan.L[1] # mnemonic v. name axis1 = scan.data.get(label1) axis2 = scan.data.get(label2) intervals1, intervals2 = int(intervals1), int(intervals2) start1, end1 = float(start1), float(end1) start2, end2 = float(start2), float(end2) time = float(time) if len(axis1) < intervals1: # stopped scan before second row started self.parser_1D_columns(nxdata, scan) # fallback support # TODO: what about the MCA data in this case? else: axis1 = axis1[0:intervals1+1] axis2 = [axis2[row] for row in range(len(axis2)) if row % (intervals1+1) == 0] column_labels = scan.L column_labels.remove(label1) # special handling column_labels.remove(label2) # special handling if scan.scanCmd.startswith('hkl'): # find the reciprocal space axis held constant label3 = [key for key in ('H', 'K', 'L') if key not in (label1, label2)][0] axis3 = scan.data.get(label3)[0] nxdata[label3] = NXfield(axis3) column_labels.remove(label3) # already handled nxdata[label1] = NXfield(axis1) # 1-D array nxdata[label2] = NXfield(axis2) # 1-D array # build 2-D data objects (do not build label1, label2, [or label3] as 2-D objects) data_shape = [len(axis2), len(axis1)] for label in column_labels: axis = np.array( scan.data.get(label) ) clean_name = utils.sanitize_name(nxdata, label) nxdata[clean_name] = NXfield(utils.reshape_data(axis, data_shape)) nxdata[clean_name].original_name = label signal_axis_label = utils.sanitize_name(nxdata, scan.column_last) nxdata.nxsignal = nxdata[signal_axis_label] nxdata.nxaxes = [nxdata[label2], nxdata[label1]] if '_mca_' in scan.data: # 3-D array # TODO: ?merge with parser_mca_spectra()? for mca_key, mca_data in scan.data['_mca_'].items(): key = "__" + mca_key spectra_lengths = list(map(len, mca_data)) num_channels = max(spectra_lengths) if num_channels != min(spectra_lengths): msg = 'MCA spectra have different lengths' msg += ' in scan #' + str(scan.scanNum) msg += ' in file ' + str(scan.specFile) raise ValueError(msg) data_shape += [num_channels, ] mca = np.array(mca_data) nxdata[key] = NXfield(utils.reshape_data(mca, data_shape)) nxdata[key].units = "counts" try: # use MCA channel numbers as known at time of scan chan1 = scan.MCA['first_saved'] chanN = scan.MCA['last_saved'] channel_range = range(chan1, chanN+1) except: # basic indices channel_range = range(1, num_channels+1) ch_key = key + "_channel" nxdata[ch_key] = NXfield(channel_range) nxdata[ch_key].units = 'channel' axes = (label1, label2, ch_key) nxdata[key].axes = ':'.join( axes )
def toTree(self, scan_list=[]): ''' convert scans from chosen SPEC file into NXroot object and structure called from nexpy.readers.readspec.ImportDialog.get_data__prjPySpec() after clicking <Ok> in dialog Each scan in the range from self.scanmin to self.scanmax (inclusive) will be converted to a NXentry. Scan data will go in a NXdata where the signal=1 is the last column and the corresponding axes= is the first column. :param [int] scanlist :raises: ValueError is Min or Max scan number are not given properly ''' import spec2nexus from spec2nexus import utils # check that scan_list is valid if len(scan_list) == 0: return None if self.SPECfile is None: return None complete_scan_list = list(self.SPECfile.scans) for key in [str(s) for s in scan_list]: if key not in complete_scan_list: msg = 'scan ' + str(key) + ' was not found' raise ValueError(msg) root = NXroot() root.attrs['spec2nexus'] = str(spec2nexus.__version__) header0 = self.SPECfile.headers[0] root.attrs['SPEC_file'] = self.SPECfile.fileName root.attrs['SPEC_epoch'] = header0.epoch root.attrs['SPEC_date'] = utils.iso8601(header0.date) root.attrs['SPEC_comments'] = '\n'.join(header0.comments) try: c = header0.comments[0] user = c[c.find('User = '******'=')[1].strip() root.attrs['SPEC_user'] = user except: pass root.attrs['SPEC_num_headers'] = len(self.SPECfile.headers) self.progress_bar.setVisible(True) self.progress_bar.setRange(scan_list[0], scan_list[-1]) for key in [str(s) for s in scan_list]: scan = self.SPECfile.getScan(key) scan.interpret() entry = NXentry() entry.title = str(scan) entry.date = utils.iso8601(scan.date) entry.command = scan.scanCmd entry.scan_number = NXfield(scan.scanNum) entry.comments = '\n'.join(scan.comments) entry.data = self.scan_NXdata(scan) # store the scan data entry.positioners = self.metadata_NXlog(scan.positioner, 'SPEC positioners (#P & #O lines)') if hasattr(scan, 'metadata') and len(scan.metadata) > 0: entry.metadata = self.metadata_NXlog(scan.metadata, 'SPEC metadata (UNICAT-style #H & #V lines)') if len(scan.G) > 0: entry.G = NXlog() desc = "SPEC geometry arrays, meanings defined by SPEC diffractometer support" # e.g.: SPECD/four.mac # http://certif.com/spec_manual/fourc_4_9.html entry.G.attrs['description'] = desc for item, value in scan.G.items(): entry.G[item] = NXfield(list(map(float, value.split()))) if scan.T != '': entry['counting_basis'] = NXfield('SPEC scan with constant counting time') entry['T'] = NXfield(float(scan.T)) entry['T'].units = 'seconds' entry['T'].description = 'SPEC scan with constant counting time' elif scan.M != '': entry['counting_basis'] = NXfield('SPEC scan with constant monitor count') entry['M'] = NXfield(float(scan.M)) entry['M'].units = 'counts' entry['M'].description = 'SPEC scan with constant monitor count' if scan.Q != '': entry['Q'] = NXfield(list(map(float,scan.Q))) entry['Q'].description = 'hkl at start of scan' root['scan_' + str(key)] = entry self.progress_bar.setValue(int(key)) self.update_progress() return root