<commit_before>"""
Class to read Sensitivity file
"""
from collections import OrderedDict
from itertools import product

from six import iteritems
from numpy import transpose, hstack
from matplotlib.pyplot import gca

from serpentTools.utils.plot import magicPlotDocDecorator, formatPlot
from serpentTools.engines import KeywordParser
from serpentTools.messages import warning, SerpentToolsException, critical
from serpentTools.utils import convertVariableName, str2vec
from serpentTools.parsers.base import BaseReader


class SensitivityReader(BaseReader):
    """
    Class for reading sensitivity files

    The arrays that are stored in ``sensitivities`` and
    ``energyIntegratedSens`` are stored under converted names.
    The original names from SERPENT are of the form
    ``ADJ_PERT_KEFF_SENS`` or ``ADJ_PERT_KEFF_SENS_E_INT``,
    respectively. Since this reader stores the resulting arrays
    in unique locations, the names are converted to a succint form.
    The two arrays listed above would be stored both as ``keff``
    in ``sensitivities`` and ``energyIntegratedSens``.
    All names are converted to ``mixedCaseNames`` to fit the
    style of the project.

    Ordered dictionaries ``materials``, ``zais``, and
    ``perts`` contain keys of the names of their respective
    data, and the corresponding index, ``iSENS_ZAI_zzaaai``,
    in the sensitivity arrays. These arrays are zero-indexed,
    so the first item will have an index of zero. The data stored
    in the ``sensitivities`` and ``energyIntegratedSens`` dictionaries
    has the exact same structure as if the arrays were loaded into
    ``MATLAB``/``Octave``, but with zero-indexing.

    Parameters
    ----------
    filePath: str
        Path to sensitivity file

    Attributes
    ----------
    nMat: None or int
        Number of materials
    nZai: None or int
        Number of perturbed isotopes
    nPert: None or int
        Number of perturbations
    nEne: None or int
        Number of energy groups
    nMu: None or int
        Number of perturbed materials
    materials: :py:class:`~collections.OrderedDict`
        Ordered dictionary of materials that have
        been perturbed.
    zais: :py:class:`~collections.OrderedDict`
        Ordered dictionary of nuclides that
        have been perturbed
    perts: :py:class:`~collections.OrderedDict`<commit_msg>DOC Update sensitivity reader docstring - explain matrices<commit_after>"""
Class to read Sensitivity file
"""
from collections import OrderedDict
from itertools import product

from six import iteritems
from numpy import transpose, hstack
from matplotlib.pyplot import gca

from serpentTools.utils.plot import magicPlotDocDecorator, formatPlot
from serpentTools.engines import KeywordParser
from serpentTools.messages import warning, SerpentToolsException, critical
from serpentTools.utils import convertVariableName, str2vec
from serpentTools.parsers.base import BaseReader


class SensitivityReader(BaseReader):
    """
    Class for reading sensitivity files

    The arrays that are stored in :attr:`sensitivities` and
    :attr:`energyIntegratedSens` are stored under converted names.
    The original names from SERPENT are of the form
    ``ADJ_PERT_KEFF_SENS`` or ``ADJ_PERT_KEFF_SENS_E_INT``,
    respectively. Since this reader stores the resulting arrays
    in unique locations, the names are converted to a succint form.
    The two arrays listed above would be stored both as ``keff``
    in :attr:`sensitivities` and :attr:`energyIntegratedSens`.
    All names are converted to ``mixedCaseNames`` to fit the
    style of the project.

    Ordered dictionaries :attr:`materials`, :attr:`zais` and
    :attr:`perts` contain keys of the names of their respective
    data, and the corresponding index, ``iSENS_ZAI_zzaaai``,
    in the sensitivity arrays. These arrays are zero-indexed,
    so the first item will have an index of zero. The data stored
    in the :attr:`sensitivities` and :attr:`energyIntegratedSens` dictionaries
    has the exact same structure as if the arrays were loaded into
    ``MATLAB``/``Octave``, but with zero-indexing.

    The matrices in :attr:`sensitivities` are ordered as they
    would be in MATLAB. The five dimensions correspond to:

        1. :attr:`materials` that were contained perturbed isotopes
        2. :attr:`zais` that were perturbed
        3. :attr:`perts` - reactions that were perturbed, e.g.
           ``'total xs'``
        4: :attr:`energies` - which energy group contained the
           perturbation. Will have one fewer dimensions than
           the number of values in :attr:`energies`, corresponding
           to the number of energy groups.
        5: [value, relative uncertainty] pairs

    The matrices in :attr:`energyIntegratedSens` will have the same
    structure, but with the :attr:`energies` dimension removed.

    Parameters
    ----------
    filePath: str
        Path to sensitivity file

    Attributes
    ----------
    nMat: None or int
        Number of materials
    nZai: None or int
        Number of perturbed isotopes
    nPert: None or int
        Number of perturbations
    nEne: None or int
        Number of energy groups
    nMu: None or int
        Number of perturbed materials
    materials: :py:class:`~collections.OrderedDict`
        Ordered dictionary of materials that have
        been perturbed.
    zais: :py:class:`~collections.OrderedDict`
        Ordered dictionary of nuclides that
        have been perturbed
    perts: :py:class:`~collections.OrderedDict`
{'fraction_non_alphanumeric': 0.06923909123692752, 'fraction_numerical': 0.0012621709340064912, 'mean_word_length': 3.381516587677725, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4721223', 'n_tokens_mistral': 1523, 'n_tokens_neox': 1445, 'n_words': 614}