Ejemplo n.º 1
0
    def plot(self, resp, zai=None, pert=None, mat=None, mevscale=False,
             egrid=None, sigma=3, normalize=True, ax=None, labelFmt=None,
             title=None, logx=True, logy=False, loglog=False, xlabel=None,
             ylabel=None, legend=None, ncol=1):
        """
        Plot sensitivities due to some or all perturbations.

        .. note::

            Without passing ``zai``, ``pert``, or ``mat``
            arguments, this method will plot all permutations of
            sensitivities for a given response.

        Parameters
        ----------
        resp: str
            Name of the specific response to be examined. Must be a key
            in ``sensitivities`` and ``energyIntegratedSens``
        zai: None or str or int or iterable
            Plot sensitivities due to these isotopes. Passing ``None``
            will plot against all isotopes.
        pert: None or str or list of strings
            Plot sensitivities due to these perturbations. Passing ``None``
            will plot against all perturbations.
        mat: None or str or list of strings
            Plot sensitivities due to these materials. Passing ``None``
            will plot against all materials.
        mevscale : bool, optional
            Flag for plotting energy grid in MeV units. If ``True``, the energy
            axis is expressed in MeV. Default is ``False``.
        egrid : numpy.array, optional
            User-defined energy grid boundaries displayed on the sensitivities
            as vblack, dashed vertical lines. Default is ``None``.
        {sigma}
        normalize: True
            Normalize plotted data per unit lethargy
        {ax}
        labelFmt: None or str
            Formattable string to be applied to the labels.
            The following entries will be formatted for each plot
            permuation::

                {m} - name of the material
                {z} - isotope zai
                {p} - specific perturbation
                {r} - response being plotted

        {logx}
        {logy}
        {loglog}
        {xlabel}
        {ylabel}
        {legend}
        {ncol}

        Returns
        -------
        {rax}

        Raises
        ------
        KeyError
            If response or any passed perturbation settings are not
            present on the object

        See Also
        --------
        * :py:meth:`str.format` - used for formatting labels

        """
        for subDict in {'sensitivities', 'energyIntegratedSens'}:
            if resp not in getattr(self, subDict):
                raise KeyError("Response {} missing from {}"
                               .format(resp, subDict))
        labelFmt = labelFmt or "mat: {m} zai: {z} pert: {p}"
        if isinstance(zai, (str, int)):
            zai = {zai, }
        zais = self._getCleanedPertOpt('zais', zai)
        perts = self._getCleanedPertOpt('perts', pert)
        mats = self._getCleanedPertOpt('materials', mat)

        ax = ax or gca()

        sigma = max(int(sigma), 0)
        resMat = self.sensitivities[resp]
        values = resMat[..., 0]
        if normalize:
            values = values.copy() / self.lethargyWidths

        errors = resMat[..., 1] * values * sigma

        energies = self.energies if mevscale else self.energies * 1E6
        for z, m, p in product(zais, mats, perts):
            iZ = self.zais[z]
            iM = self.materials[m]
            iP = self.perts[p]
            yVals = values[iM, iZ, iP]
            yVals = hstack((yVals, yVals[-1]))
            yErrs = errors[iM, iZ, iP]
            yErrs = hstack((yErrs, yErrs[-1]))
            label = labelFmt.format(r=resp, z=z, m=m, p=p)
            ax.errorbar(energies, yVals, yErrs, label=label,
                        drawstyle='steps-post')

        if egrid is not None:
            for group in egrid:
                ax.axvline(group, color='k', linestyle='dashed')

        if xlabel is None:
            xlabel = "Energy [MeV]" if mevscale else "Energy [eV]"

        if ylabel is None:
            parts = ["Sensitivity"]
            if normalize:
                parts.append("per unit lethargy")
            if sigma:
                parts.append(r"$\pm{}\sigma$".format(sigma))
            ylabel = " ".join(parts)

        ax = formatPlot(ax, loglog=loglog, logx=logx, logy=logy, legendcols=ncol,
                        legend=legend, xlabel=xlabel, ylabel=ylabel)
        return ax
