def write_sample_counts(self, total, rate): self._entry.sample.total_counts = NXfield(int(total), dtype='int32', units=string_attr('counts')) self._entry.sample.total_count_rate = NXfield(float(rate), dtype='float32', units=string_attr('1/s'))
def get_data(self): prefix = self.get_prefix() if prefix: self.import_file = prefix else: self.import_file = self.get_directory() filenames = self.get_files() v0 = self.read_image(filenames[0]) x = NXfield(range(v0.shape[1]), dtype=np.uint16, name='x') y = NXfield(range(v0.shape[0]), dtype=np.uint16, name='y') z = NXfield(range(1, len(filenames) + 1), dtype=np.uint16, name='z') v = NXfield(shape=(len(filenames), v0.shape[0], v0.shape[1]), dtype=v0.dtype, name='v') v[0] = v0 if v._memfile: chunk_size = v._memfile['data'].chunks[0] else: chunk_size = v.shape[0] / 10 self.progress_bar.setVisible(True) self.progress_bar.setRange(0, len(filenames)) for i in range(0, len(filenames)): try: files = [] for j in range(i, i + chunk_size): files.append(filenames[j]) self.progress_bar.setValue(j) self.update_progress() v[i:i + chunk_size, :, :] = self.read_images(files) except IndexError as error: pass global maximum v.maximum = maximum return NXentry(NXdata(v, (z, y, x)))
def get_data(self): prefix = self.get_prefix() if prefix: self.import_file = prefix else: self.import_file = self.get_directory() filenames = self.get_files() try: import fabio except ImportError: raise NeXusError("Please install the 'fabio' module") im = self.read_image(filenames[0]) v0 = im.data x = NXfield(range(v0.shape[1]), dtype=np.uint16, name='x') y = NXfield(range(v0.shape[0]), dtype=np.uint16, name='y') z = NXfield(range(1, len(filenames)+1), dtype=np.uint16, name='z') v = NXfield(shape=(len(filenames), v0.shape[0], v0.shape[1]), dtype=v0.dtype, name='v') v[0] = v0 if v._memfile: chunk_size = v._memfile['data'].chunks[0] else: chunk_size = v.shape[0]/10 self.progress_bar.setVisible(True) self.progress_bar.setRange(0, len(filenames)) for i in range(0, len(filenames), chunk_size): try: files = [] for j in range(i, i+chunk_size): files.append(filenames[j]) self.progress_bar.setValue(j) self.update_progress() v[i:i+chunk_size, :, :] = self.read_images(files) except IndexError as error: pass global maximum v.maximum = maximum if im.getclassname() == 'CbfImage': note = NXnote(type='text/plain', file_name=self.import_file) note.data = im.header.pop('_array_data.header_contents', '') note.description = im.header.pop( '_array_data.header_convention', '') else: note = None header = NXcollection() for key, value in im.header.items(): header[key] = value if note: return NXentry( NXdata( v, (z, y, x), CBF_header=note, header=header)) else: return NXentry(NXdata(v, (z, y, x), header=header))
def get_model(self, f=None): self.read_parameters() fit = Fit(self.data, self.functions) if self.plot_checkbox.isChecked(): x = fit.x else: x = np.linspace(float(self.plot_minbox.text()), float(self.plot_maxbox.text()), 1001) return NXdata(NXfield(fit.get_model(x, f), name='model'), NXfield(x, name=fit.data.nxaxes[0].nxname), title='Fit Results')
def write_chopper_vacuum(self, vac0, vac1, vac2, vac3): if vac0 is not None: self._entry.instrument.chopper_vac0 = NXfield( float(vac0), dtype='float32', units=string_attr('mbar')) if vac1 is not None: self._entry.instrument.chopper_vac1 = NXfield( float(vac1), dtype='float32', units=string_attr('mbar')) if vac2 is not None: self._entry.instrument.chopper_vac2 = NXfield( float(vac2), dtype='float32', units=string_attr('mbar')) if vac3 is not None: self._entry.instrument.chopper_vac3 = NXfield( float(vac3), dtype='float32', units=string_attr('mbar'))
def write_sample_temperature(self, average, std, minimum, maximum): val, unit = average.split() self._entry.sample.temperature = NXfield(float(val), dtype='float32', units=string_attr(unit)) val, unit = std.split() self._entry.sample.standard_deviation_of_temperature = NXfield( float(val), dtype='float32', units=string_attr(unit)) val, unit = minimum.split() self._entry.sample.minimum_temperature = NXfield( float(val), dtype='float32', units=string_attr(unit)) val, unit = maximum.split() self._entry.sample.maximum_temperature = NXfield( float(val), dtype='float32', units=string_attr(unit))
def get_data(self): self.import_file = self.get_filename() if not self.import_file: raise NeXusError("No file specified") try: import tifffile as TIFF except ImportError: raise NeXusError("Please install the 'tifffile' module") im = TIFF.imread(self.import_file) z = NXfield(im, name='z') y = NXfield(np.arange(z.shape[0], dtype=float), name='y') x = NXfield(np.arange(z.shape[1], dtype=float), name='x') return NXentry(NXdata(z, (y, x)))
def convert_QE(entry, dQ, dE): """Convert S(phi,eps) to S(Q,eps)""" az = entry.data.azimuthal.nxdata[:] pol = entry.data.polar.nxdata[:] pol, en = centers(entry.data.nxsignal, entry.data.nxaxes) data = entry.data.data.nxdata[:] errors = entry.data.errors.nxdata[:] Ei = entry.instrument.monochromator.incident_energy.nxdata Q = np.zeros((len(pol), len(en))) E = np.zeros((len(pol), len(en))) for i in range(0, len(pol)): for j in range(0, len(en)): Q[i][j] = np.sqrt((2*Ei - en[j] - 2*np.sqrt(Ei*(Ei-en[j])) * np.cos(pol[i]*np.pi/180.0))/2.0721) E[i][j] = en[j] s = Q.shape Qin = Q.reshape(s[0]*s[1]) Ein = E.reshape(s[0]*s[1]) datain = data.reshape(s[0]*s[1]) errorsin = errors.reshape(s[0]*s[1]) qmin = Q.min() qmax = Q.max() emin = E.min() emax = E.max() NQ = int((qmax-qmin)/dQ) + 1 NE = int((emax-emin)/dE) + 1 Qb = np.linspace(qmin, qmax, NQ) Eb = np.linspace(emin, emax, NE) # histogram and normalize norm, nbin = np.histogramdd((Ein, Qin), bins=(Eb, Qb)) hist, hbin = np.histogramdd((Ein, Qin), bins=(Eb, Qb), weights=datain) histe, hbin = np.histogramdd( (Ein, Qin), bins=(Eb, Qb), weights=errorsin * errorsin) histe = histe**0.5 Ib = NXfield(hist/norm, name='S(Q,E)') err = histe/norm Qb = NXfield(Qb[:-1]+dQ/2., name='Q') Eb = NXfield(Eb[:-1]+dE/2., name='E') return NXdata(Ib, (Eb, Qb), errors=NXfield(err))
def plot_peaks(self, x, y): try: polar_angles, azimuthal_angles = self.refine.calculate_angles(x, y) if polar_angles[0] > polar_angles[-1]: polar_angles = polar_angles[::-1] azimuthal_angles = azimuthal_angles[::-1] azimuthal_field = NXfield(azimuthal_angles, name='azimuthal_angle') azimuthal_field.long_name = 'Azimuthal Angle' polar_field = NXfield(polar_angles, name='polar_angle') polar_field.long_name = 'Polar Angle' plotview = get_plotview() plotview.plot( NXdata(azimuthal_field, polar_field, title='Peak Angles')) except NeXusError as error: report_error("Plotting Lattice", error)
def write_sample_pressure(self, average, std, minimum=None, maximum=None): val, unit = average.split() self._entry.sample.pressure = NXfield(float(val), dtype='float32', units=string_attr(unit)) val, unit = std.split() self._entry.sample.standard_deviation_of_pressure = NXfield( float(val), dtype='float32', units=string_attr(unit)) if minimum: val, unit = minimum.split() self._entry.sample.minimum_pressure = NXfield( float(val), dtype='float32', units=string_attr(unit)) if maximum: val, unit = maximum.split() self._entry.sample.maximum_pressure = NXfield( float(val), dtype='float32', units=string_attr(unit))
def write_monitor_data(self, value): self._entry.monitor.data = NXfield( value, signal=1, dtype='int64', # axis=string_attr('channel_number'), units=string_attr('counts'))
def save(self, x=None): """Save the fit results in a NXprocess group. Parameters ---------- x : ndarray, optional x-values at which to calculate the model. Defaults to `self.x` Returns ------- group : NXprocess NXprocess group that contains the data, models and parameters. """ group = NXprocess(program='lmfit', version=__version__) group['data'] = self.data for f in self.functions: group[f.name] = NXdata(NXfield(self.get_model(x, f), name='model'), NXfield(x, name=self.data.nxaxes[0].nxname), title='Fit Results') parameters = NXparameters() for p in f.parameters: parameters[p.name] = NXfield(p.value, error=p.stderr, initial_value=p.init_value, min=str(p.min), max=str(p.max)) group[f.name]['parameters'] = parameters group['title'] = 'Fit Results' group['fit'] = NXdata(NXfield(self.get_model(x), name='model'), NXfield(x, name=self.data.nxaxes[0].nxname), title='Fit Results') if self.result is not None: fit = NXparameters() fit.nfev = self.result.nfev fit.chisq = self.result.chisqr fit.redchi = self.result.redchi fit.message = self.result.message group['statistics'] = fit group.note = NXnote( self.fit.result.message, f'Chi^2 = {self.fit.result.chisqr}\n' f'Reduced Chi^2 = {self.fit.result.redchi}\n' f'No. of Function Evaluations = {self.fit.result.nfev}\n' f'No. of Variables = {self.fit.result.nvarys}\n' f'No. of Data Points = {self.fit.result.ndata}\n' f'No. of Degrees of Freedom = {self.fit.result.nfree}\n' f'{self.fit.fit_report()}') return group
def save_fit(self): """Saves fit results to an NXentry""" self.read_parameters() group = NXprocess() group['data'] = self.data for f in self.functions: group[f.name] = self.get_model(f) parameters = NXparameters() for p in f.parameters: parameters[p.name] = NXfield(p.value, error=p.stderr, initial_value=p.init_value, min=str(p.min), max=str(p.max)) group[f.name].insert(parameters) if self.fit is not None: group['program'] = 'lmfit' group['version'] = lmfit.__version__ group['title'] = 'Fit Results' group['fit'] = self.get_model() fit = NXparameters() fit.nfev = self.fit.result.nfev fit.ier = self.fit.result.ier fit.chisq = self.fit.result.chisqr fit.redchi = self.fit.result.redchi fit.message = self.fit.result.message fit.lmdif_message = self.fit.result.lmdif_message group['statistics'] = fit group.note = NXnote( self.fit.result.message, ('%s\n' % self.fit.result.lmdif_message + 'scipy.optimize.leastsq error value = %s\n' % self.fit.result.ier + 'Chi^2 = %s\n' % self.fit.result.chisqr + 'Reduced Chi^2 = %s\n' % self.fit.result.redchi + 'No. of Function Evaluations = %s\n' % self.fit.result.nfev + 'No. of Variables = %s\n' % self.fit.result.nvarys + 'No. of Data Points = %s\n' % self.fit.result.ndata + 'No. of Degrees of Freedom = %s\n' % self.fit.result.nfree + '%s' % self.fit.fit_report())) else: group['title'] = 'Fit Model' group['model'] = self.get_model() if 'w0' not in self.tree: self.tree['w0'] = nxload(self.mainwindow.scratch_file, 'rw') ind = [] for key in self.tree['w0']: try: if key.startswith('f'): ind.append(int(key[1:])) except ValueError: pass if not ind: ind = [0] name = 'f' + str(sorted(ind)[-1] + 1) self.tree['w0'][name] = group
def plot_peaks(self): try: x, y = (self.refine.xp[self.refine.idx], self.refine.yp[self.refine.idx]) polar_angles, azimuthal_angles = self.refine.calculate_angles(x, y) if polar_angles[0] > polar_angles[-1]: polar_angles = polar_angles[::-1] azimuthal_angles = azimuthal_angles[::-1] azimuthal_field = NXfield(azimuthal_angles, name='azimuthal_angle') azimuthal_field.long_name = 'Azimuthal Angle' polar_field = NXfield(polar_angles, name='polar_angle') polar_field.long_name = 'Polar Angle' plotview = get_plotview() plotview.plot(NXdata(azimuthal_field, polar_field, title=f'{self.refine.name} Peak Angles'), xmax=self.get_polar_max()) except NeXusError as error: report_error('Plotting Lattice', error)
def setup_configuration(self): default = self.settings['nxrefine'] entry = self.configuration_file['entry'] entry['instrument/monochromator/wavelength'] = NXfield( default['wavelength'], dtype=np.float32) entry['instrument/monochromator/wavelength'].attrs['units'] = ( 'Angstroms') entry['instrument/monochromator/energy'] = NXfield(12.398419739640717 / 0.5, dtype=np.float32) entry['instrument/monochromator/energy'].attrs['units'] = 'keV' entry['instrument/goniometer'] = NXgoniometer() entry['instrument/detector'] = NXdetector() self.configuration = GridParameters() self.configuration.add('configuration', 'configuration', 'Configuration Filename') self.configuration.add('wavelength', entry['instrument/monochromator/wavelength'], 'Wavelength (Å)')
def setup_scan(self): default = self.settings['nxrefine'] entry = self.configuration_file['entry'] entry['instrument/goniometer/chi'] = (NXfield(default['chi'], dtype=float)) entry['instrument/goniometer/chi'].attrs['units'] = 'degree' entry['instrument/goniometer/phi'] = (NXfield(default['phi'], dtype=float)) entry['instrument/goniometer/phi'].attrs['step'] = (NXfield( default['phi_step'], dtype=float)) entry['instrument/goniometer/phi'].attrs['end'] = (NXfield( default['phi_end'], dtype=float)) entry['instrument/goniometer/phi'].attrs['units'] = 'degree' entry['instrument/detector/frame_time'] = (NXfield( 1 / float(default['frame_rate']), dtype=float)) self.scan = GridParameters() self.scan.add('chi', default['chi'], 'Chi (deg)') self.scan.add('phi_start', default['phi'], 'Phi Start (deg)') self.scan.add('phi_end', default['phi_end'], 'Phi End (deg)') self.scan.add('phi_step', default['phi_step'], 'Phi Step (deg)') self.scan.add('frame_rate', default['frame_rate'], 'Frame Rate (Hz)')
def rebin2D(self, spw, phi, psi, omega, dphi, dpsi): rot = np.linspace(np.round(phi.min() - 0.5 * dphi, 2), np.round(phi.max() + 0.5 * dphi, 2), np.round(phi.ptp() / dphi)).astype(np.float32) tilt = np.linspace(np.round(psi.min() - 0.5 * dpsi, 2), np.round(psi.max() + 0.5 * dpsi, 2), np.round(psi.ptp() / dpsi)).astype(np.float32) en = 0.5*(omega[1:]+omega[:-1]) data = NXfield(name='data', dtype='float32', shape=[ rot.size-1, tilt.size-1, omega.size-1]) rotation_angle = NXfield(rot, name='rotation_angle', units='degree') tilt_angle = NXfield(tilt, name='tilt_angle', units='degree') energy_transfer = NXfield(omega, name='energy_transfer', units='meV') pixels = np.array(zip(np.repeat(phi, en.size), np.repeat( psi, en.size), np.tile(en, phi.size))) hist, edges = np.histogramdd( pixels, [rot, tilt, omega], weights=spw.reshape(spw.size)) return NXdata( NXfield(hist, name='intensity'), (rotation_angle, tilt_angle, energy_transfer))
def write_data(self, block, channels): try: self._entry.data.makelink( self._entry.instrument.detector.polar_angle) except NeXusError: pass nDet = len(self.eleTotal) data = [] for i in range(nDet): data += block[self.eleTotal[i] - 1].tolist() data = np.array(data, dtype='int32').reshape(nDet, 1, int(channels)) self._entry.data.data = NXfield( data, signal=1, dtype='int32', # compression='lzf', axes=string_attr('2theta:channel_number'), units=string_attr('counts')) channel_number = np.arange(int(channels), dtype='float32') self._entry.data.channel_number = NXfield(channel_number)
def plot_cake(self): if 'Cake Plot' in plotviews: plotview = plotviews['Cake Plot'] else: plotview = NXPlotView('Cake Plot') if not self.is_calibrated: raise NeXusError('No refinement performed') res = self.cake_geometry.integrate2d(self.counts, 1024, 1024, method='csr', unit='2th_deg', correctSolidAngle=True) self.cake_data = NXdata(res[0], (NXfield(res[2], name='azimumthal_angle'), NXfield(res[1], name='polar_angle'))) self.cake_data['title'] = 'Cake Plot' plotview.plot(self.cake_data, log=True) wavelength = self.parameters['wavelength'].value polar_angles = [2 * np.degrees(np.arcsin(wavelength/(2*d))) for d in self.calibrant.dSpacing] plotview.vlines([polar_angle for polar_angle in polar_angles if polar_angle < plotview.xaxis.max], linestyle=':', color='r')
def write_times(self, stime, etime, duration=None): fmtin = '%d.%m.%YT%H:%M:%S' fmtout = '%Y-%m-%dT%H:%M:%S%z' tzinfo = pytz.timezone('Europe/Berlin') t0 = datetime.strptime(stime, fmtin).replace(tzinfo=tzinfo) t1 = datetime.strptime(etime, fmtin).replace(tzinfo=tzinfo) if duration is None: duration = (t1 - t0).total_seconds() assert (duration >= 0) self._entry.start_time = string_(t0.strftime(fmtout)) self._entry.end_time = string_(t1.strftime(fmtout)) self._entry.duration = NXfield(int(duration), dtype='int32', units=string_attr('s'))
def get_nxspe(self): spe_file = nxload(self.import_file) entry = NXentry() entry.title = self.get_title() Ei = self.get_energy() if Ei and Ei > 0.0: entry.instrument = NXinstrument() entry.instrument.monochromator = NXmonochromator( NXfield(Ei, name="incident_energy", units="meV")) entry.data = spe_file.NXentry[0].data entry.data.nxsignal = entry.data.data if 'energy' in entry.data.entries: entry.data.energy.rename('energy_transfer') entry.data.nxaxes = [entry.data.polar, entry.data.energy_transfer] if 'error' in entry.data.entries: entry.data.error.rename('errors') return entry
def get_data(self): group = NXgroup(name=self.groupbox.text()) group.nxclass = self.groupcombo.selected for i, col in enumerate( [c for c in self.data if self.data[c]['signal'] != 'exclude']): name = self.data[col]['name'] group[name] = NXfield(self.data[col]['data'], dtype=self.data[col]['dtype']) if self.header and name != self.headers[i]: group[name].long_name = self.headers[i] if isinstance(group, NXdata): if self.data[col]['signal'] == 'signal': group.nxsignal = group[name] elif self.data[col]['signal'] == 'axis': group.nxaxes = [group[name]] elif self.data[col]['signal'] == 'signal': group.nxerrors = group[name] return NXentry(group)
def setup_instrument(self): default = self.settings['nxrefine'] entry = self.configuration_file['entry'] entry['instrument/detector/distance'] = NXfield(default['distance'], dtype=float) entry['instrument/detector/distance'].attrs['units'] = 'mm' self.instrument = GridParameters() self.instrument.add('distance', entry['instrument/detector/distance'], 'Detector Distance (mm)') detector_list = sorted( list(set([detector().name for detector in ALL_DETECTORS.values()]))) self.instrument.add('detector', detector_list, 'Detector') self.instrument['detector'].value = 'Pilatus CdTe 2M' self.instrument.add('positions', [0, 1, 2, 3, 4, 5, 6, 7, 8], 'Number of Detector Positions', slot=self.set_entries) self.instrument['positions'].value = '0'
def save_fit(self): """Saves fit results to an NXentry""" self.read_parameters() entry = NXentry() entry['data'] = self.data for f in self.functions: entry[f.name] = self.get_model(f) parameters = NXparameters() for p in f.parameters: parameters[p.name] = NXfield(p.value, error=p.stderr, initial_value=p.init_value, min=str(p.min), max=str(p.max)) entry[f.name].insert(parameters) if self.fit is not None: entry['title'] = 'Fit Results' entry['fit'] = self.get_model() fit = NXparameters() fit.nfev = self.fit.result.nfev fit.ier = self.fit.result.ier fit.chisq = self.fit.result.chisqr fit.redchi = self.fit.result.redchi fit.message = self.fit.result.message fit.lmdif_message = self.fit.result.lmdif_message entry['statistics'] = fit else: entry['title'] = 'Fit Model' entry['model'] = self.get_model() if 'w0' not in self.tree.keys(): self.tree.add(NXroot(name='w0')) ind = [] for key in self.tree['w0'].keys(): try: if key.startswith('f'): ind.append(int(key[1:])) except ValueError: pass if not ind: ind = [0] name = 'f' + str(sorted(ind)[-1] + 1) self.tree['w0'][name] = entry
def load_image(filename): if os.path.splitext( filename.lower())[1] in ['.png', '.jpg', '.jpeg', '.gif']: from matplotlib.image import imread im = imread(filename) z = NXfield(im, name='z') y = NXfield(range(z.shape[0]), name='y') x = NXfield(range(z.shape[1]), name='x') if z.ndim > 2: rgba = NXfield(range(z.shape[2]), name='rgba') if len(rgba) == 3: z.interpretation = 'rgb-image' elif len(rgba) == 4: z.interpretation = 'rgba-image' data = NXdata(z, (y, x, rgba)) else: data = NXdata(z, (y, x)) else: try: im = fabio.open(filename) except Exception as error: if fabio: raise NeXusError("Unable to open image") else: raise NeXusError( "Unable to open image. Please install the 'fabio' module") z = NXfield(im.data, name='z') y = NXfield(range(z.shape[0]), name='y') x = NXfield(range(z.shape[1]), name='x') data = NXdata(z, (y, x)) if im.header: header = NXcollection() for k, v in im.header.items(): if v or v == 0: header[k] = v data.header = header if im.getclassname() == 'CbfImage': note = NXnote(type='text/plain', file_name=filename) note.data = im.header.pop('_array_data.header_contents', '') note.description = im.header.pop('_array_data.header_convention', '') data.CBF_header = note data.title = filename return data
def setup_analysis(self): default = self.settings['nxreduce'] entry = self.configuration_file['entry'] entry['nxreduce/threshold'] = NXfield(default['threshold'], dtype=float) entry['nxreduce/monitor'] = NXfield(default['monitor']) entry['nxreduce/norm'] = NXfield(default['norm'], dtype=float) entry['nxreduce/first_frame'] = NXfield(default['first'], dtype=int) entry['nxreduce/last_frame'] = NXfield(default['last'], dtype=int) entry['nxreduce/radius'] = NXfield(default['radius'], dtype=float) self.analysis = GridParameters() self.analysis.add('threshold', entry['nxreduce/threshold'], 'Peak Threshold') self.analysis.add('first', entry['nxreduce/first_frame'], 'First Frame') self.analysis.add('last', entry['nxreduce/last_frame'], 'Last Frame') self.analysis.add('monitor', ['monitor1', 'monitor2'], 'Normalization Monitor') self.analysis['monitor'].value = default['monitor'] self.analysis.add('norm', entry['nxreduce/norm'], 'Normalization Value') self.analysis.add('radius', entry['nxreduce/radius'], 'Punch Radius (Å)')
def get_spe(self, phxfile=None): entry = NXentry() phi, omega, spw, errors = readspe(self.get_filename()) if phxfile: theta, phi, dtheta, dpsi = readphx(phxfile) phip, psi = angles(theta, phi) instrument = NXinstrument(NXdetector()) instrument.detector.polar_angle = NXfield(theta, units="degrees") Ei = self.get_energy() if Ei and Ei > 0.0: instrument.monochromator = NXmonochromator( NXfield(Ei, name="incident_energy", units="meV")) if phi.ptp() > 1.0: # i.e., the azimuthal angle is specified instrument.detector.azimuthal_angle = NXfield( phi, units="degrees") instrument.detector.rotation_angle = NXfield( phip, units="degrees") instrument.detector.tilt_angle = NXfield(psi, units="degrees") data = NXdata( NXfield( spw, name="intensity", long_name="Neutron Intensity"), ( NXfield( np.arange(1, len(theta) + 1), name="spectrum_index", long_name="Spectrum Index"), NXfield( omega, name="energy_transfer", units="meV", long_name="Energy Transfer")), errors=NXfield( np.sqrt(errors), name="errors", long_name="Errors")) if np.median(dtheta) > 0.0 and np.median(dpsi) > 0.0: data2D = rebin2D( spw, phip, psi, omega, np.median(dtheta), np.median(dpsi)) return NXentry(instrument, data, data2D=data2D) else: return NXentry(instrument, data) else: phi = np.zeros(theta.size+1) phi[:-1] = theta - 0.5*dtheta phi[-1] = theta[-1] + 0.5*dtheta[-1] data = NXdata( NXfield( spw, name="intensity", long_name="Neutron Intensity"), ( NXfield( phi, name="polar_angle", long_name="Polar Angle", units="degrees"), NXfield( omega, name="energy_transfer", units="meV", long_name="Energy Transfer")), errors=NXfield( np.sqrt(errors), name="errors", long_name="Errors")) return NXentry(instrument, data) else: Ei = self.get_energy() if Ei and Ei > 0.0: entry = NXentry( NXinstrument( NXmonochromator( NXfield( Ei, name="incident_energy", units="meV")))) else: entry = NXentry() if phi.ptp() > 1.0: entry.data = NXdata( NXfield(spw, name="intensity", long_name="Neutron Intensity"), (NXfield(phi, name="polar_angle", units="degrees", long_name="Polar Angle"), NXfield(omega, name="energy_transfer", units="meV", long_name="Energy Transfer")), errors=NXfield(np.sqrt(errors), name="errors", long_name="Errors")) else: entry.data = NXdata( NXfield(spw, name="intensity", long_name="Neutron Intensity"), (NXfield(np.arange(1, len(phi)+1), name="spectrum_index", long_name="Spectrum Index"), NXfield(omega, name="energy_transfer", units="meV", long_name="Energy Transfer")), errors=NXfield(np.sqrt(errors), name="errors", long_name="Errors")) return entry
def convert_QE(self): """Convert S(phi,eps) to S(Q,eps)""" self.read_parameters() Ei = self.Ei dQ = self.dQ dE = self.dE signal = self.entry['data'].nxsignal pol = centers(self.entry['data/polar_angle'], signal.shape[0]) tof = centers(self.entry['data/time_of_flight'], signal.shape[1]) en = self.convert_tof(tof) idx_max = min(np.where(np.abs(en - 0.75 * Ei) < 0.1)[0]) en = en[:idx_max] data = signal.nxdata[:, :idx_max] if self.entry['data'].nxerrors: errors = self.entry['data'].nxerrors.nxdata[:] Q = np.zeros((len(pol), len(en))) E = np.zeros((len(pol), len(en))) for i in range(0, len(pol)): p = pol[i] Q[i, :] = np.array( np.sqrt( (2 * Ei - en - 2 * np.sqrt(Ei * (Ei - en)) * np.cos(p * np.pi / 180.0)) / 2.0721)) E[i, :] = np.array(en) s = Q.shape Qin = Q.reshape(s[0] * s[1]) Ein = E.reshape(s[0] * s[1]) datain = data.reshape(s[0] * s[1]) if self.entry['data'].nxerrors: errorsin = errors.reshape(s[0] * s[1]) qmin = Q.min() qmax = Q.max() emin = E.min() emax = E.max() NQ = int((qmax - qmin) / dQ) + 1 NE = int((emax - emin) / dE) + 1 Qb = np.linspace(qmin, qmax, NQ) Eb = np.linspace(emin, emax, NE) # histogram and normalize norm, nbin = np.histogramdd((Ein, Qin), bins=(Eb, Qb)) hist, hbin = np.histogramdd((Ein, Qin), bins=(Eb, Qb), weights=datain) if self.entry['data'].nxerrors: histe, hbin = np.histogramdd((Ein, Qin), bins=(Eb, Qb), weights=errorsin * errorsin) histe = histe**0.5 err = histe / norm Ib = NXfield(hist / norm, name='S(Q,E)') Qb = NXfield(Qb[:-1] + dQ / 2., name='Q') Eb = NXfield(Eb[:-1] + dE / 2., name='E') result = NXdata(Ib, (Eb, Qb)) if self.entry.data.nxerrors: result.errors = NXfield(err) return result
def write_wavelength(self, value): val, unit = value.split() self._entry.wavelength = NXfield(float(val), dtype='float32', units=string_attr(unit))
def plot(self, data_group, fmt, xmin, xmax, ymin, ymax, zmin, zmax, **opts): """ Plot the data entry. Raises NeXusError if the data cannot be plotted. """ try: import matplotlib.pyplot as plt except ImportError: raise NeXusError( "Default plotting package (matplotlib) not available.") over = opts.pop("over", False) image = opts.pop("image", False) log = opts.pop("log", False) logx = opts.pop("logx", False) logy = opts.pop("logy", False) if fmt == '': fmt = 'o' if over: plt.autoscale(enable=False) else: plt.autoscale(enable=True) plt.clf() signal = data_group.nxsignal errors = data_group.nxerrors title = data_group.nxtitle # Provide a new view of the data if there is a dimension of length 1 data, axes = (signal.nxdata.reshape(data_group.plot_shape), data_group.plot_axes) #One-dimensional Plot if len(data.shape) == 1: if hasattr(signal, 'units'): if not errors and signal.units == 'counts': errors = NXfield(np.sqrt(data)) if errors: ebars = errors.nxdata plt.errorbar(centers(axes[0], data.shape[0]), data, ebars, fmt=fmt, **opts) else: plt.plot(centers(axes[0], data.shape[0]), data, fmt, **opts) if not over: ax = plt.gca() xlo, xhi = ax.set_xlim(auto=True) ylo, yhi = ax.set_ylim(auto=True) if xmin: xlo = xmin if xmax: xhi = xmax ax.set_xlim(xlo, xhi) if ymin: ylo = ymin if ymax: yhi = ymax ax.set_ylim(ylo, yhi) if logx: ax.set_xscale('symlog') if log or logy: ax.set_yscale('symlog') plt.xlabel(label(axes[0])) plt.ylabel(label(signal)) plt.title(title) #Two dimensional plot else: from matplotlib.image import NonUniformImage from matplotlib.colors import LogNorm, Normalize if len(data.shape) > 2: slab = [] if image: for _dim in data.shape[:-3]: slab.append(0) slab.extend([slice(None), slice(None), slice(None)]) else: for _dim in data.shape[:-2]: slab.append(0) slab.extend([slice(None), slice(None)]) data = data[slab] if 0 in slab: print "Warning: Only the top 2D slice of the data is plotted" if image: x = boundaries(axes[-2], data.shape[-2]) y = boundaries(axes[-3], data.shape[-3]) xlabel, ylabel = label(axes[-2]), label(axes[-3]) else: x = boundaries(axes[-1], data.shape[-1]) y = boundaries(axes[-2], data.shape[-2]) xlabel, ylabel = label(axes[-1]), label(axes[-2]) if not zmin: zmin = np.nanmin(data[data > -np.inf]) if not zmax: zmax = np.nanmax(data[data < np.inf]) if not image: if log: zmin = max(zmin, 0.01) zmax = max(zmax, 0.01) opts["norm"] = LogNorm(zmin, zmax) else: opts["norm"] = Normalize(zmin, zmax) ax = plt.gca() if image: im = ax.imshow(data, **opts) ax.set_aspect('equal') else: im = ax.pcolormesh(x, y, data, **opts) im.get_cmap().set_bad('k', 1.0) ax.set_xlim(x[0], x[-1]) ax.set_ylim(y[0], y[-1]) ax.set_aspect('auto') if not image: plt.colorbar(im) if 'origin' in opts and opts['origin'] == 'lower': image = False if xmin: ax.set_xlim(left=xmin) if xmax: ax.set_xlim(right=xmax) if ymin: if image: ax.set_ylim(top=ymin) else: ax.set_ylim(bottom=ymin) if ymax: if image: ax.set_ylim(bottom=ymax) else: ax.set_ylim(top=ymax) plt.xlabel(xlabel) plt.ylabel(ylabel) plt.title(title) plt.gcf().canvas.draw_idle() plt.ion() plt.show()