def dynamicsusceptibility(workspace, temperature, outputName=None, zeroEnergyEpsilon=1e-6): """Convert :math:`S(Q,E)` to susceptibility :math:`\chi''(Q,E)`. #. If the X units are not in DeltaE, the workspace is transposed #. The Y data in *workspace* is multiplied by :math:`1 - e^{\Delta E / (kT)}` #. Y data in the bin closest to 0 meV and within -*zeroEnergyEpsilon* < :math:`\Delta E` < *zeroEnergyEpsilon* is set to 0 #. If the input was transposed, transpose the output as well :param workspace: a :math:`S(Q,E)` workspace to convert :type workspace: :class:`mantid.api.MatrixWorkspace` :param temperature: temperature in Kelvin :type temperature: float :param outputName: name of the output workspace. If :class:`None`, the output will be given some generated name. :type outputName: str or None :param zeroEnergyEpsilon: if a bin center is within this value from 0, the bin's value is set to zero. :type zeroEnergyEpsilon: float :returns: a :class:`mantid.api.MatrixWorkspace` containing :math:`\chi''(Q,E)` """ workspace = _normws(workspace) if not _validate._isSofQW(workspace): raise RuntimeError('Failed to calculate dynamic susceptibility. ' + "The workspace '{}' does not look like a S(Q,E).". format(str(workspace))) horAxis = workspace.getAxis(0) horUnit = horAxis.getUnit().unitID() doTranspose = horUnit != 'DeltaE' if outputName is None: outputName = 'CHIofQW_{}'.format(str(workspace)) if doTranspose: workspace = Transpose(workspace, OutputWorkspace='__transposed_SofQW_', EnableLogging=False) c = 1e-3 * constants.e / constants.k / temperature outWS = OneMinusExponentialCor(workspace, OutputWorkspace=outputName, C=c, Operation='Multiply', EnableLogging=False) _removesingularity(outWS, zeroEnergyEpsilon) if doTranspose: outWS = Transpose(outWS, OutputWorkspace=outputName, EnableLogging=False) DeleteWorkspace('__transposed_SofQW_', EnableLogging=False) outWS.setYUnitLabel("Dynamic susceptibility") return outWS
def dynamicsusceptibility(workspace, temperature, outputName=None, zeroEnergyEpsilon=1e-6): """Convert :math:`S(Q,E)` to susceptibility :math:`\chi''(Q,E)`. #. If the X units are not in DeltaE, the workspace is transposed #. The Y data in *workspace* is multiplied by :math:`1 - e^{\Delta E / (kT)}` #. Y data in the bin closest to 0 meV and within -*zeroEnergyEpsilon* < :math:`\Delta E` < *zeroEnergyEpsilon* is set to 0 #. If the input was transposed, transpose the output as well :param workspace: a :math:`S(Q,E)` workspace to convert :type workspace: :class:`mantid.api.MatrixWorkspace` :param temperature: temperature in Kelvin :type temperature: float :param outputName: name of the output workspace. If :class:`None`, the output will be given some generated name. :type outputName: str or None :param zeroEnergyEpsilon: if a bin center is within this value from 0, the bin's value is set to zero. :type zeroEnergyEpsilon: float :returns: a :class:`mantid.api.MatrixWorkspace` containing :math:`\chi''(Q,E)` """ workspace = _normws(workspace) if not _validate._isSofQW(workspace): raise RuntimeError('Failed to calculate dynamic susceptibility. ' + "The workspace '{}' does not look like a S(Q,E).".format(str(workspace))) horAxis = workspace.getAxis(0) horUnit = horAxis.getUnit().unitID() doTranspose = horUnit != 'DeltaE' if outputName is None: outputName = 'CHIofQW_{}'.format(str(workspace)) if doTranspose: workspace = Transpose(workspace, OutputWorkspace='__transposed_SofQW_', EnableLogging=False) c = 1e-3 * constants.e / constants.k / temperature outWS = OneMinusExponentialCor(workspace, OutputWorkspace=outputName, C=c, Operation='Multiply', EnableLogging=False) _removesingularity(outWS, zeroEnergyEpsilon) if doTranspose: outWS = Transpose(outWS, OutputWorkspace=outputName, EnableLogging=False) DeleteWorkspace('__transposed_SofQW_', EnableLogging=False) outWS.setYUnitLabel("Dynamic susceptibility") return outWS
def plotSofQW(workspace, QMin=0., QMax=None, EMin=None, EMax=None, VMin=0., VMax=None, colormap='jet', colorscale='linear'): """Plot a 2D :math:`S(Q,E)` workspace. :param workspace: a workspace to plot :type workspace: str or :class:`mantid.api.MatrixWorkspace` :param QMin: minimum :math:`Q` to include in the plot :type QMin: float or None :param QMax: maximum :math:`Q` to include in the plot :type QMax: float or None :param EMin: minimum energy transfer to include in the plot :type EMin: float or None :param EMax: maximum energy transfer to include in the plot :type EMax: float or None :param VMin: minimum intensity to show on the color bar :type VMin: float or None :param VMax: maximum intensity to show on the color bar :type VMax: float or None :param colormap: name of the colormap :type colormap: str :param colorscale: color map scaling: 'linear', 'log' :type colorscale: str :returns: a tuple of (:mod:`matplotlib.Figure`, :mod:`matplotlib.Axes`) """ workspace = _normws(workspace) if not _validate._isSofQW(workspace): logger.warning("The workspace '{}' does not look like proper S(Q,W) data. Trying to plot nonetheless.".format(str(workspace))) qHorizontal = workspace.getAxis(0).getUnit().name() == 'q' isSusceptibility = workspace.YUnitLabel() == 'Dynamic susceptibility' figure, axes = subplots() if QMin is None: QMin = 0. if QMax is None: dummy, QMax = validQ(workspace) if EMin is None: if isSusceptibility: EMin = 0. else: EMin, unusedEMax = _energylimits(workspace) if EMax is None: EAxisIndex = 1 if qHorizontal else 0 EAxis = workspace.getAxis(EAxisIndex).extractValues() EMax = EAxis[-1] if VMax is None: vertMax = EMax if EMax is not None else numpy.inf dummy, VMax = nanminmax(workspace, horMin=QMin, horMax=QMax, vertMin=EMin, vertMax=vertMax) VMax /= 100. if VMin is None: VMin = 0. colorNormalization = None if colorscale == 'linear': colorNormalization = matplotlib.colors.Normalize() elif colorscale == 'log': if VMin <= 0.: if VMax > 0.: VMin = VMax / 1000. else: raise RuntimeError('Cannot plot nonpositive range in log scale.') colorNormalization = matplotlib.colors.LogNorm() else: raise RuntimeError('Unknown colorscale: ' + colorscale) contours = axes.pcolor(workspace, vmin=VMin, vmax=VMax, distribution=True, cmap=colormap, norm=colorNormalization) colorbar = figure.colorbar(contours) if isSusceptibility: colorbar.set_label(r"$\chi''(Q,E)$ (arb. units)") else: colorbar.set_label(r'$S(Q,E)$ (arb. units)') if qHorizontal: xLimits = {'left': QMin, 'right': QMax} yLimits = {'bottom': EMin} if EMax is not None: yLimits['top'] = EMax xLabel = r'$Q$ ($\mathrm{\AA}^{-1}$)' yLabel = 'Energy (meV)' else: xLimits = {'left': EMin} if EMax is not None: xLimits['right'] = EMax yLimits = {'bottom': QMin, 'top': QMax} xLabel = 'Energy (meV)' yLabel = r'$Q$ ($\mathrm{\AA}^{-1}$)' axes.set_xlim(**xLimits) axes.set_ylim(**yLimits) axes.set_xlabel(xLabel) axes.set_ylabel(yLabel) _SofQWtitle(workspace, axes) return figure, axes
def plotSofQW(workspace, QMin=0., QMax=None, EMin=None, EMax=None, VMin=0., VMax=None, colormap='jet', colorscale='linear'): """Plot a 2D :math:`S(Q,E)` workspace. :param workspace: a workspace to plot :type workspace: str or :class:`mantid.api.MatrixWorkspace` :param QMin: minimum :math:`Q` to include in the plot :type QMin: float or None :param QMax: maximum :math:`Q` to include in the plot :type QMax: float or None :param EMin: minimum energy transfer to include in the plot :type EMin: float or None :param EMax: maximum energy transfer to include in the plot :type EMax: float or None :param VMin: minimum intensity to show on the color bar :type VMin: float or None :param VMax: maximum intensity to show on the color bar :type VMax: float or None :param colormap: name of the colormap :type colormap: str :param colorscale: color map scaling: 'linear', 'log' :type colorscale: str :returns: a tuple of (:mod:`matplotlib.Figure`, :mod:`matplotlib.Axes`) """ workspace = _normws(workspace) if not _validate._isSofQW(workspace): logger.warning( "The workspace '{}' does not look like proper S(Q,W) data. Trying to plot nonetheless." .format(str(workspace))) qHorizontal = workspace.getAxis(0).getUnit().name() == 'q' isSusceptibility = workspace.YUnitLabel() == 'Dynamic susceptibility' figure, axes = subplots() if QMin is None: QMin = 0. if QMax is None: dummy, QMax = validQ(workspace) if EMin is None: if isSusceptibility: EMin = 0. else: EMin, unusedEMax = _energylimits(workspace) if EMax is None: EAxisIndex = 1 if qHorizontal else 0 EAxis = workspace.getAxis(EAxisIndex).extractValues() EMax = EAxis[-1] if VMax is None: vertMax = EMax if EMax is not None else numpy.inf dummy, VMax = nanminmax(workspace, horMin=QMin, horMax=QMax, vertMin=EMin, vertMax=vertMax) VMax /= 100. if VMin is None: VMin = 0. colorNormalization = None if colorscale == 'linear': colorNormalization = matplotlib.colors.Normalize() elif colorscale == 'log': if VMin <= 0.: if VMax > 0.: VMin = VMax / 1000. else: raise RuntimeError( 'Cannot plot nonpositive range in log scale.') colorNormalization = matplotlib.colors.LogNorm() else: raise RuntimeError('Unknown colorscale: ' + colorscale) contours = axes.pcolor(workspace, vmin=VMin, vmax=VMax, distribution=True, cmap=colormap, norm=colorNormalization) colorbar = figure.colorbar(contours) if isSusceptibility: colorbar.set_label(r"$\chi''(Q,E)$ (arb. units)") else: colorbar.set_label(r'$S(Q,E)$ (arb. units)') if qHorizontal: xLimits = {'left': QMin, 'right': QMax} yLimits = {'bottom': EMin} if EMax is not None: yLimits['top'] = EMax xLabel = r'$Q$ ($\mathrm{\AA}^{-1}$)' yLabel = 'Energy (meV)' else: xLimits = {'left': EMin} if EMax is not None: xLimits['right'] = EMax yLimits = {'bottom': QMin, 'top': QMax} xLabel = 'Energy (meV)' yLabel = r'$Q$ ($\mathrm{\AA}^{-1}$)' axes.set_xlim(**xLimits) axes.set_ylim(**yLimits) axes.set_xlabel(xLabel) axes.set_ylabel(yLabel) _SofQWtitle(workspace, axes) return figure, axes