Ejemplo n.º 2
0
    def plot(self,
             resp,
             zai=None,
             pert=None,
             mat=None,
             sigma=3,
             normalize=True,
             ax=None,
             labelFmt=None,
             title=None,
             logx=True,
             logy=False,
             loglog=False,
             xlabel=None,
             ylabel=None,
             legend=None,
             ncol=1):
        """
        Plot sensitivities due to some or all perturbations.

        .. note::

            Without passing ``zai``, ``pert``, or ``mat``
            arguments, this method will plot all permutations of
            sensitivities for a given response.

        Parameters
        ----------
        resp: str
            Name of the specific response to be examined. Must be a key
            in ``sensitivities`` and ``energyIntegratedSens``
        zai: None or str or int or iterable
            Plot sensitivities due to these isotopes. Passing ``None``
            will plot against all isotopes.
        pert: None or str or list of strings
            Plot sensitivities due to these perturbations. Passing ``None``
            will plot against all perturbations.
        mat: None or str or list of strings
            Plot sensitivities due to these materials. Passing ``None``
            will plot against all materials.
        {sigma}
        normalize: True
            Normalize plotted data per unit lethargy
        {ax}
        labelFmt: None or str
            Formattable string to be applied to the labels.
            The following entries will be formatted for each plot
            permuation::

                {m} - name of the material
                {z} - isotope zai
                {p} - specific perturbation
                {r} - response being plotted

        {logx}
        {logy}
        {loglog}
        {xlabel}
        {ylabel}
        {legend}
        {ncol}

        Returns
        -------
        {rax}

        Raises
        ------
        KeyError
            If response or any passed perturbation settings are not
            present on the object

        See Also
        --------
        * :py:meth:`str.format` - used for formatting labels

        """
        for subDict in {'sensitivities', 'energyIntegratedSens'}:
            if resp not in getattr(self, subDict):
                raise KeyError("Response {} missing from {}".format(
                    resp, subDict))
        labelFmt = labelFmt or "mat: {m} zai: {z} pert: {p}"
        if isinstance(zai, (str, int)):
            zai = {
                zai,
            }
        zais = self._getCleanedPertOpt('zais', zai)
        perts = self._getCleanedPertOpt('perts', pert)
        mats = self._getCleanedPertOpt('materials', mat)

        ax = ax or gca()

        sigma = max(int(sigma), 0)
        resMat = self.sensitivities[resp]
        values = resMat[..., 0]
        if normalize:
            values = values.copy() / self.lethargyWidths

        errors = resMat[..., 1] * values * sigma

        energies = self.energies * 1E6
        for z, m, p in product(zais, mats, perts):
            iZ = self.zais[z]
            iM = self.materials[m]
            iP = self.perts[p]
            yVals = values[iM, iZ, iP]
            yVals = hstack((yVals, yVals[-1]))
            yErrs = errors[iM, iZ, iP]
            yErrs = hstack((yErrs, yErrs[-1]))
            label = labelFmt.format(r=resp, z=z, m=m, p=p)
            ax.errorbar(energies,
                        yVals,
                        yErrs,
                        label=label,
                        drawstyle='steps-post')

        xlabel = 'Energy [eV]' if xlabel is None else xlabel
        ylabel = ylabel if ylabel is not None else ('Sensitivity {} {}'.format(
            'per unit lethargy' if normalize else '',
            r'$\pm{}\sigma$'.format(sigma) if sigma else ''))
        ax = formatPlot(ax,
                        loglog=loglog,
                        logx=logx,
                        logy=logy,
                        ncol=ncol,
                        legend=legend,
                        xlabel=xlabel,
                        ylabel=ylabel.strip())
        return ax
