Example #1
0
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
Example #2
0
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
Example #3
0
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
Example #4
0
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