Ejemplo n.º 3
0
    def plot(self,
             mts='all',
             ax=None,
             loglog=False,
             xlabel=None,
             ylabel=None,
             logx=True,
             logy=False,
             title=None,
             legend=None,
             ncol=1,
             **kwargs):
        """
        Return a matplotlib figure for plotting XS.

        mts should be a list of the desired MT numbers to plot for this
        XS. Units should automatically be fixed between micro and macro XS.

        Parameters
        ----------
        mts: int, string, or list of ints
            If it's a string, it should be 'all'.
            A single int indicates one MT reaction number.
            A list should be a list of MT numbers to plot.
        {ax}
        {loglog}
        {logx}
        {logy}
        {xlabel}
        {ylabel}
        {title}
        {legend}
        {ncol}
        {kwargs} :py:func:`matplotlib.pyplot.plot`

        Returns
        -------
        {rax}

        Raises
        ------
        TypeError
            if MT numbers that don't make sense come up
        """

        if mts == 'all':
            mts = self.MT
        elif isinstance(mts, int):
            # convert to list if it's just one MT
            mts = [mts]
        elif isinstance(mts, list) and all([isinstance(ii, int)
                                            for ii in mts]):
            pass
        else:
            msg = ("mts argument must be a string saying 'all',"
                   "a list of integer MTs, or a single interger"
                   "instead, {} of type {} was passed.".format(mts, type(mts)))
            raise TypeError(msg)

        for mt in mts:
            if mt not in self.MT:
                error("{} not in collected MT numbers, {}".format(mt, self.MT))

        ax = ax or pyplot.gca()

        x = self.metadata['egrid']
        for mt in mts:
            for i, MT in enumerate(self.MT):
                if mt == MT:
                    y = self.xsdata[:, i]
                    ax.plot(x, y, drawstyle='steps', label=self.MTdescrip[i])

        title = title or '{} cross section{}'.format(
            self.name, 's' if len(mts) > 1 else '')
        xlabel = xlabel or "Energy [MeV]"

        ylabel = ylabel or (
            'Cross Section ({})'.format('b' if self.isIso else 'cm$^{-1}$'))
        ax = formatPlot(ax,
                        loglog=loglog,
                        logx=logx,
                        logy=logy,
                        ncol=ncol,
                        legend=legend,
                        title=title,
                        xlabel=xlabel,
                        ylabel=ylabel)

        return ax
Ejemplo n.º 4
0
    def plot(self,
             mts='all',
             ax=None,
             loglog=False,
             xlabel=None,
             ylabel=None,
             logx=True,
             logy=False,
             title=None,
             legend=None,
             ncol=1,
             labels=None,
             **kwargs):
        """
        Plot XS corresponding to their MTs.

        Parameters
        ----------
        mts : int, string, or list of ints
            If it's a string, it should be 'all'.
            A single int indicates one MT reaction number.
            A list should be a list of MT numbers to plot.
        {ax}
        {loglog}
        {logx}
        {logy}
        {xlabel}
        {ylabel}
        {title}
        {legend}
        {ncol}
        labels : str or list of str or dict {int: str}
            Labels to apply to the plot. Defaults to labeling by MT
            description.  If a string, then ``mts`` must be a single
            integer. If a list of strings, each label will be applied
            to each entry in ``mts``. If a dictionary, keys must be
            mts and their labels as values. The number of keys do
            not have to align with the number of MTs
        {kwargs} :func:`matplotlib.pyplot.plot`

        Returns
        -------
        {rax}

        Raises
        ------
        TypeError
            If MT numbers that don't make sense come up

        """

        mts = self._processPlotMts(mts)

        userlabel = kwargs.pop("label", None)
        if userlabel is not None:
            # Allow label to be passed for single MT plots
            # Little easier to remember and it makes more sense.
            # Don't allow mixed label / labels arguments
            if labels is not None:
                raise ValueError(
                    "Passing label and labels is not allowed. Prefer labels")
            if len(mts) == 1:
                labels = [userlabel]
            else:
                raise ValueError("Use labels when plotting multiple MTs")
        else:
            labels = self._processPlotLabels(mts, labels)

        ax = ax or pyplot.gca()

        kwargs.setdefault("drawstyle", "steps")
        for mt, label in zip(mts, labels):
            y = self[mt]
            ax.plot(self.energies, y, label=label, **kwargs)

        title = title or '{} cross section{}'.format(
            self.name, 's' if len(mts) > 1 else '')
        xlabel = xlabel or "Energy [MeV]"

        ylabel = ylabel or (
            'Cross Section ({})'.format('b' if self.isIso else 'cm$^{-1}$'))
        ax = formatPlot(ax,
                        loglog=loglog,
                        logx=logx,
                        logy=logy,
                        legendcols=ncol,
                        legend=legend,
                        title=title,
                        xlabel=xlabel,
                        ylabel=ylabel)

        return ax